GUID/UUID数据库密钥的优点和缺点

Mat*_*ard 217 database uuid guid

我曾经在许多数据库系统上工作,如果所有数据库密钥都是GUID/UUID值,那么在数据库之间移动条目会变得更容易.我曾经考虑过几次走这条路,但总会有一些不确定性,特别是在性能和​​未读出电话的URL方面.

有没有人在数据库中广泛使用GUID?通过这种方式我可以获得哪些优势,以及可能存在的陷阱是什么?

Nic*_*ise 224

好处:

  • 可以离线生成它们.
  • 使复制变得微不足道(与int相反,这使得它非常难)
  • ORM通常喜欢他们
  • 独特的应用程序.所以我们可以在我们的应用程序(也是guid)中使用我们的CMS(guid)中的PK,并且知道我们永远不会发生冲突.

缺点:

  • 使用空间更大,但空间便宜(呃)
  • 无法按ID排序以获取插入顺序.
  • 在URL中看起来很难看,但实际上,WTF你是否正在将一个真正的数据库密钥放在一个URL中!
  • 更难做手动调试,但不是那么难.

就个人而言,我在任何体系相当的系统中都使用它们作为大多数PK,但我在一个系统上进行了"训练",这个系统在整个地方被复制,所以我们必须拥有它们.因人而异.

我认为重复数据的东西是垃圾 - 你可以获得重复数据但是你这样做.在我工作的地方,代理钥匙通常都不受欢迎.我们使用类似WordPress的系统:

  • 行的唯一ID(GUID /无论如何).用户永远不会看到.
  • 公共ID是从某个字段生成的(例如标题 - 使其成为文章的标题)

更新: 所以这个人得到了很多,并且我认为我应该指出GUID PK的一个重大缺点:聚集索引.

如果GUID上有很多记录和聚簇索引,那么插入性能将为SUCK,因为你会在项目列表中的随机位置插入(这就是要点),而不是在结尾(这很快)

因此,如果您需要插入性能,可以使用auto-inc INT,并在您想与其他人共享时生成GUID(即,将其显示给URL中的用户)

  • [WTF你在把一个真正的数据库密钥放在URL中吗??]不确定为什么会让你烦恼.你还会用什么?看看Stack Overflow ...它在整个地方的URL中都有IDENTITY值,它运行得很好.在URL中使用数据库密钥不会阻止您强制执行安全性. (178认同)
  • 记住一件事,人们经常更改页面,问题,论坛标题.对于搜索引擎优化,可以在URL中使用类似小ID的内容,这样如果标题发生变化,您仍然知道将来自旧URL的人转发到何处.`example.com/35/old-and-busted`刚刚成为`example.com/35/new-hotness`而你是应用程序只需检查标题并转发用户301. (25认同)
  • 不,它没有,但是像SEO这样的东西通常会更好,如果没有钥匙 - 特别是像GUID一样长的东西.当然,它可以很容易地解决,所以我猜这是一个过于笼统的声明 (20认同)
  • 索引GUID既昂贵又缓慢,这使得它们非常不适合主键. (9认同)
  • 很好的答案,如果您还添加有关使用GUID的性能缺点的信息,那将是很好的; 例如,加入,排序和索引将比使用整数慢.Guids非常棒,但是当性能至关重要时,它们会付出代价. (7认同)
  • "在我工作的时候,代理键通常是不受欢迎的" - 但你所描述的建议你使用UUID作为代理键.此外,如果你只将代理键与自然键对比,那么可以说UUID是你可能拥有的最不自然的键.所以只是为了澄清,代理与自然完全是另一场辩论,这两种方法都没有任何内在错误. (2认同)
  • 如果您使用 UUID1,您将获得递增的键,因为时间戳占据最高有效位。您可以将 UUID1 作为数字进行比较以确定生成顺序。它们也是数据库索引友好的,因为新生成的键总是在最后。(注意:UUID1 包括生成服务器的 MAC 地址,因此如果您不想透露这一点,请使用 UUID1 的多播变体。) (2认同)

Tro*_*vin 13

@Matt Sheppard:

假设您有一张顾客表.当然,您不希望客户不止一次存在于表中,或者您的销售和后勤部门会发生很多混淆(特别是如果客户的多行包含不同的信息).

