当我创建新的数据库表时,我应该考虑哪些因素来选择主键的数据类型?
很抱歉这样做,但我发现我给相关问题的答案(你可以检查这个和这个)可以适用于这个.我把它们重塑了一下......
你会发现很多关于这个问题的帖子,你会做出的每一个选择都有其优点和缺点.这些参数通常是指关系数据库理论和数据库性能.
关于这个问题,我的观点非常简单:代理主键总是有效,而自然键可能不会总是工作这些天,这有多种原因:字段太短,规则改变等.
到目前为止,您已经猜到我基本上是uniqueIdentifier/surrogate主键团队的成员,即使我欣赏和理解这里提到的论点,我仍然在寻找"自然"的情况.关键比代理更好......
除此之外,支持这一基本规则的最重要但总是被遗忘的论据之一与代码规范化和生产率有关:
每次我创建一张桌子,我都会浪费时间
识别其主键及其物理特征(类型,大小)
每次我想在我的代码中引用它时记住这些特性?
向团队中的其他开发人员解释我的PK选择?
我对所有这些问题的回答都是否定的:
当代理选项为我提供防弹解决方案时,我没有时间试图找出"最好的自然主键".
在编写代码时,我不想记住我的Table_wake的主键是一个10个字符长的字符串.
我不想浪费时间谈判自然钥匙的长度:"好吧,如果你需要10,你为什么不把12 安全放在一边?".这个"安全方面"的说法真让我烦恼:如果你想保持安全,那就意味着你离不安全的一面真的不远了!选择代理:它是防弹的!
所以我在过去的五年里一直在使用一个非常基本的规则:每个表(我们称之为'myTable')都有第一个名为uniqueIdentifier 'id_MyTable'
类型的字段.即使这个表支持"多对多"关系,其中字段组合提供了一个非常可接受的主键,我更喜欢创建这个'id_myManyToManyTable'
字段作为uniqueIdentifier,只是为了坚持规则,因为,最后,它确实不疼.
主要优点是您不必再关心代码中主键和/或外键的使用.获得表名后,就会知道PK名称和类型.一旦知道数据模型中实现了哪些链接,您就会知道表中可用外键的名称.
如果您仍然希望在桌子的某个位置放置"自然键",我建议您按照标准模型(如
Tbl_whatever id_whatever, unique identifier, primary key code_whatever, whateverTypeYouWant(whateverLengthYouEstimateTheRightOne), indexed .....
其中id_是主键的前缀,code_用于"自然"索引字段.有些人认为code_字段应该设置为唯一.这是事实,可以通过DDL或外部代码轻松管理.请注意,计算了许多"自然"键(发票号),因此它们已经通过代码生成
我不确定我的规则是最好的.但这是一个非常有效的!如果每个人都在应用它,我们会避免时间丢失回答这类问题!
如果使用数字键,请确保数据类型为giong足够大,以容纳表格可能会增长到的行数.
如果使用guid,是否需要考虑存储guid所需的额外空间?针对guid PK的编码对于应用程序的开发人员或用户来说是一种痛苦.
如果使用复合键,您确定组合列始终是唯一的吗?
我真的不喜欢他们在学校教的东西,即使用"自然键"(例如书籍数据库中的ISBN),或者甚至使用2个或更多字段构成的主键.我永远不会那样做.所以这是我的小建议:
每个表中始终有一个专用列用于主键.
它们都应该在所有表中具有相同的colomn名称,即"ID"或"GUID"
尽可能使用GUID(如果不需要性能),否则增加INT
编辑:
好的,我想我需要解释一下我的选择.
在所有表中为您的主键设置专用列名称,只需使您的SQL语句更容易构建,并且更容易理解其他人(可能不熟悉您的数据库布局).特别是当你做很多JOINS和类似的事情时.您已经知道,您不需要查找特定表的主键是什么,因为它在任何地方都是相同的.
GUIDs与INTs在大多数情况下并不重要.除非您达到GUID的性能上限或进行数据库合并,否则您不会遇到任何重大问题.但是我更喜欢GUIDs.GUID的全球唯一性有朝一日可能会派上用场.也许你现在看不到它的需要,但是诸如将数据库的各个部分同步到笔记本电脑/手机甚至找不到数据线而不需要知道它们在哪个表中,这些都是GUID优点的优秀例子.提供.整数仅标识一个表的上下文中的记录,而GUID标识任何位置的记录.
在大多数情况下,我使用identity int主键,除非场景需要大量复制,在这种情况下我可以选择GUID.
我(几乎)从未使用过有意义的键.