同时使用GUID和自增整数

9
我一直在研究在数据库中使用GUID作为主键。到目前为止,优点似乎超过了缺点。然而,我发现有一个地方GUID可能不是我想要的。
在我的应用程序中,用户应该能够根据用户友好的ID来识别对象。因此,例如,如果他们想要获取特定产品而不必输入完整名称,他们可以使用产品的ID。对于这样的东西,GUID不容易记住。
我一直在考虑的解决方案是同时使用GUID和自增整数。 GUID将是行的主键,而自增整数将是应用程序过滤函数使用的索引。但是,所有SQL SELECT、UPDATE、DELETE语句都将使用GUID。
我想使用GUID的主要原因是防止合并两个数据库时发生冲突。如果数据库#1和数据库#2都有一个产品#2,导入脚本将不得不更改ID和所有引用它的外键。使用GUID,我只需要更改表本身中的用户友好ID,而外键将使用每个导入记录唯一的GUID,因此无需修改即可工作。
所以,我的问题是:除了GUID字段大小和易于页面碎片化之外,同时具有自增整数索引和GUID主键是否存在任何重大问题?
5个回答

14

我总是倾向于在我的数据库中使用替代主键。 也就是说:这些主键在问题域中没有实际意义,因此这些主键永远不会暴露给用户。 (如果这个替代主键是GUID或标识的类型,那么我不在意;这取决于要求)。

如果你认为用户应该能够根据用户友好的ID来识别对象,那么我认为这个用户友好的ID是属于你的“问题域”的一个值。 这意味着,这个ID确实应该是你表中的一个属性,但它不应该被用作你表中的主键。

这也使您可以轻松地修改这种用户友好ID的值(如果有必要),而无需担心修改相关外键。


1

“为什么‘用户应该能够根据用户友好的ID识别对象’?”

在我看来,您的用户应该使用代码来识别记录。

假设您的数据库包含产品(正如您在问题中提到的)。如果它们有代表产品的代码,用户可以输入这些代码,那不是更好吗?

比如说,您有桌子和椅子,作为用户,我更喜欢使用tbl和chr而不是1和2来识别我所谈论的内容。


每个模块都执行查找功能。因此,如果用户尝试在“产品”模块中查找ID,则应用程序已经知道他们想要一个产品。 - David Brown

0
在MySQL中,您需要将数字ID设置为PRIMARY KEY,因为AUTO_INCREMENT可能只是PRIMARY KEY,这意味着它也应该是NOT NULL。
您仍然可以在GUID列上定义UNIQUE INDEX并在任何地方使用它,尽管InnoDB表将聚集在数字id上,而不是在GUID上。

抱歉,我忘了提到我正在使用 SQL Server 2008。 - David Brown

0

有一种观点认为,您不应该将您的代理 ID 暴露给外部世界。所以他们会说,如果您想要一个业务 ID,您应该使用其他东西来代替。

例如,这篇维基百科文章 就是这样说的:

解除关联
生成的代理键的值是任意的,因此与行中保存的数据的现实世界含义没有关系。当检查另一行持有对代理键的外键引用时,仅通过查看行本身中的数据就无法确定它持有该引用的含义。每个外键连接都添加了一个层次结构,必须在尝试理解数据项时导航。这也可能使审计更加困难,因为在检查时不会明显地显示不正确的数据。
代理键对于导出和共享的数据也不是自然的。特别困难的是,两个模式实例可以保存逻辑上相同的记录(即,在业务意义上它们是相同的),但由于分配键的历史而具有不同的键。处理这个问题的方法是采用规则:代理键永远不会被导出或导入:除了作为瞬态数据(最明显的是,在执行与数据库的“实时”连接的应用程序时)之外,它们永远不会在数据库之外公开。

0

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