我过去曾在许多数据库系统上工作过,如果所有数据库键都已被存储,那么在数据库之间移动条目就会容易得多。 GUID/UUID 价值观。我曾多次考虑走这条路,但总是存在一些不确定性,特别是在性能和​​无法通过电话读出的 URL 方面。

有人在数据库中广泛使用过 GUID 吗?这样做有什么好处,可能存在哪些陷阱?

有帮助吗?

解决方案

优点:

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

缺点:

  • 更大的空间使用,但空间便宜(呃)
  • 无法通过 ID 订购来获取插入订单。
  • 在 URL 中看起来可能很难看,但实际上,你到底在搞什么把真正的数据库密钥放在 URL 中!?
  • 手动调试比较困难,但也不是那么难。

就我个人而言,我在任何规模合适的系统中将它们用于大多数 PK,但我在一个到处复制的系统上接受了“训练”,所以我们必须拥有它们。YMMV。

我认为重复数据的事情是垃圾——无论你怎么做,你都可以获得重复的数据。在我工作的任何地方,代理键通常都不受欢迎。不过,我们确实使用了类似 WordPress 的系统:

  • 行的唯一 ID(GUID/其他)。用户永远不可见。
  • 公共 ID 从某个字段生成一次(例如标题 - 使其成为文章的标题)

更新:所以这个得到了很多+1,我想我应该指出 GUID PK 的一个很大的缺点:聚集索引。

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

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

其他提示

@马特谢泼德:

假设您有一桌顾客。当然,您不希望某个客户在表中出现多次,否则整个销售和物流部门会发生很多混乱(特别是当有关客户的多行包含不同的信息时)。

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

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

一些“建筑师”可能会告诉你“哦,但是我们处理 真实的 我们的应用程序层中的客户唯一性约束!”。正确的。关于通用编程语言和(尤其是)中间层框架的时尚一直在变化,并且通常永远不会比数据库更长寿。并且您很有可能在某些时候需要访问数据库而不需要通过当前的应用程序。==麻烦。(不过幸运的是,你和“建筑师”早已不在了,所以你不会再去收拾烂摊子了。) 换句话说:请务必在数据库中维护明显的约束(如果有时间,也请在其他层中维护)。

换句话说:向表中添加 GUID 列可能有充分的理由,但请不要因为这样做而降低您对一致性的期望。 真实的 (==非 GUID)信息。

主要优点是您可以创建唯一的 ID,而无需连接到数据库。而且 ID 是全球唯一的,因此您可以轻松组合来自不同数据库的数据。这些看似很小的优势,但在过去为我节省了很多工作。

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

存在一些性能问题,例如索引碎片。但这些很容易解决(吉米·尼尔森的梳子指南: http://www.informit.com/articles/article.aspx?p=25862 )

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

@Matt Sheppard 我认为他的意思是您可以使用不同的 GUID 作为主键来复制行。这是任何类型的代理键的问题,而不仅仅是 GUID。正如他所说,通过向非键列添加有意义的唯一约束可以轻松解决这个问题。另一种方法是使用自然密钥,但它们确实存在问题。

如果 GUID 被用作“唯一标识符”,让重复的数据进入您的表中,那么它们可能会在将来给您带来很多麻烦。如果您想使用 GUID,请考虑仍然在其他列上维护 UNIQUE 约束。

为什么没有人提到性能?当你有多个连接时,所有这些都基于这些令人讨厌的 GUID,性能将会下降,一直在那里:(

如果您还将该列用作聚集索引(一种相对常见的做法),则使用 GUIDS 作为主键时需要考虑的另一个小问题。由于 guid 的性质无论如何都不会按顺序开始,因此在插入时它们将是页面拆分等,因此您将在插入时受到影响。如果系统将具有高 IO,则需要考虑一些事情......

主键 ids 与 Guid

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

神话、GUID 与 GUID自动递增 (MySQL 5)

这确实是您想要的。

UID 优点

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

GUID 缺点

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

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

RDBM通常保证主键的唯一性,并保证通过键进行查找,其结构称为BTree,它是一种具有大分支因子的搜索树(二叉搜索树的分支因子为2)。现在,连续整数 ID 会导致插入发生 树的一侧,保留大部分叶节点不变。添加随机 UUID 将导致插入在整个索引上分割叶节点。

同样,如果存储的数据大部分是临时的,则通常需要访问最新的数据并将其连接到最多的数据。对于随机 UUID,模式不会从中受益,并且会命中更多索引行,从而需要内存中更多索引页。对于顺序 ID,如果最需要最新数据,则热索引页将需要更少的 RAM。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top