我有一张叫设备的桌子。存储在此表中的大多数设备可以通过序列号和部件号进行唯一标识。但是有些设备类型没有序列号和部件号分配给它们。相反,它们可以由另一个字段(内部id)唯一标识。
我应该为这个表创建一个代理键,还是应该创建一个复合主键(序列号、部件号、内部id),并在不提供序列号和部件号列时插入默认值?现在没有部件号和序列号的设备类型将在将来的版本中分配给它们(可能五年后)。在这种情况下,我应该创建代理键还是复合键?或者使用这三个唯一的属性,我应该在程序中创建一个散列,并使用它作为表的代理键吗?
发布于 2017-08-26 13:55:10
发布于 2017-08-26 17:29:21
我认为我们应该首先澄清,我们说的是初级钥匙,而不是备用钥匙,对吗?既然我们谈论的是小学钥匙,最好不要随着时间的推移而改变。也最好是尽可能小,特别是如果会有任何FKs指向这个PK。
避免使用自然密钥的一个主要原因是可靠性因素:你能信任数据的来源吗?机器是由人生成还是输入的?人类输入数据可能而且经常会犯错误。而且,即使数据是机器生成的,导入过程中的错误也有可能以某种方式破坏值。仅出于这个原因,我倾向于选择代孕密钥。当然,有些人会抱怨代孕值“毫无意义”,但我们不是在讨论纸上或屏幕上的逻辑数据模型。一个可靠和有效的价值将赢得“有意义”的每一次。将一个30字节(或其他什么)键复制到几个表中(然后再复制到多个索引中),这些键最有可能与不区分大小写的排序规则进行比较(即使是连接),如果您可以选择一个4字节INT,这是一个简单的二进制比较,则没有任何意义。
您的“自然”键列应该被索引,并且是一个备用键。这是应用程序将用来查找记录,以获得代理键,将用于所有后续联接和查询。随着时间的推移,本专栏可以更改数据类型、长度、值等,而无需告诉上面的人员,所请求的更改将需要1到6个月的时间(取决于系统的大小和更改的范围),因为它会影响太多的表,这意味着有更多的时间计划、开发更改的时间、测试所需的时间,以及一些东西不会在测试中被捕获的风险,并且会导致1名或更多的客户记录支持请求,这会使客户感到不安,也是对支持人员的拖累。
复合键,虽然本质上不是错误的,但在这里似乎没有添加任何内容。事实上,对于那些拥有它们的设备类型,它似乎是在对抗现有序列号的唯一性。
我也不建议使用“三个唯一属性至在程序中创建哈希并将其用作代理键”。同样,如果这三个“唯一属性”中的任何一个发生变化,这似乎是一个可以改变的值。对于PK来说,它也比理想的要大,更不用说散列的非顺序性质,它将使您和那些一开始就认为GUID是PKs的一个很好选择的人处于同一条船上;-)。
https://dba.stackexchange.com/questions/184403
复制相似问题