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

MySQL:优化没有主键的表(索引、外键),mysql,performance,optimization,indexing,primary-key,Mysql,Performance,Optimization,Indexing,Primary Key,每个成员有0个或多个订单。每个订单至少包含一个项目。 memberid-varchar,不是整数-没关系(请不要提及这不是很好,我无法更改)。 所以,thera有3个表:成员、订单和订单项。订单和订单项目如下: CREATE TABLE `orders` ( `orderid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `memberid` VARCHAR( 20 ), `Time` TIMESTAMP NOT NULL DEFAULT CURRENT

每个成员有0个或多个订单。每个订单至少包含一个项目。 memberid-varchar,不是整数-没关系(请不要提及这不是很好,我无法更改)。 所以,thera有3个表:成员、订单和订单项。订单和订单项目如下:

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-购物车中的商品号-价格:

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\u items表没有主键(我认为为这个表创建一个自动增量id是没有意义的,因为一旦我们想要提取数据,我们总是将其提取为
,其中orderid='1000456'order by item\u number\u在\u card asc
中-整个块,id在查询中没有帮助)。 一旦数据被插入到订单项中,它就不会被更新,而是被选中

问题是:

  • 我认为在购物车的商品编号上放置索引是个好主意。谁能确认一下吗
  • 为了提高性能,我是否还需要对订单项目进行其他处理,或者这看起来相当不错?我可能会错过一些东西,因为我是新手

提前谢谢。

不会使用购物车中的
项目编号的索引。它的int值很小,没有足够的选择性,而且一旦你有2条记录,引擎甚至不会考虑它。您可以将其作为第二列添加到
orderid
上的现有索引中(因为您在
orderid
上创建了FK约束,mysql会自动在此字段上添加索引)。

您说,
order\u items
中的数据从未更新过,但我认为它可以删除;如果不使用主键,则会出现问题。

不会使用购物车中的
项目编号上的索引。它的int值很小,没有足够的选择性,而且一旦你有2条记录,引擎甚至不会考虑它。您可以将其作为第二列添加到
orderid
上的现有索引中(因为您在
orderid
上创建了FK约束,mysql会自动在此字段上添加索引)。

您说,
order\u items
中的数据从未更新过,但我认为它可以删除;如果没有主键,这样做会有问题。

无论如何,我会有一个autoinc,因为我非常相信代理键,但正如alex07所建议的那样,索引,甚至orderid的主键,购物车中的项目编号应该会解决问题。请注意,按项目编号的顺序将使用两次排序(获取数据,然后按数字顺序排序),因此索引/键会直接将其切掉,这样即使使用代理键,您也会想要该索引。

无论如何,我都会使用autoinc,因为我非常相信代理键,但正如Alexan所建议的那样,或者甚至是orderid的主键,购物车中的商品号都应该进行分类。请注意,按项目编号排序将使用两次传递排序(获取数据,然后按编号顺序排序),因此索引/键将直接将其切掉,这样即使使用代理键,您也需要该索引。

主键可以跨多个列。您不能使用列的
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\u number\u排序不会占用太多时间或内存。但是,在主键中包含列将有助于数据的一致性。

主键可以跨多个列。您不能使用列的
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\u number\u排序不会占用太多时间或内存。但是,在主键中包含列将有助于数据的一致性。

是否没有用于
订单项目的数量字段
,或者是否删除了列以简化示例?谢谢您的提问。是的,我删除了几行。当选择或插入价格时,它们被选中并插入。你的意思是你删除了几个列吗?对不起,这是一个打字错误。是的,我指的是列。
order\u items
是否没有数量字段,或者您是否省略了列以简化示例?谢谢您的提问。是的,我删除了几行。当选择或插入价格时,它们被选中并插入。你的意思是你删除了几个列吗?对不起,这是一个打字错误。是的,我指的是列。“您可以将其作为第二列添加到orderid上的现有索引中”-这是什么意思-“将其作为第二列添加到现有索引中”?正如Outis在回答您时所做的那样,(主键(orderid,购物车中的项目编号),这会提示您关于性能的额外问题。“您可以将其作为第二列添加到orderid上的现有索引中”-这是什么意思-“将其作为第二列添加到现有索引中”?正如Outis在回答您时所做的那样,(主键(orderid,cart中的项目编号),这提示了您关于性能的额外问题。我不确定在我将我的问题检查为res后是否可以提问