MySQL:没有主键的表(索引,外键)的优化

时间:2011-11-15 00:56:37

标签: mysql performance optimization indexing primary-key

每个成员有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。

问题是:

  • 我认为将index放在item_number_in_cart上是个好主意。有人可以确认一下吗?
  • 我还有什么需要与order_items一起提高性能,还是看起来相当不错?我可能会错过一些东西,因为我是新手。

提前谢谢。

3 个答案:

答案 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排序不会花费太多时间或内存。但是,在主键中包含列将有助于数据的一致性。