【发布时间】:2011-02-22 20:04:23
【问题描述】:
为什么Sql server 不允许在一张表中有多个IDENTITY 列??任何具体原因。
【问题讨论】:
-
接受的答案是错误的原因。即使它允许您创建两个身份列,尽管as here
标签: sql sql-server
为什么Sql server 不允许在一张表中有多个IDENTITY 列??任何具体原因。
【问题讨论】:
标签: sql sql-server
你为什么需要它? SQL Server 为每个具有IDENTITY 列的表跟踪单个值(当前标识值),因此每个表只能有一个标识列。
【讨论】:
身份列是数据库表中的一列(也称为字段):-
这很像 Microsoft Access 中的自动编号字段或 Oracle 中的序列。
标识列与主键的不同之处在于它的值由服务器管理并且(除了极少数情况)不能修改。在许多情况下,标识列用作主键,但并非总是如此。
SQL 服务器使用标识列作为键值来引用特定行。所以只能创建一个标识列。此外,如果没有明确声明标识列,Sql server 会在内部存储一个单独的列,其中包含每行的键值。如前所述,如果您希望多个列具有唯一值,则可以使用 UNIQUE 关键字。
【讨论】:
SQL Server 将标识存储在内部表中,使用表的 id 作为键。因此,SQL Server 不可能在每个表中拥有多个 Identity 列。
【讨论】:
因为 MS 意识到,超过 80% 的用户只希望每个表有一个自动增量列,而拥有第二个(或更多)的解决方法很简单,即创建一个 IDENTITY,种子 = 1,增量 = 1 然后计算列将自动生成的值乘以一个因子以更改增量并添加偏移量以更改种子。
【讨论】:
是的,Sequences 允许多个身份,例如 atable 中的列,但这里存在一些问题。在典型的开发场景中,我看到开发人员在列中手动插入有效值(假设是通过序列插入)。稍后当一个序列尝试向表中插入值时,它可能会由于唯一键冲突而失败。
此外,在多开发人员/多供应商的情况下,开发人员可能对多个表使用相同的序列(因为序列未链接到表)。这可能会导致其中一个表中的值缺失。即 tableA 可能会得到值 1,而 tableB 可能会使用值 2,而 tableA 会得到 3。这意味着 tableA 将有 1 和 3(缺少 2)。
除此之外,还有另一种情况,您有一个每天都会被截断的表。由于序列与 table 没有任何链接,因此截断的表将继续使用 Seq.NextVal 再次(除非您手动重置序列),从而在一段时间后导致缺失值甚至更危险的算术溢出错误。
由于上述原因,我觉得 Oracle 序列和 SQL 服务器标识列都适合它们的用途。我更喜欢 oracle 实现标识列的概念和 SQL Server 实现序列概念,以便开发人员可以根据需要实现两者中的任何一个。
【讨论】:
标识列的全部目的是它将包含表中每一行的唯一值。那么,为什么在任何给定的表中都需要不止一个呢?
如果您确实需要不止一个,也许您需要澄清您的问题。
【讨论】:
标识列用于唯一标识表的单行。如果您希望其他列是唯一的,您可以为您可能需要的每个“身份”列创建一个 UNIQUE 索引。
【讨论】:
我一直认为这是对 SQL Server 的任意且不好的限制。是的,您只需要一个标识列来实际标识一行,但是有正当理由希望数据库为数据库中的多个字段自动生成一个数字。
这就是 Oracle 中序列的好处。它们没有绑在桌子上。您可以使用几个不同的序列在同一个表中填充任意数量的字段。您也可以让多个表共享相同的序列,尽管这可能是一个非常糟糕的决定。但关键是你可以。它更精细,为您提供更大的灵活性。
序列的坏处是您必须编写代码来实际递增它们,无论是在您的插入语句中还是在表上的插入触发器中。 SQL Server 标识的好处在于,您所要做的就是更改属性或在表创建中添加关键字,然后就完成了。
【讨论】: