我有一些只有 2 个 int 列的 innoDb,它们是其他表主键的外键。
例如,一个表是 user_items,它有 2 列,userId,itemId,用户表和项目表的外键,如果更新或删除,则设置为级联。
我应该在这些表中添加第三列并使其成为主键,还是现在的方式更好,在性能或任何其他好处方面?
我有一些只有 2 个 int 列的 innoDb,它们是其他表主键的外键。
例如,一个表是 user_items,它有 2 列,userId,itemId,用户表和项目表的外键,如果更新或删除,则设置为级联。
我应该在这些表中添加第三列并使其成为主键,还是现在的方式更好,在性能或任何其他好处方面?
仅仅为了添加 ID 列而添加第三个 ID 列是没有意义的。事实上,当您插入或删除行时,它只会增加处理开销(索引维护)。
主键不一定是“ID 列”。
如果您只允许用户和项目之间有一个关联(一个用户不能被分配两次相同的项目),那么将其定义(userid, itemid)
为表的主键是有意义的。
如果您确实允许同一对出现多次,那么您当然不需要该约束。
你已经有一把天然钥匙了{userId, itemId}
。除非有特定原因添加另一个(代理)键,否则只需使用现有键作为主键。
代孕的一些原因可能包括:
我认为这不适用于您的情况。
另外,请注意InnoDB 表是聚集的,聚集表中的二级索引比基于堆的表中的二级索引更昂贵。因此,理想情况下,您应该尽可能避免使用二级索引。
一般来说,如果它不会给您正在编写的代码增加真正的复杂性,并且该表预计包含 100,000-500,000 行或更少,我建议添加主键。我有时还建议添加created_at
和updated_at
列。
是的,它们需要更多的存储空间——但它是最小的。还有一个问题是必须维护主键索引,因此如果表变大,插入和更新可能会变慢。但除非表很大(数千或数百万行),否则处理速度可能没有区别。
因此,除非表非常大,否则对空间和处理速度的影响是微不足道的——因此您要决定维护它需要多少努力以及它提供的潜在效用。如果只需要很少的额外代码,那么它提供的几乎任何实用程序都可能值得。
拥有主键的最佳理由之一是根据插入的顺序为行提供自然顺序。如果您想检索添加的最后 100 行(或前 100 行),如果您在表上有一个自动递增的主键,这将非常简单和快速。
在基于日期范围获取数据方面,添加inserted_at
和列可以提供类似的实用程序。updated_at
同样,除非行数非常大,否则也可能值得评估这些。