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

Sql server 同时使用GUID和自动递增整数,sql-server,database,indexing,primary-key,guid,Sql Server,Database,Indexing,Primary Key,Guid,我一直在研究如何使用guid作为数据库中的主键。到目前为止,利大于弊。然而,我看到一点,guid可能不是我想要的 在我的应用程序中,用户应该能够基于用户友好的ID来识别对象。因此,例如,如果他们想在不键入全名的情况下获得特定产品,他们可以使用产品的ID。对于类似的情况,GUI不容易记住 我一直在考虑的解决方案是同时使用GUID和自动递增整数。GUID将是行的主键,而自动递增的整数将是应用程序的筛选函数使用的索引。但是,所有SQL SELECT、UPDATE和DELETE语句都将使用GUID 我想

我一直在研究如何使用guid作为数据库中的主键。到目前为止,利大于弊。然而,我看到一点,guid可能不是我想要的

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

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

我想使用guid的主要原因是为了防止合并两个数据库时发生冲突。如果数据库#1和数据库#2都有产品#2,导入器脚本必须更改ID和所有引用它的外键。对于GUID,我只需更改表本身中的用户友好ID,而外键将使用每个导入记录唯一的GUID,因此无需修改即可工作


因此,我的问题是:拥有一个自动递增的整数索引和一个GUID主键是否存在任何主要问题(除了GUID字段的大小和容易的页面碎片)?

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

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


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

MySQL
中,您需要将数字
ID
设置为
主键,由于
自动增量
可能只是
主键
,这意味着它也应该是
非空的


您仍然可以在
GUID
列上定义
唯一索引
,并在任何地方使用它,尽管
InnoDB
表将聚集在数值
id
上,而不是
GUID

上有一个学派认为您永远不应该将代理id暴露给外部世界。所以他们会说,如果你想要一个商业ID,你应该使用其他东西

例如,他说:

分离

生成的代理键的值 -因为它们是生成的和任意的-与 数据的现实意义 排成一行。检查另一个时 包含对的外键引用的行 如果是代理密钥,则无法 弄清楚它的意思 通过查看 行本身中的数据。一层是 添加到每个 必须加入的外键 在尝试进行导航时进行导航 数据项的意义。这也可以 使审计更加困难,如 不正确的数据在屏幕上不明显 检查

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

“为什么“用户应该能够基于用户友好的ID识别对象”

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

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


假设你有桌子和椅子,作为一个用户,我更喜欢使用tbl和chr而不是1和2来确定我在说什么。

要更具体地回答你的问题,是的,在数据库中使用GUI作为主键还有其他问题:

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


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

对不起,我忘了提到我使用的是SQL Server 2008。查找功能在每个模块中执行。因此,如果用户试图在“产品”中查找ID“模块,应用程序已经知道他们想要一个产品。