2012-01-31 95 views
1

我不太满意我有两个原因下面的SQL表结构。SQL表结构反馈

  1. 我不喜欢,我列出所有的项目包括在一个1020字节的varchar变量订单(orders.itemOrderIds)。我觉得有一个更优雅的方式来保存一堆ID号码。

  2. 我依靠从项目表中的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; 

编辑:

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 2012-01-31 15:38:40

+0

你能多说一点吗?我是新手软件开发人员(仅1年的经验),所以任何意见将不胜感激。 – thatidiotguy 2012-01-31 15:46:45

+0

我假设'orderNum'值远不及255个字符。如果有的话,它们的长度可能并不相同。如果这些值实际上总是10个字符,那么'CHAR(10)'是合适的:它向用户指出数据的重要属性,并且你可以免费获得最大长度检查,我认为这对于MySQL来说特别重要因为它不支持'CHECK'约束。至于气味,使用'VARCHAR(255)'表明数据模型不是由具有相关企业特定知识的人设计的。 HTH。 – onedaywhen 2012-02-01 08:25:51

回答

3

是的,你需要一个OrderItem交集表(我通常把父对象首先在名称),而不是反规范化所有定购ID为varchar字段。没有办法像这样正确地索引字段,并且它使更新变得非常困难。

database normalization上阅读,这些是第一个可以找到的第一类示例。

+0

所以你说我应该有这样的表格:看帖子进行编辑。 – thatidiotguy 2012-01-31 15:30:05

1

最好的办法就是将所有的数据结构标准化为至少3NF。

Database Normalization

至于现在 - 在不同的表顺序项目亦持有到Orders表的引用更好地存储列表。

0

你想要一个订单明细表(不是连接表)。为什么?因为订单信息是特定日期的特定信息。所以你必须保存当时的信息。因此,订单明细通常包括商品编号,商品名称,价格(包括价格的关键,您需要订单销售时的价格而不是2年后的价格)以及任何此类选项的详细信息作为颜色,订购的物品数量等等。在订单表中,您还需要包含有关运送到的地址的详细信息,以及客户的姓名,因为这些行李也随时间变化。

我还会打出客户表。客户通常可以有多个地址,电话号码和电子邮件,每个应该是一个单独的相关表。

+0

该方案不负责详细的融资信息。它只是记录所订购的东西,以便如果客户丢失许可证密钥,可以在以后查询。许可证密钥将取决于它们在订购时提供的信息,而不是他们当前的送货地址。我的另一个项目负责处理财务问题,而不是处理财务问题。 – thatidiotguy 2012-01-31 15:52:55