可能的重复:
每个表都应该有一个单字段代理/人工主键吗?
我无法想象每个表都不使用唯一 ID,这就是我问这个问题的原因。您不应该为表中的每一行分配一个唯一的 ID 吗?
小智 22
是的,例如在映射表表示两个表之间的 N:M 关联的情况下。在最简单的形式中,它只包含两个外键,这些外键构成了它的复合键,因此不需要单独的 ID 列。事实上,向这样的表添加一个 ID(没有唯一性约束,正如@Jeff 指出的那样)将允许在相同的两行之间添加多个关联,这通常是不希望的。
小智 7
这是一种我持观望态度的情况,那就是多对多的“关系”。
Table: Students (PK_StudentID)
Table: Teachers (PK_TeacherID)
Table: StudentsTeachers(PK_StudentsTeachersID, FK_StudentID, FK_TeacherID), Unique Contraint on (FK_StudentID, FK_TeacherID)
Run Code Online (Sandbox Code Playgroud)
*不要让学期或学年掩盖问题。
StudentsTeachers 表真的需要 PK_StudentsTeachersID 吗?所有这些 id 都没有添加任何智能。它们只是唯一的数字。是否需要在不指明老师的情况下创建学生记录的任何部分?如果您需要将此表加入到 StudentTeacherMeeting 表中,拥有一个用于加入的字段总是很好,但是您需要加入只是为了获取特定教师的会议列表。
速度、选择灵活性、连接编译、内存、磁盘空间,您只需根据具体情况考虑这些因素。
当您想要执行以下操作时,您需要密钥:
更新/删除/读取特定数据行
如果表有 1 个或多个子表
通过实施业务规则来强制唯一性(例如客户编号必须是唯一的)
不需要关键字段的示例:
数据仓库中的事实表可以不用键来定义。可在此处找到详细说明:To Key or Not To Key
日志表不需要标识符列。
在 ETL 应用程序中,通常将数据加载到没有 ID 的暂存区并按顺序处理输入数据,删除整个表。
如果您的表只包含 1 行(非常罕见!)
如果您的表具有保证(以某种方式)正确的自然键并且信息量很小并且您将此数据用于只读。在这种情况下,键不会增加值
有这样的案例。在领域驱动设计中,我们有称为“值对象”的东西,它不需要 ID。这些对象自然不具有任何身份,因此您无需为它们存储一个。保持它们不可变也被认为是最佳实践。
但在创建多次存储相同值对象的表之前,请考虑标准化。通常情况下,最好有一把钥匙(并且可以是替代品)并只存储您拥有的物品数量。在决定省略 PK 之前,请仔细考虑您的设计。
因此,仅仅因为您不一定需要它们并不总是意味着您不应该拥有它们。PK 让生活变得更加轻松。