另一方面,在某些情况下,如果表中有其他唯一列可以起到同样的作用,它们似乎是多余的。例如,你正在构建一个将9位数字邮政编码映射到城市区域的表。如果你能保证数据格式和值不重复,那么邮政编码字段也可以很好地工作。
总之,我的经验像我们所有人一样是有限的。还有哪些真实世界的例子导致人们选择不使用自动编号列作为表的主键,以及原因是什么?这对我来说是一种"开阔眼界"的事情,我希望能从那些与各种数据库打过交道并有充分理由选择其他方法的人那里学到一些东西。
在我看来,使用身份列非常重要,因为即使最简单的表在未来可能变得更加重要。
唯一不使用身份列的情况是,我使用GUID代替,在这种情况下,记录可能是在断开连接的客户端上创建的,然后需要与中央系统同步。
我的经验法则是:“如果在正常使用中要添加记录,则使用自动增量主键;如果是静态表,则使用更加自然的标识符”
换句话说:用户、历史记录、资产等都要用自动增量主键。邮政编码/城市、类型/描述、机器ID通常使用“自然”键。
我坚信在几乎所有情况下都应该使用技术主键,因此我的答案是……从来不需要。
在需要频繁进行数据转储/加载/合并且存在外键关系的情况下,我通常会避免使用自增列(auto_increment)。尝试从使用自增id的相同模式的两个表实例中合并数据是一个可怕的问题。
这种用法对大多数人来说并不常见,但我的工作涉及大量批处理,每个批次都会合并到主数据库中以供后续分析/使用。
我认为唯一需要使用标识列的情况是当用于主键的字段数量很大,或者作为主键的字段非常大(例如20个字符的字符串)。在所有其他情况下,我更喜欢不使用它们。
关于标识符的问题,没有人提到的是当数据发生变化时会发生什么。由于键仅基于记录添加的时间,因此在灾难事件后重新加载数据到表中是一个真正的问题。现在,数据库管理系统应该帮助您防止截断表或切换主键值...应该。事情发生了,表被损坏,或者数据库更新遇到问题。对于标识主键,突然之间你就会陷入困境,试图弄清楚哪个标识值与哪一行相对应....等等,除非你不能,因为标识值对于数据没有意义。对于少量条目,您可能还可以,但是当您开始拥有数百万个值的较大表格时(我们的表格在这种情况下略高于1100万),这将迅速成为一个问题。每个人都说,“那是最坏的情况,永远不会发生。”直到它发生了。
我没有使用自动编号字段的一个领域是,在定义星型模式的DateDimension表时。在这种情况下,我使用了一个以yyyymmdd格式表示日期的整数。这样可以实现快速连接中央事实表和DateDimension(与自动编号ID列一样)。然而……
DateDimension表包含其他日期表示(例如smalldatetime列、dayOfWeek列等)。如果用户只想要yyyy-mm-dd格式的日期,则不需要连接,因为中央事实表中的日期维度键已经存储了这些信息。
总的来说,我不太喜欢包含业务信息的键。通常,在设计架构时对主键做出的假设随着时间的推移不再成立,你会变得卡住。但在这种情况下,我相当确定日期不会发生改变!