使用什么类型的数据库记录ID:long还是guid?

9
近年来,我一直在使用MSSQL数据库,在表中所有唯一记录的ID列类型为bigint(长整型)。它是自动递增的,通常情况下运行良好。
目前,我观察到人们更喜欢使用GUID作为记录的标识。
将bigint替换为guid作为唯一记录id是否有意义?
我认为这没有意义,因为生成和排序bigint总是比guid快,但是...当使用两个(或更多)分离的应用程序实例和数据库并将它们保持同步时,会遇到一些麻烦,因此您必须在SQL服务器之间管理ID池(例如:sql1使用从100到200的ID,sql2使用从201到300的ID)-这是一种危险的做法。使用guid id,您不需要担心ID池。
对于我的镜像应用程序(和数据库),您的建议是保留传统的ID还是转移到GUID?
感谢您提前的回复!
5个回答

8

GUID(全局唯一标识符)具有以下优点:

  • 可以在离线状态下从数据库中创建它们,而不必担心冲突。
  • 你永远不会用完它们。

缺点:

  • 顺序插入的性能可能较差(特别是在聚簇索引上)。
  • 占用每行更多的空间。
  • 干净地创建一个 GUID 并不便宜。
    • 但如果客户端生成它们,这实际上不是问题。

该列仍应具有唯一约束条件(作为主键或作为其他关系的一部分的单独约束条件),因为没有阻止某人手动提供 GUID 并意外/故意违反唯一性。

如果空间不影响您的性能,并且性能没有受到显着影响,它们可以解决许多问题。决策必然是特定于应用程序的个体需求。


我从来没有听说过顺序GUID,但这应该是可能的 - 只需添加一个实例前缀/后缀。 - twk
还有另一个缺点……当您手动操作表中的数据时,GUID 是不可能记住的,必须复制和粘贴才能做任何有价值的事情。您也无法使用 > 或 < 更新/删除数据集。 - Robert C. Barth
公平的观点,有时候强制复制/粘贴而不是从内存中获取可以避免一些问题,但它确实会减慢某些操作。如果您有一个用于测试的常见ID,则将其放在某个地方(例如作为返回它的函数,如GetTestFooId()),其中Foo是有意义的,这样做可能会更有价值。 - ShuggyCoUk
我不理解为什么顺序 GUID 比自增长的 long 值更受欢迎:基本原理是相同的,每个人都能够预测你的下一个 ID,这个想法让我感到不舒服。 - Philippe Grondier
如果这会造成安全风险,那就不要使用。对于许多用户来说,这不是问题,因为该字段不是用于外部使用的。 - ShuggyCoUk

3

在涉及复制或客户端ID生成的任何情况下,我都使用GUID。在这些情况下,使用GUID更容易管理身份标识。

对于像Web应用程序直接访问数据库或不需要复制(或者可能只需要单向复制,如发布/订阅)的服务器等两层情况,我认为自增ID列就足够了。

至于是保持自增ID还是转向GUID……在全新的应用程序中提倡使用GUID是一回事,因为可以在前期做出所有这些决策。但是,如果建议某人迁移现有的数据库,那么可能会带来更多的痛苦,得不偿失。


2
GUID在页面分裂时会影响性能和并发。 INT在100%的页面填充时只在一端添加,而GUIDS则在任何地方添加,因此您可能需要运行较低的填充量-这会浪费索引中的空间。
GUIDS可以在应用程序中分配,因此应用程序可以知道它将创建的记录的ID,这可能很方便;但从技术上讲,可能会生成重复的GUID(几率很小,但至少在GUID列上放置唯一索引)。
我同意对于合并数据库来说更容易。但对我来说,直接使用INT更好,然后承担解决如何合并数据库的麻烦,当/如果确实需要时。

1
如果你的数据经常移动,那么GUID是表的主键最好的选择。如果你真的关心性能,就坚持使用int或bigint作为主键。
如果你想利用上述两者,可以将int或bigint用作表的主键,并且每一行都可以有一个rowguid列,以便数据也可以轻松地移动而不失去完整性。

0
如果ids将被显示在查询字符串中,请使用Guid,否则按照规则使用长整型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接