我曾经在许多数据库系统上工作过,如果所有的数据库键都是GUID / UUID值,那么在数据库之间移动条目就会容易得多。我考虑过几次采用这种方法,但总有一些不确定性,特别是在性能和无法通过电话读出的url方面。

有人在数据库中大量使用guid吗?这样做会有什么好处,可能的陷阱是什么?


当前回答

@Matt谢泼德:

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

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

接下来,出于某种原因(我想不出是什么原因),要求您向客户表添加一个GUID列,并将其作为主键。如果客户标识符列现在没有惟一性保证,那么您将在整个组织中引起未来的麻烦,因为guid将始终是惟一的。

Some "architect" might tell you that "oh, but we handle the real customer uniqueness constraint in our app tier!". Right. Fashion regarding that general purpose programming languages and (especially) middle tier frameworks changes all the time, and will generally never out-live your database. And there is a very good chance that you will at some point need to access the database without going through the present application. == Trouble. (But fortunately, you and the "architect" are long gone, so you will not be there to clean up the mess.) In other words: Do maintain obvious constraints in the database (and in other tiers, as well, if you have the time).

换句话说:向表中添加GUID列可能有很好的理由,但请不要因此降低了在真实(==非GUID)信息中保持一致性的目标。

其他回答

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

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

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

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

@Matt Sheppard我想他的意思是你可以用不同的guid作为主键来复制行。这是任何类型的代理键都存在的问题,而不仅仅是guid。就像他说的,这很容易解决,只需向非键列添加有意义的惟一约束。另一种选择是使用天然钥匙,而这些钥匙存在实际问题。

guid在将来可能会给您带来很多麻烦,如果它们被用作“唯一符”,让重复的数据进入您的表。如果您想使用guid,请考虑在其他列上仍然保持unique -约束。

primary-keys-ids-versus-guids

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

神话,GUID vs. Autoincrement (MySQL 5)

这就是你真正想要的。

UUID优点

每个表,每个数据库,每个服务器都是独一无二的 允许轻松合并来自不同数据库的记录 允许跨多个服务器轻松分布数据库 您可以在任何地方生成id,而不必往返于数据库 大多数复制场景都需要GUID列

GUID笨蛋

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

优点:

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

到目前为止还没有提到的一件事是:uuid使分析数据变得更加困难

至少对于web应用程序来说,通过url中的id访问资源是很常见的,比如stackoverflow.com/questions/45399。如果id是整数,则两者都是

提供有关问题数目的资料(即2008年9月5日,第45,399个问题被问到) 提供了一个迭代问题的杠杆点(当我将其增加1时会发生什么?我打开下一个问题)

从第一点开始,我可以结合问题的时间戳和数字来分析问题被问到的频率,以及它如何随时间变化。这在像Stack Overflow这样的网站上不太重要,因为它有公开的信息,但是,根据上下文,这可能会暴露敏感信息。

例如,我是一家为客户提供权限门控门户的公司。地址是portal.com/profile/{customerId}。如果id是一个整数,您可以通过定期查询lastKnownCustomerCount + 1来分析客户数量,而不管是否能够看到他们的信息,并检查结果是否为404 - NotFound(客户不存在)或403 - Forbidden(客户确实存在,但您没有访问权限)。

uuid的非连续性质缓解了这些问题。这并不是为了防止侧写,但这是一个开始。