2012-01-31 2 views
1

Я не очень доволен структурой таблицы sql, которую я имею ниже по двум причинам.SQL Table Structure Feedback

  1. мне не нравится, что я перечисляю все элементы, включенные в Распоряжения (orders.itemOrderIds) в переменной VARCHAR в 1020 байт. Я чувствую, что есть более элегантный способ держать кучу идентификационных номеров.

  2. Я полагаюсь на извлечение информации о предмете (в основном полях) в своем java-коде из переменной itemDescription в таблице элементов.

Есть ли у кого-нибудь советы относительно наилучшего способа справиться с этими ситуациями. Я прочитал на этом веб-сайте, что все в порядке, когда Java-код генерирует таблицы. Так, например, мой Java-код создаст таблицу под названием order_ (orderId) _items, которая будет содержать все элементы, включенные в заказ, с помощью orderId. Это лучший способ сделать это?

CREATE TABLE IF NOT EXISTS customers 
(
id INT AUTO_INCREMENT, 
name VARCHAR(255) NOT NULL, 
email VARCHAR(255) NOT NULL, 
company VARCHAR(255) NOT NULL, 
address1 VARCHAR(255) NOT NULL, 
address2 VARCHAR(255), 
city VARCHAR(255) NOT NULL, 
province_state VARCHAR(255) NOT NULL, 
country VARCHAR(255) NOT NULL, 
zip VARCHAR(255), 
telephone VARCHAR(255), 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

CREATE TABLE IF NOT EXISTS orders 
(
id INT AUTO_INCREMENT, 
customerId INT NOT NULL, 
orderNum VARCHAR(255) NOT NULL, 
itemOrderIds VARCHAR(1020) NOT NULL, 
regName VARCHAR(255) NOT NULL, 
regCompany VARCHAR(255) NOT NULL, 
regEmail VARCHAR(255) NOT NULL, 
orderTime DATETIME NOT NULL, 
FOREIGN KEY(customerId) REFERENCES customers(id), 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

CREATE TABLE IF NOT EXISTS items 
(
itemNum VARCHAR(255) UNIQUE, 
itemName VARCHAR(255), 
itemTypeId SMALLINT NOT NULL, 
--itemDescription must hold all information needed to generate license keys in format 
-- Field_Name1: Field_Value1, Field_Name2: Field_Value2, ..... 
-- Field names are platform, version, (choose one: port, voiceName) 
itemDescription VARCHAR(1020), 
FOREIGN KEY(itemTypeId) REFERENCES item_types(id) ON DELETE CASCADE, 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

CREATE TABLE IF NOT EXISTS item_types 
(
id SMALLINT AUTO_INCREMENT, 
itemType VARCHAR(255) UNIQUE NOT NULL, 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

CREATE TABLE IF NOT EXISTS item_orders 
(
id INT AUTO_INCREMENT, 
itemNum VARCHAR(255) NOT NULL, 
licenseKey VARCHAR(255) NOT NULL, 
FOREIGN KEY(itemNum) REFERENCES items(itemNum), 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

Edit:

CREATE TABLE IF NOT EXISTS Order_Items 
(
orderId INT NOT NULL, 
itemOrderId INT NOT NULL, 
PRIMARY KEY(orderId, itemOrderId) 
) ENGINE = INNODB; 
+0

Использование 'VARCHAR (255)' для большинства атрибутов вонючее. – onedaywhen

+0

Не могли бы вы рассказать об этом больше? Я начинающий разработчик программного обеспечения (только 1 год опыта), поэтому любой совет будет высоко оценен. – thatidiotguy

+0

Я предполагаю, что значения 'orderNum' не имеют ширины до 255 символов. Вероятно, они не сильно различаются по длине, если вообще. Если значения на самом деле всегда имеют длину 10 символов, тогда будет целесообразно «CHAR (10)»: он указывает пользователям важные свойства данных, и вы получаете максимальную проверку длины «бесплатно», что, на мой взгляд, особенно важно для mySQL потому что в нем отсутствует поддержка ограничений CHECK. Что касается запаха, использование 'VARCHAR (255)' предполагает, что модель данных не была разработана кем-то с конкретным знанием рассматриваемого предприятия. НТН. – onedaywhen

ответ

3

Да, вам нужна таблица OrderItem пересечения (я обычно ставлю родительский объект первым в названии), а не денормализации всех идентификаторов заказов в поле VARCHAR. Невозможно правильно индексировать такое поле, и это делает обновления очень сложными.

Читайте дальше на database normalization, это первые первые типы примеров, которые вы найдете.

+0

Итак, вы говорите, что у меня должен быть такой стол: см. Сообщение для редактирования. – thatidiotguy

1

Лучший способ сделать это - нормализовать всю структуру данных, по крайней мере, до 3NF.

Database Normalization

Как сейчас - лучше список магазина элементов порядка в отдельной таблице, которая также содержит ссылку на таблицу Orders.

0

Вам нужна таблица деталей заказа (а не таблица соединений). Зачем? Потому что информация о заказе специфична для конкретной даты. Таким образом, вы должны хранить информацию, как было в тот день. Таким образом, информация о заказе обычно включает номер позиции, название товара, цену (критическая для включения цены, вам нужна цена на момент, когда заказ был продан не по цене 2 года спустя.) И любые детали опций, таких как как цвет, количество заказанных предметов и т. д. В таблице заказов вы также хотите включить информацию о том, к какому адресу он был отправлен, и имя клиента, поскольку эти тики также меняются со временем.

I woudl тоже вырвать таблица клиентов. Клиенты обычно могут иметь несколько адресов, номер телефона и электронную почту, и каждая из них должна быть отдельной связанной таблицей.

+0

Программа не отвечает за детализацию финансовой информации. Он просто записывает то, что было заказано, чтобы, если клиент потерял свой лицензионный ключ, его можно будет просмотреть позже. Лицензионный ключ будет зависеть от информации, которую они предоставили, когда он был заказан, а не того, что их адрес доставки в настоящее время. Другая из моих программ отвечает за финансы, а что нет. – thatidiotguy