Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 不为主键使用自动递增数字的原因_Sql Server_Primary Key - Fatal编程技术网

Sql server 不为主键使用自动递增数字的原因

Sql server 不为主键使用自动递增数字的原因,sql-server,primary-key,Sql Server,Primary Key,我目前正在处理其他人的数据库,其中的主键是通过一个查找表生成的,该表包含一个表名列表和使用的最后一个主键。存储过程会递增此值,并在将其返回到调用“insert”SP之前检查其唯一性 使用这样的方法(或仅生成GUID)而不是仅使用标识/自动编号有什么好处 我说的不是真正“意味着”ISBN或产品代码之类的主键,而是唯一标识符 谢谢。在您使用复制的情况下,自动生成的ID可能会导致问题(我相信您找到的技术可以解决问题!)。在这些情况下,我通常选择GUID 如果您不太可能使用复制,那么自动递增的PK很可能

我目前正在处理其他人的数据库,其中的主键是通过一个查找表生成的,该表包含一个表名列表和使用的最后一个主键。存储过程会递增此值,并在将其返回到调用“insert”SP之前检查其唯一性

使用这样的方法(或仅生成GUID)而不是仅使用标识/自动编号有什么好处

我说的不是真正“意味着”ISBN或产品代码之类的主键,而是唯一标识符


谢谢。

在您使用复制的情况下,自动生成的ID可能会导致问题(我相信您找到的技术可以解决问题!)。在这些情况下,我通常选择GUID


如果您不太可能使用复制,那么自动递增的PK很可能会正常工作。

递增的过程方法必须是线程安全的。否则,您可能无法获得唯一的号码。此外,它必须快速,否则将成为应用程序瓶颈。内置函数已经考虑了这两个因素。

一个好处是它可以让数据库/SQL更跨平台。SQL Server、Oracle等上的SQL可以完全相同。

对于客户端来说,能够预先分配一整组ID来执行批量插入,而无需使用插入的ID更新其本地对象,这是非常有用的。然后是整个复制问题,正如Galwegian所提到的。

使用唯一标识符将允许您合并来自两个不同数据库的数据

也许您有一个应用程序,它在多个数据库中收集数据,然后在一天中的不同时间与主数据库“同步”。在这种情况下,您不必担心主键冲突


或者,您可能想在实际创建记录之前知道记录的ID是什么。

我能想到的唯一原因是代码是在序列发明之前编写的,而代码忘记了追赶;)

我更愿意在大多数情况下使用GUID,在这些情况下,post的当前方法对我来说是有意义的(复制是可能的)。如果存在复制问题,则此类存储过程必须知道必须链接的另一台服务器,以确保密钥的唯一性,这将使其非常脆弱,而且可能是一种糟糕的方法。

我使用非自动递增标识的整数主键的一种情况是,很少更改的查找表强制使用外键约束,在数据使用应用程序中将具有相应的枚举。在这种情况下,我希望确保enum映射在开发和部署之间是正确的,特别是在有多个prod服务器的情况下。

这样做的唯一真正原因是数据库不可知(如果不同的db版本使用不同的自动编号技术)


这里提到的另一个问题是在多个地方创建记录的能力(比如在中央办公室以及旅行用户的笔记本电脑上)。不过,在这种情况下,您可能需要一个“站点代码”之类的东西,该代码对于每个安装都是唯一的,并且前缀为每个ID。

另一个可能的原因是您故意想要随机密钥。比如说,如果你不想让爱管闲事的浏览器浏览数据库中的每一项,这可能是可取的,但这还不足以保证实际的身份验证安全措施。

使用自动编号本身并没有什么问题,但有几个理由不这样做。不过,正如dacracot所提到的,滚动您自己的解决方案并不是最好的主意。让我解释一下

不在每个表上使用自动编号的第一个原因是,可能会合并多个表中的记录。假设您有一个销售订单表和一些其他类型的订单表,并且您决定提取一些公共数据并使用多表继承。拥有全局唯一的主键很好。这类似于Bobvienholt所说的合并数据库,但它可以发生在数据库中

其次,其他数据库不使用这种模式,而Oracle的序列等其他模式则更好。幸运的是,可以使用SQL Server模拟Oracle序列。一种方法是为整个数据库创建一个单独的自动编号表,称为MainSequence,或者其他什么。数据库中没有其他表将使用autonumber,但是需要自动生成主键的任何人都将使用MainSequence来获取它。这样,您就可以获得dacracot所说的所有内置性能、锁定、线程安全等,而无需自己构建

另一种选择是使用guid作为主键,但我不建议这样做,因为即使您确信人类(甚至开发人员)永远不会阅读它们,也可能有人会阅读,而且这很难。更重要的是,在T-SQL中,隐式转换为int非常容易,但是隐式转换为GUID会有很多麻烦。基本上,它们是不方便的

在构建新系统时,我建议使用专用表生成主键(就像Oracle序列一样)。对于现有数据库,我不会特意更改它。

来自:

专业指南

  • 每个表、每个数据库、每个服务器都是唯一的
  • 允许轻松合并来自不同数据库的记录
  • 允许跨多台服务器轻松分发数据库
  • 您可以在任何地方生成ID,而不必往返数据库
  • 大多数复制方案仍然需要GUID列
GUID Cons

  • 它比传统的4字节索引值大4倍;如果不小心,这可能会对性能和存储造成严重影响
  • increment = 2
    db1 - offset = 1
    db2 - offset = 2