每个成员有0个或更多订单。每个订单至少包含1个项目。 memberid - varchar,不是整数 - 那没关系(请不要提到它不是很好,我不能改变它)。 所以,thera 3表:成员,订单和order_items。订单和订单项目如下:
CREATE TABLE `orders` (
`orderid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`memberid` VARCHAR( 20 ),
`Time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`info` VARCHAR( 3200 ) NULL ,
PRIMARY KEY (orderid) ,
FOREIGN KEY (memberid) REFERENCES members(memberid)
) ENGINE = InnoDB;
CREATE TABLE `order_items` (
`orderid` INT(11) UNSIGNED NOT NULL,
`item_number_in_cart` tinyint(1) NOT NULL , --- 5 items in cart= 5 rows
`price` DECIMAL (6,2) NOT NULL,
FOREIGN KEY (orderid) REFERENCES orders(orderid)
) ENGINE = InnoDB;
因此,order_items表看起来像:
orderid - item_number_in_cart - 价格:
...
1000456 - 1 - 24.99
1000456 - 2 - 39.99
1000456 - 3 - 4.99
1000456 - 4 - 17.97
1000457 - 1 - 20.00
1000458 - 1 - 99.99
1000459 - 1 - 2.99
1000459 - 2 - 69.99
1000460 - 1 - 4.99
...
如您所见, order_items 表没有主键(我认为为此表创建auto_increment id是没有意义的,因为一旦我们想要提取数据,我们总是将其提取为WHERE orderid='1000456' order by item_number_in_card asc
- 整个块,id对查询没有帮助)。
一旦将数据插入order_items,它就不是UPDATEd,只是SELECTed。
问题是:
提前谢谢。
答案 0 :(得分:1)
item_number_in_cart
上的索引将不会被使用。它是一个很小的int,没有足够的选择性,一旦你有2条记录就不会被引擎考虑。您可以将它作为第二列添加到orderid
上的现有索引(因为您在orderid
上创建了FK约束,mysql会自动在此字段上添加索引)。
你说order_items
中的数据从未更新,但我认为它可以删除;没有主键这样做会有问题。
答案 1 :(得分:1)
好吧,无论如何我都会有一个autoinc,因为我非常相信代理键,但正如alex07建议的一个索引,甚至是orderid的主键,item_number_in_cart都应该解决问题。请注意,按item_number的顺序将使用两遍排序,(获取数据然后按数字顺序对其进行排序),因此索引/键将直接关闭,因此您甚至需要使用代理键来获取该索引。
答案 2 :(得分:1)
主键可以跨多个列。您不能使用列的PRIMARY
属性来执行此操作,但您可以定义具有多个列的单独主键:
CREATE TABLE `order_items` (
`orderid` INT(11) UNSIGNED NOT NULL,
`item_number_in_cart` tinyint(1) NOT NULL , --- 5 items in cart= 5 rows
`price` DECIMAL (6,2) NOT NULL,
PRIMARY KEY (orderid, item_number_in_cart),
FOREIGN KEY (orderid) REFERENCES orders(orderid)
) ENGINE = InnoDB;
此外,主键只是一个唯一键,其中每列不具有某个名称的空值;您可以在非可空列上创建自己的唯一键以获得相同的效果。
通过索引item_number_in_cart
,您不可能获得很大的性能提升;由于给定订单的订单项数量往往很小,按item_number_in_cart
排序不会花费太多时间或内存。但是,在主键中包含列将有助于数据的一致性。