没有主键的MySQL表(最佳实践)

7
我有一张包含多个用户信息的表格users,我想将每个用户的特定权限存储到另一个表中。
即使在任何地方都不使用up_id主键,我是否需要在user_permissions表中拥有它? 我知道在表格中建议始终拥有一个主键,但对于我的情况来说这没有意义。如果我需要连接这两个表格,我会使用user_id连接up_of_user。
Table `user`
==========================
user_id int(11) PK AI NN
user_name varchar(50)
...


Table `user_permissions`
=======================================
up_id int(11) PK AI NN
up_of_user int(11) FK of user.user_id
up_edit_post tinyint(4) DEFAULT '0'

1
“up_of_user”不是“user_permissions”的候选主键吗? - Gordon Linoff
1
up_of_user 将是指向 user 表的外键。 - Lewis Browne
据我所知,外键不能作为主键。但是我可能错了。 - btx
保留主键是一个好的实践,这样你可以从MySQL中获取一个已识别的行,如果您的要求是不需要主键,则不要保留它,在表中拥有主键没有严格的规定。 - Meenesh Jain
2个回答

6
请阅读MySQL的文档:
表的主键代表你在最重要的查询中使用的列或一组列。它有一个相关联的索引,可提高查询性能。由于不能包含任何NULL值,因此查询性能受NOT NULL优化的益处。使用InnoDB存储引擎时,表数据按照主键列或多个主键列进行物理组织,以便进行超快速查找和排序。
如果你的表很大且很重要,但没有明显的列或一组列可用作主键,则可以创建一个带有自动递增值的单独列,用作主键。这些唯一的ID可以在使用外键连接表时作为指向其他表中相应行的指针。
根据我的经验和知识,如果你不定义主键,数据库将创建一个隐藏的主键。在你的情况下,我建议保留主键。
感谢@AaronDigulla的解释:
必须吗?不是。在幕后使用了吗?是的,它保存在磁盘上并保存在行缓存中等等。删除会稍微提高性能(请使用毫秒精度的手表来注意)。
但是......下次有人需要创建对该表的引用时,他们会诅咒你。如果他们勇敢,他们会添加一个PK(并等待长时间使DB创建该列)。如果他们不勇敢或愚蠢,他们将开始使用业务键(即数据列)创建引用,这将导致维护的噩梦。
结论:由于拥有主键的成本(即使当前未使用)非常小,请让它存在。

5

InnoDB有三种PK的选择: 按顺序为:

  1. 显式 PRIMARY KEY(...) -- 最佳实践:总是这样做。
  2. 第一个拥有所有 NON NULL 列的 UNIQUE(...)。-- 比#1粗糙。
  3. 一个隐藏的6字节整数。 -- 由于它是隐藏的,因此会使表的维护变得困难。

AUTO_INCREMENT与"自然" PK:

第一条规则:如果您有自然键,则使用它而不是添加人造ID。我创建的约2/3的表都有一个“自然”PK,有时是“组合”(多列)。

第二条规则:如果您有多个辅助索引,则使用AI PK可能需要更少的空间。这是因为每个辅助键都包括PK的副本。

第三条规则:仅有一个辅助索引时,这是个无法确定的问题。

示例

老妇人的故事,也称为“假新闻”

  • “庞大的PK很慢” -- 也许是,也许不是。
  • “VARCHAR PK很慢” -- 并不会慢很多。

如果您有其他节省(例如,摆脱列),那可能会覆盖老妇人的故事。

你的例子

放弃 up_id 并将 user_name 提升为PK。

听起来 useruser_permissions 是1:1的关系?拥有相同PK的两个表通常是非常罕见的。通常这两个表应该合并成一个表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接