因此,您拥有唯一标识客户的客户标识符,并确保客户(在发票中)知道标识符,以便客户和客户服务人员在需要通信时具有共同参考.为了保证没有重复的客户记录,您可以通过客户标识符上的主键或客户标识符列上的NOT NULL + UNIQUE约束向表中添加唯一性约束.

接下来,出于某种原因(我无法想到),系统会要求您将GUID列添加到customer表并将其作为主键.如果现在客户标识符列没有唯一性保证,那么您要求整个组织将来遇到麻烦,因为GUID始终是唯一的.

一些"架构师"可能会告诉你"哦,但我们在应用层中处理真正的客户唯一性约束!".对.关于通用编程语言和(特别是)中间层框架的时尚一直在变化,并且通常永远不会超出您的数据库.并且您很有可能在某些时候需要访问数据库而无需通过本应用程序.==麻烦.(但幸运的是,你和"架构师"早已不复存在,所以你不会在那里清理混乱.)换句话说:在数据库中保持明显的约束(在其他层中,如果你有时间).

换句话说:可能有充分的理由将GUID列添加到表中,但请不要试图降低您在真实(==非GUID)信息中保持一致性的抱负.

  • 我认为这个答案需要澄清一下:这假设UUID从未用作主键.我不知道这个假设来自哪里,但我还没有看到一个系统不允许你这样使用它们.*我知道这是一个古老的答案,我认为在分布式系统中使用UUID的优势当时并没有被广泛理解(?).* (3认同)

Men*_*elt 11

主要优点是您可以创建唯一的ID而无需连接到数据库.id是全球唯一的,因此您可以轻松地组合来自不同数据库的数据.这些似乎是小优点,但过去为我节省了大量工作.

主要的缺点是需要更多的存储空间(在现代系统上不是问题),并且id不是真正的人类可读性.这在调试时可能是个问题.

有一些性能问题,如索引碎片.但那些是可以解决的(jimmy nillson的梳子指南:http://www.informit.com/articles/article.aspx? p = 25862 )

编辑合并了我对这个问题的两个答案

@Matt Sheppard我认为他意味着您可以将具有不同GUID的行复制为主键.这是任何类型的代理键的问题,而不仅仅是GUID.就像他说的那样,通过向非键列添加有意义的唯一约束可以很容易地解决它.另一种方法是使用自然键,那些有实际问题.


And*_*nea 11

为什么没有人提到表现?当你有多个连接,所有基于这些讨厌的GUID,性能将通过地板,在那里:(

  • UUID 仅是整数大小的 4 倍...(如果您的数据库具有 UUID 类型) (2认同)

Tro*_*vin 10

如果GUID用作"uniqifiers",让重复数据进入您的表格,将来可能会给您带来很多麻烦.如果要使用GUID,请考虑仍然在其他列上维护UNIQUE约束.

  • 这是问题的核心:引入GUID使任何行都是唯一的.但行的非人为部分可能突然包含重复(事实的几个版本). (11认同)
  • +1补偿.我明白你的意思,但表达得很糟糕. (7认同)

小智 7

如果您还将该列用作聚簇索引(相对常见的做法),则将GUID用作主键时要考虑的另一个小问题.你将会在插入时受到攻击,因为guid的性质无论如何都不会开始顺序,因此当你插入时它们将是页面拆分等.如果系统具有高IO,那么需要考虑的事情......


wen*_*ner 5

主密钥的IDS抗的GUID

GUID作为主键的成本(SQL Server 2000)

神话,GUID与自动增量(MySQL 5)

这真的是你想要的.

UID优点

  • 每个表,每个数据库,每个服务器都是唯一的
  • 允许轻松合并来自不同数据库的记录
  • 允许跨多个服务器轻松分发数据库
  • 您可以在任何地方生成ID,而不必往返数据库
  • 大多数复制方案无论如何都需要GUID列

GUID缺点

  • 它比传统的4字节索引值大4倍; 如果你不小心,这可能会产生严重的性能和存储影响
  • 调试很麻烦(其中userid ='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • 生成的GUID应该是部分顺序的以获得最佳性能(例如,SQL 2005上的newsequentialid())并允许使用聚簇索引