您如何看待您的主键?

在我团队中一个相当活跃的讨论中,我想到了大多数人喜欢的主键。我们有以下几类:

  1. Int / BigInt哪个自动增量是足够好的主键。

  2. 应该有至少3列组成的主键。

  3. id,GUID和人类可读的行标识符都应区别对待。

什么是对的PK最好的方法?这将是真棒,如果你能证明你的意见。有没有更好的办法,上面?

编辑:任何人都具有简单的样品/算法产生人可读的标识符为很好地进行扩展的行?


眼眸繁星
浏览 609回答 3
3回答

素胚勾勒不出你

如果你打算做与偶尔连接的应用程序数据库之间的同步,那么你应该使用的GUID为您的主键。它是一种用于调试的痛苦,从这种情况下,我倾向于坚持整数是自动增量如此分开。自动增量整数应该是默认的,并没有使用它们应该是合理的。

函数式编程

我没有看到一个答案可以指出(我认为)真正的基本要点-即,主键可以确保您不会在表中获得同一真实世界实体的两个条目(例如在数据库中建模)。该观察有助于确定主键的优点和缺点。例如,在(美国)状态名称和代码表中,名称或代码可以是主键-它们构成两个不同的候选键,并且选择其中一个(通常是较短的-代码)作为主键。首要的关键。在功能相关性(以及连接相关性-1NF到5NF)的理论中,关键的是候选键而不是主键。作为反例,人名通常是主键的错误选择。有很多人以“约翰·史密斯”(John Smith)或其他类似的名字命名;即使考虑到中间名(请记住:并非每个人都有一个中间名,例如,我没有),重复的空间很大。因此,人们不会将名称用作主键。他们发明了诸如社会安全号(SSN)或员工号之类的人工密钥,并使用它们来指定个人。理想的主键应简短,独特,令人难忘且自然。在这些特征中,唯一性是强制性的;鉴于现实世界数据的限制,其他人必须灵活应对。因此,在确定给定表的主键时,您必须查看该表代表什么。表中哪些集合或哪些列值集合唯一标识表中的每一行?这些是候选键。现在,如果每个候选键由4或5列组成,那么您可能会认为这些键太笨拙而不能做成一个好的主键(主要是出于简短的考虑)。在这种情况下,您可能会引入一个替代密钥-一个人工生成的数字。通常(但不总是),一个简单的32位整数足以替代代理密钥。然后,您可以将此代理键指定为主键。但是,您仍然必须确保将其他候选键(对于替代键也是候选键,以及所选的主键)都保持为唯一标识符-通常是通过在那些列集上设置唯一约束。有时候,人们发现很难识别什么使行变得独特,但是应该做些什么,因为仅仅重复一条信息并不能使它变得更真实。而且,如果您不小心并且确实得到两(或更多)行声称要存储相同的信息,然后又需要更新该信息,则有一种危险(尤其是如果您使用游标),您只会更新一行而不是每一行,因此这些行是不同步的,没有人知道哪一行包含正确的信息。在某些方面,这是一个很强硬的观点。我在需要时使用GUID并没有特别的问题,但是它们往往很大(如16-64字节),而且使用频率也很高。通常,一个很好的4字节值就足够了。由于每个索引页的值较少,因此使用4字节值的GUID会浪费磁盘空间,并且甚至减慢索引访问数据的速度,因此索引将更深,必须读取更多页才能到达索引。信息。

ibeautiful

这只是一个宗教问题,因为人们寻求普遍的正确答案。您的团队和该SO线程都显示出很大的分歧这一事实应该表明,有充分的理由在不同情况下使用您描述的所有解决方案。如果表中没有其他属性或一组属性适合于唯一地标识行,则代理键很有用。在可能的情况下,最好使用自然键,以使表更易于阅读。自然键还允许从属表中的外键包含实际值而不是代理ID。例如,当您需要存储state(CA,TX,NY)时,最好使用char(2)自然键而不是int。在适当的地方使用复合主键。id当存在完美的复合键时,不要不必要地添加“ ”替代键(在多对多表中尤其如此)。在每个表中对三列键的授权都是绝对的废话。当您需要在多个站点上保留唯一性时,GUID是一种解决方案。如果您需要主键中的值唯一但又不是有序或连续的,则它们也很方便。INT vs. BIGINT:表需要主键的64位范围并不常见,但是随着64位硬件可用性的增加,它不应该成为负担,并且可以确保您不会溢出。INT当然较小,因此,如果空间有限,则可以带来一点优势。
打开App,查看更多内容
随时随地看视频慕课网APP