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

时间:2008-09-05 08:00:50

标签: database guid uuid

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

有没有人在数据库中广泛使用GUID?通过这种方式我会得到什么好处,以及可能存在的陷阱是什么?

9 个答案:

答案 0 :(得分:215)

优点:

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

缺点:

  • 空间使用量较大,但空间便宜(呃)
  • 无法通过ID订购以获取插入订单。
  • 在URL中看起来很难看,但实际上,WTF你是否正在将一个真正的数据库密钥放入URL中??
  • 更难做手动调试,但不是那么难。

就我个人而言,我在任何体系相当的系统中都使用它们,但是我在一个被复制的系统上“受过训练”,所以我们不得不拥有它们。 YMMV。

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

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

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

如果您有很多记录,并且GUID上有聚集索引,那么您的插入性能将为SUCK,因为您会在项目列表(即该点)中的随机位置插入,而不是在末尾(这是快)

因此,如果您需要插入性能,可以使用auto-inc INT,如果您想与其他人共享(例如,通过URL向用户显示),则生成GUID

答案 1 :(得分:13)

@Matt Sheppard:

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

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

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

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

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

答案 2 :(得分:11)

主要优点是您可以在不连接数据库的情况下创建唯一ID。 id是全球唯一的,因此您可以轻松地组合来自不同数据库的数据。这些似乎是小优点,但过去为我节省了很多工作。

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

存在一些性能问题,例如索引碎片。但这些是可以解决的(jimmy nillson的梳子指导:http://www.informit.com/articles/article.aspx?p=25862

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

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

答案 3 :(得分:9)

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

答案 4 :(得分:9)

为什么没有人提到表现?当你有多个联接时,所有基于这些令人讨厌的GUID的表现将会在场上进行:(

答案 5 :(得分:7)

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

答案 6 :(得分:5)

primary-keys-ids-versus-guids

The Cost of GUIDs as Primary Keys(SQL Server 2000)

Myths, GUID vs. Autoincrement(MySQL 5)

这真的是你想要的。

UID专业人士

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

GUID缺点

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

答案 7 :(得分:0)

有一件事没有真正解决,即使用随机(UUIDv4)ID作为主键会损害主键索引的性能。无论您的表是否围绕密钥聚集,都会发生这种情况。

RDBM通常确保主键的唯一性,并确保在名为BTree的结构中通过键进行查找,该结构是具有大分支因子的搜索树(二叉搜索树具有2的分支因子)。现在,顺序整数ID将导致插入仅发生在树的一个侧,使大多数叶节点保持不变。添加随机UUID将导致插入在整个索引上拆分叶节点。

同样,如果存储的数据大部分是临时的,通常情况下需要访问和加入最新的数据。使用随机UUID,模式将不会从中受益,并且将触及更多索引行,从而需要更多内存中的索引页。如果最需要最新数据,则使用顺序ID,热索引页面将需要更少的RAM。

答案 8 :(得分:0)

优势:

  • UUID值在表和数据库之间是唯一的。这就是为什么它可以是两个数据库或分布式数据库之间的合并行。
  • 与整数类型数据相比,UUID通过url更安全。 如果通过URL传递UUID,则攻击者无法猜测下一个ID;但是如果我们传递整数类型(例如10),则攻击者可以猜测下一个ID为11然后是12等。
  • UUID可以离线生成。