首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >代理密钥与自然密钥

代理密钥与自然密钥
EN

Database Administration用户
提问于 2017-08-26 04:07:54
回答 2查看 1.5K关注 0票数 5

我有一张叫设备的桌子。存储在此表中的大多数设备可以通过序列号和部件号进行唯一标识。但是有些设备类型没有序列号和部件号分配给它们。相反,它们可以由另一个字段(内部id)唯一标识。

我应该为这个表创建一个代理键,还是应该创建一个复合主键(序列号、部件号、内部id),并在不提供序列号和部件号列时插入默认值?现在没有部件号和序列号的设备类型将在将来的版本中分配给它们(可能五年后)。在这种情况下,我应该创建代理键还是复合键?或者使用这三个唯一的属性,我应该在程序中创建一个散列,并使用它作为表的代理键吗?

EN

回答 2

Database Administration用户

发布于 2017-08-26 13:55:10

暂时使用代理键作为主键。当自然键可用时,使它们成为不可空的唯一约束。

根据雅格尼原则,您应该只为“现实生活”当前需求编写代码--一个可能(或不可能)在5年内到达的主键现在不值得考虑!

代孕键在实践中被广泛使用,这让纯粹主义者感到恐怖:我们其余的人只是使用它们而已!请参阅这个堆栈溢出回答 (以及线程的其余部分)。

票数 4
EN

Database Administration用户

发布于 2017-08-26 17:29:21

我认为我们应该首先澄清,我们说的是初级钥匙,而不是备用钥匙,对吗?既然我们谈论的是小学钥匙,最好不要随着时间的推移而改变。也最好是尽可能小,特别是如果会有任何FKs指向这个PK。

避免使用自然密钥的一个主要原因是可靠性因素:你能信任数据的来源吗?机器是由人生成还是输入的?人类输入数据可能而且经常会犯错误。而且,即使数据是机器生成的,导入过程中的错误也有可能以某种方式破坏值。仅出于这个原因,我倾向于选择代孕密钥。当然,有些人会抱怨代孕值“毫无意义”,但我们不是在讨论纸上或屏幕上的逻辑数据模型。一个可靠和有效的价值将赢得“有意义”的每一次。将一个30字节(或其他什么)键复制到几个表中(然后再复制到多个索引中),这些键最有可能与不区分大小写的排序规则进行比较(即使是连接),如果您可以选择一个4字节INT,这是一个简单的二进制比较,则没有任何意义。

您的“自然”键列应该被索引,并且是一个备用键。这是应用程序将用来查找记录,以获得代理键,将用于所有后续联接和查询。随着时间的推移,本专栏可以更改数据类型、长度、值等,而无需告诉上面的人员,所请求的更改将需要1到6个月的时间(取决于系统的大小和更改的范围),因为它会影响太多的表,这意味着有更多的时间计划、开发更改的时间、测试所需的时间,以及一些东西不会在测试中被捕获的风险,并且会导致1名或更多的客户记录支持请求,这会使客户感到不安,也是对支持人员的拖累。

复合键,虽然本质上不是错误的,但在这里似乎没有添加任何内容。事实上,对于那些拥有它们的设备类型,它似乎是在对抗现有序列号的唯一性。

我也不建议使用“三个唯一属性至在程序中创建哈希并将其用作代理键”。同样,如果这三个“唯一属性”中的任何一个发生变化,这似乎是一个可以改变的值。对于PK来说,它也比理想的要大,更不用说散列的非顺序性质,它将使您和那些一开始就认为GUID是PKs的一个很好选择的人处于同一条船上;-)。

票数 2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/184403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档