【问题标题】:Usage of user ID as primary key in a large table在大表中使用用户 ID 作为主键
【发布时间】:2016-10-06 02:11:06
【问题描述】:

我有一个表(id(PK,UNIQUE),user_id,[此处的其他列]),其中包含大量(100k+)用户订单,每个用户只能访问设置了他的 user_id 的订单。

我想知道使用 user_id 作为主键会如何影响该数据库上 SELECT 查询的性能。是否有任何有效的解决方案可以在单个 InnoDB 表中维护大量绑定到用户的行(每个订单都有一个所有者)?

【问题讨论】:

  • 对于每个user_id 有多个条目的表,User_id 可能是一个错误的主键。
  • @Solarflare 可能
  • @philipxy 好吧,“可能”的意思是“你可能想重新考虑一下”。他仍然可以使用以user_id 作为第一列的复合主键来创建他的物理顺序。但是要对@pfcode 进行评估(不了解有关数据/数据库/查询的更多信息,并且不详细说明原因以及好处和后果,例如插入、其他查询或索引大小):您通常不需要想一想。您的(订单)ID 似乎是您表中的逻辑主键。将优化重点放在好的索引上,索引是最相关的性能因素。
  • @Solarflare 谢谢。我的意思是,正如我在下面的答案中所写,user_id 不能是一个表的主键,其中每个 user_id 有多个条目。
  • @philipxy 是的,我当然知道这一点,但感谢您的澄清,以防有人(其他人)误解了我的评论,你是对的,我想在那里表达的并不是很清楚.

标签: mysql optimization key primary-key innodb


【解决方案1】:

如果大多数查询都包含user_id 的特定值,则效率更高:

PRIMARY KEY(user_id, id),  -- to get the benefit of 'clustering' around user_id
INDEX(id)  -- to make AUTO_INCREMENT happy

【讨论】:

    【解决方案2】:

    只要两者的数据类型相同,即intuint,在性能上并没有什么不同。

    您可以安全地删除 ID 并将 UID 设为主键。

    【讨论】:

    • user_id 不能是主键,因为它不是唯一的;一个用户可以有多个订单。
    【解决方案3】:

    表格是“用户订单”。如果 user_id 加上某些列唯一地标识了一个订单并且没有这些列的子集,那么该列集就是一个候选键(被声明为 PK/UNIQUE)。如果没有唯一标识订单的列集,那么您需要使用 id 之类的代理项。 (您可能出于其他原因想要它。)

    由于每个用户可以有多个订单,{user_id} 不是此表的候选键。

    【讨论】:

      猜你喜欢
      • 2012-11-30
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      • 2021-08-10
      • 1970-01-01
      • 2014-05-09
      相关资源
      最近更新 更多