【问题标题】:"There can only be one IDENTITY column per table" - Why?“每个表只能有一个 IDENTITY 列” - 为什么?
【发布时间】:2011-04-17 23:09:56
【问题描述】:

“每个表只能有一个 IDENTITY 列”

为什么会这样?以车辆为例,存在唯一的底盘号和唯一的注册号。为了在 sql server 中描述这个场景,我们需要一个自定义的实现来实现一个列。相反,在 Oracle 中,您可以在一个表上拥有任意数量的序列。为什么对 IDENTITY 列有限制,有什么具体原因吗?

拥有车辆架构的场景是虚构的,我质疑自己为什么对身份列有限制。

【问题讨论】:

  • 我想知道为什么不可能。
  • 因为 SQL Server 团队的工程师要么做不到,要么认为这样做不是个好主意。
  • PostgreSQL 也 [谢天谢地] 有序列,我同意它们是比 IDENTITY 更好的方法(以及 MySQL 的 auto_increment )。为什么 SQL Server 不支持这个?我认为这是对 SQL Server 所基于的 Sybase 代码的回归,但构建该代码的人从未遇到过这种需求。我承认,需要非常极端。
  • 听起来有人正在放弃对 SqlServer 的需求实现。
  • @Chaitanya - 如果你的索引被正确应用,它不会很糟糕。另请记住,您在设计中禁止任何人拥有多于一辆车。理想情况下,车辆将有一个 ID,车主将有一个 ID,并且您将有更大的灵活性来模拟现实世界的情况。我想这将取决于您是希望您的数据适合现实世界,还是让现实世界适应您的数据模型......

标签: sql-server identity-column database-design


【解决方案1】:

SQL Server 中的标识列有一个种子和一个自动增量。如果我们知道第一个 id 列的值,我们总是可以计算出第二个假设的 id 值应该是多少。

例如如果这是合法的语法

create table #foo
(
bar int identity(1,10),
baz int identity(1000,1)
)

我们不需要存储 baz,因为它可以从 bar 计算如下。

baz = 1000 + (bar-1)/10

【讨论】:

  • 该死的你说出我想说的话!
  • 很晚了,但是如果bar 是guid 而baz 是int 呢?
  • @ibubi IDENTITY 在 SQL Server 中始终是某种整数。您不能使用 IDENTITY 属性声明 guid 列。
【解决方案2】:

因为这将是相同的值。如果你有 identity(1,1) 作为主要,并且 identity(100,2),你会得到这些结果:

1     100
2     102
3     104
4     106
5     108
6     110
7     112
8     114
9     116
10    118

您可以通过这样做获得第二列:

((ID-1)*2)+100

这是一个线性方程,那么除了展示之外还有什么意义呢?

【讨论】:

  • IDENTITY 值并不总是按顺序分配。如果您有两个同时插入的多行,则这些值可以在两组行之间交错。此外,可以插入特定值,以便两列不相互依赖。您可能需要两个 IDENTITY 列的几个原因。
  • @dportas,当然可以,但理论上,如果你有 2 个身份,它们会同时被分配,仍然给你同样的效果。
  • 很好的答案!
【解决方案3】:

数据存储在数据库中,由IDENTITY 列键控。单个这样的列允许类似文件系统的存储。拥有多个 IDENTITY 列会混淆问题。

我的建议是选择您的一个列作为IDENTITYPRIMARY KEY,而另一个作为UNIQUE KEY。作为用户不会有什么不同,但它会让 DBMS 高兴。

【讨论】:

    【解决方案4】:
    • Oracle 序列不是 SQL Server IDENTITY 列:您为它们编写了一些代码。它们不能根据 CREATE TABLE DDL 开箱即用
    • 任何后续 IDENTITY 列都可以从第一个列中计算出来(编辑:正如其他人提到的)

    【讨论】:

      【解决方案5】:

      我可以找到的 MSDN 中没有解释原因。但是,我怀疑它与 sql server 实现标识列的方式有关。从概念上讲,我认为它更多的是表级别的设置或值,而不是列级别,列只是访问值的一种方式。我认为这是因为所有与标识值交互的方法都将表作为参数而不是列,例如。 IDENT_SEED、IDENT_CURRENT 和 IDENT_INCR。如果是列级设置,则参数将包括列名。如果表上有多个标识列,则这些功能将不起作用。

      不过,我只是在猜测。

      【讨论】:

        【解决方案6】:

        我同意这是一个愚蠢的限制。不过,解决它并不太难。只需创建一个带有 IDENTITY 列的单独表,以纯粹用作序列生成器。插入序列表,使用 SCOPE_IDENTITY() 检索值,然后将值插入到您喜欢的任何位置。然后,您可以根据需要支持任意数量的序列。

        【讨论】:

          【解决方案7】:

          您可以改用 computed 列,从某个值加上 id 值开始:

          CREATE TABLE dbo.TwoIdentity (id INT IDENTITY (1,1) NOT NULL, SecondID AS 100+id, TEXT VARCHAR(50) NULL)
          

          【讨论】:

            猜你喜欢
            • 2012-11-14
            • 1970-01-01
            • 2023-03-22
            • 1970-01-01
            • 2011-05-07
            • 1970-01-01
            • 1970-01-01
            • 2019-07-17
            相关资源
            最近更新 更多