我曾经在一些数据库系统中工作过,如果所有的数据库键都是Guid / uuid值,那么在数据库之间移动条目就会容易得多。我考虑过几次采用这种方法,但总有一些不确定性,特别是在性能和无法通过电话读出的url方面。
有人在数据库中大量使用guid吗?这样做会有什么好处,可能的陷阱是什么?
主要的优点是您可以在不连接到数据库的情况下创建唯一的id。id是全局唯一的,因此您可以轻松地组合来自不同数据库的数据。这些看起来都是小优势,但在过去却为我节省了很多工作。
主要的缺点是需要更多的存储空间(在现代系统上不是问题),并且id不是真正的人类可读。在调试时,这可能是一个问题。
存在一些性能问题,如索引碎片。但这些都是很容易解决的(梳子guids by jimmy nilson: http://www.informit.com/articles/article.aspx?p=25862)
编辑合并了我对这个问题的两个答案
@Matt Sheppard我想他的意思是你可以用不同的guid作为主键来复制行。这是任何类型的代理键都存在的问题,而不仅仅是guid。就像他说的,这很容易解决,只需向非键列添加有意义的惟一约束。另一种选择是使用天然钥匙,而这些钥匙存在实际问题。
guid在将来可能会给您带来很多麻烦,如果它们被用作“唯一符”,让重复的数据进入您的表。如果您想使用guid,请考虑在其他列上仍然保持unique -约束。
@Matt谢泼德:
假设你有一桌子的顾客。当然,您不希望一个客户在表中存在多次,否则整个销售和物流部门将会发生许多混乱(特别是当关于客户的多行包含不同的信息时)。
因此,您有一个唯一标识客户的客户标识符,并确保客户(在发票中)知道该标识符,以便客户和客户服务人员在需要沟通时有一个共同的参考。为了保证没有重复的客户记录,可以通过客户标识符上的主键或通过客户标识符列上的NOT NULL + UNIQUE约束向表中添加唯一性约束。
接下来,出于某种原因(我想不出是什么原因),要求您向客户表添加一个GUID列,并将其作为主键。如果客户标识符列现在没有惟一性保证,那么您将在整个组织中引起未来的麻烦,因为guid将始终是惟一的。
一些“架构师”可能会告诉你“哦,但是我们在应用程序层中处理真正的客户唯一性约束!”正确的。通用编程语言和(特别是)中间层框架一直在变化,通常永远不会比数据库更长寿。您很有可能在某个时候需要访问数据库,而不需要通过当前应用程序。= =麻烦。(但幸运的是,你和“建筑师”早已不在,所以你不会在那里收拾烂摊子。)换句话说:要在数据库中维护明显的约束(如果有时间,也要在其他层中维护)。
换句话说:可能有很好的理由将GUID列添加到表中,但请不要陷入诱惑,降低您在真正的 (==non-GUID)信息中一致性的野心。
优点:
缺点:
就我个人而言,我在任何一个相当大的系统中使用它们进行大多数PK,但我得到了“训练”。在一个到处复制的系统上,所以我们必须拥有它们。YMMV。
我认为重复数据的事情是垃圾-你可以得到重复的数据,无论你做什么。在我工作的任何地方,代理键通常都不受欢迎。我们确实使用类似于wordpress的系统:
< >强更新: 所以这个得到了很多+1,我想我应该指出GUID PK的一个大缺点:聚集索引。
如果您有很多记录,并且在GUID上有一个聚集索引,那么您的插入性能将非常糟糕,因为您将插入到项目列表中的随机位置(这是重点),而不是在末尾(这是快速的)。
因此,如果你需要插入性能,也许可以使用auto-inc INT,如果你想与其他人共享它,则生成一个GUID(例如,在URL中向用户显示它)。
为什么没人提性能?当你有多个连接时,都是基于这些讨厌的guid,性能将通过地板,一直在那里:(
如果您还将该列用作聚集索引(一种相对常见的做法),那么使用GUIDS作为主键需要考虑的另一个小问题是。你会在插入时受到打击,因为guid的本质不是按顺序开始的,因此当你插入时,它们会出现页面分割等。只是需要考虑的问题,如果系统将有高IO…
primary-keys-ids-versus-guids
guid作为主键的代价 (SQL Server 2000)
神话,GUID vs. Autoincrement (MySQL 5)
这就是你真正想要的。
UUID优点
GUID缺点
有一件事没有真正解决,即使用随机 (UUIDv4) id作为主键将损害主键索引的性能。无论表是否围绕键聚集,都会发生这种情况。
RDBMs通常确保主键的唯一性,并确保在一个名为BTree的结构中通过一个键进行查找,这是一个具有大分支因子的搜索树(二叉搜索树的分支因子为2)。现在,一个连续整数ID将导致插入只发生在树的一个一侧,而大多数叶节点不受影响。添加随机uuid将导致插入拆分整个索引中的叶节点。
同样地,如果存储的数据主要是临时的,通常情况下需要访问最新的数据,并根据最新的数据进行连接。对于随机uuid,模式将无法从中受益,并将访问更多的索引行,因此需要内存中更多的索引页。如果最需要最近的数据,那么使用顺序id,热索引页将需要更少的RAM。
到目前为止还没有提到的一件事是:uuid使分析数据变得更加困难
至少对于web应用程序,通常使用url中的id访问资源,如stackoverflow.com/questions/45399。如果id是整数,则两者都是
stackoverflow.com/questions/45399
从第一点开始,我可以结合问题的时间戳和数字来分析问题被问到的频率,以及它如何随时间变化。这在像Stack Overflow这样的网站上不太重要,因为它有公开的信息,但是,根据上下文,这可能会暴露敏感信息。
例如,我是一家为客户提供权限门控门户的公司。地址是portal.com/profile/{customerId}。如果id是一个整数,你可以分析客户的数量,而不需要定期查询lastKnownCustomerCount + 1来查看他们的信息,并检查结果是否为404 - NotFound(客户不存在)或403 - Forbidden(客户确实存在,但你没有访问权限)。
portal.com/profile/{customerId}
lastKnownCustomerCount + 1
404 - NotFound
403 - Forbidden
uuid的非连续性质缓解了这些问题。这并不是为了防止侧写,但这是一个开始。