同时使用GUID和自动递增整数

时间:2009-04-03 15:28:48

标签: sql-server database indexing primary-key guid

我一直在研究使用GUID作为数据库中的主键。到目前为止,专业人士似乎超过了缺点。但是,我看到GUID可能不是我想要的一点。

在我的应用程序中,用户应该能够根据用户友好的ID识别对象。因此,例如,如果他们想要在不输入全名的情况下获得特定产品,他们可以使用产品的ID。对于类似的东西,GUID并不容易记住。

我一直在考虑的解决方案是使用GUID和自动递增整数。 GUID将是行的主键,而自动递增的整数将是应用程序的过滤函数使用的索引。但是,所有SQL SELECT,UPDATE,DELETE语句都将使用GUID。

我想使用GUID的主要原因是在合并两个数据库时防止冲突。如果Database#1和Database#2都有Product#2,则导入器脚本必须更改ID以及引用它的所有外键。使用GUID,我只需要更改表本身的用户友好ID,而外键将使用每个导入记录唯一的GUID,因此无需修改即可使用。

所以,我的问题是:是否有任何重大问题(除了GUID字段的大小和简单的页面碎片)与自动递增整数索引和GUID主键?

5 个答案:

答案 0 :(得分:13)

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

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

这也允许您轻松修改这种用户友好ID的值(如果这是必要的话),而不必担心修改相关的外键。

答案 1 :(得分:1)

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

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

假设您的数据库包含产品(正如您在问题中提到的那样)。如果他们有代码来代表产品,用户可以进入,那会不会更好。

假设您有桌椅,作为用户,我更喜欢使用tbl和chr而不是1和2来识别我在说什么。

答案 2 :(得分:0)

MySQL中,您需要将数字ID设置为PRIMARY KEY,因为AUTO_INCREMENT可能只是PRIMARY KEY,这意味着它也应该是NOT NULL

您仍然可以在UNIQUE INDEX列上定义GUID并在任何地方使用它,但InnoDB表格会聚集在数字id上,而不是{ {1}}。

答案 3 :(得分:0)

有一种思想流派认为你不应该将你的代理身份证暴露给外面的世界。所以他们会说如果你想要一个商业ID,你应该使用别的东西。

例如,

This Wikipedia article说:

  

解除关联

     

生成的代理键的值    - 因为它们是生成的并且是任意的 - 与之无关   数据的真实含义   连续举行。检查另一个时   持有外键引用的行   一个代理键,是不可能的   弄清楚它持有的意义   仅仅通过观察即可参考   行中的数据本身。一层是   为每个人添加了这个间接   必须的外键连接   在尝试制作时导航   感觉数据项。这也可以   使审计更加困难,如   不正确的数据不明显   检查。

     

代理键也不自然   用于导出和共享的数据。   特别困难的是两个   模式的实例可以保存记录   这在逻辑上意味着同样的事情   (也就是说 - 它们是相同的   商业意识),但有一个   由于历史的不同   如何分配密钥。一个   解决这个问题的方法是   采用代理键的规则   从未出口或进口:他们是   从未暴露在数据库之外   除了作为瞬态数据(大多数   显然,在执行应用程序时   与...有“实时”连接的   数据库)。

答案 4 :(得分:0)

要更具体地说明您的问题,是的,在使用GUID作为数据库中的主键时还存在其他问题:

http://www.sqlskills.com/BLOGS/KIMBERLY/post/GUIDs-as-PRIMARY-KEYs-andor-the-clustering-key.aspx

问题不在于使用GUID作为主键,而是使用非顺序GUID作为表的聚簇索引

这里要点是使用其他字段作为聚簇索引,或者使用顺序GUID来避免这种碎片。