我一直在研究使用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主键?
答案 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,你应该使用别的东西。
例如,解除关联
生成的代理键的值 - 因为它们是生成的并且是任意的 - 与之无关 数据的真实含义 连续举行。检查另一个时 持有外键引用的行 一个代理键,是不可能的 弄清楚它持有的意义 仅仅通过观察即可参考 行中的数据本身。一层是 为每个人添加了这个间接 必须的外键连接 在尝试制作时导航 感觉数据项。这也可以 使审计更加困难,如 不正确的数据不明显 检查。
代理键也不自然 用于导出和共享的数据。 特别困难的是两个 模式的实例可以保存记录 这在逻辑上意味着同样的事情 (也就是说 - 它们是相同的 商业意识),但有一个 由于历史的不同 如何分配密钥。一个 解决这个问题的方法是 采用代理键的规则 从未出口或进口:他们是 从未暴露在数据库之外 除了作为瞬态数据(大多数 显然,在执行应用程序时 与...有“实时”连接的 数据库)。
答案 4 :(得分:0)
要更具体地说明您的问题,是的,在使用GUID作为数据库中的主键时还存在其他问题:
http://www.sqlskills.com/BLOGS/KIMBERLY/post/GUIDs-as-PRIMARY-KEYs-andor-the-clustering-key.aspx
问题不在于使用GUID作为主键,而是使用非顺序GUID作为表的聚簇索引。
这里要点是使用其他字段作为聚簇索引,或者使用顺序GUID来避免这种碎片。