【问题标题】:Primary key (two columns) identity increment主键(两列)标识增量
【发布时间】:2011-11-20 22:40:49
【问题描述】:

我的主键(id、type)中有两列,id 是标识,type 是外键。 我想为 id 列设置种子,如下所示:

 id    type
10000   1
10001   1
10000   2
10001   2
10002   1
10002   2
10000   3

我可以通过代码(或 dml)执行此操作,但想知道是否可以在 ddl 或 SqlServer 表属性中执行此操作?

【问题讨论】:

  • 您对使用触发器有一些限制吗?如果没有,您可以使用一个而不是标识列。
  • 在单一类型中,是否允许序列中有空缺?
  • 当前版本的 SQL Server 中确实不支持此功能,但使用 SQL Server 2012(“Denali”),您将能够创建 SEQUENCE 对象在您的数据库中,这将是完美的 - 他们分发序列号,与任何其他数据库对象完全分开。
  • @marc_s 我不确定 SEQUENCE 是否适用于这个特定目的。对于 OP,您需要为 10000、10001、10002 等中的每一个创建序列,这是不切实际的。您将无法仅在一个序列甚至一组序列中填写类型列。每次 id 列增加时,您都需要创建一个新的

标签: sql-server database-design ddl seed


【解决方案1】:

id 列每行递增 1。没有办法让它重复。有什么理由不能让标识符列成为表的 pk 吗?您可能不得不求助于使用触发器来执行此操作。

【讨论】:

  • 关于原因:嗯,我和我的团队争论过这个问题。该组织有几种发票类型(收款、收款自己的费用、收款预付款...... - 法律禁止)。大约 20 年来,每个型号都以相同的数字开头,我不确定是否要更改。
  • 不清楚您是否可以灵活地更改表结构,但在这种情况下,我总是提倡使用代理键,例如 InvoiceId 作为标识列,然后使用另一列作为自然键。在这种情况下,自然键可能是 InvoiceNo,它是您的 id+type 字段的组合(例如 10001-2、10003-1)。您仍然可以拥有单独的类型列。如果您以这种方式进行设置,那么企业是否会改变对如何生成发票编号的想法并不重要。
  • 闻起来像规范化/数据库设计问题。应该有一个发票表格和一个发票类型表格。虽然发票可以有一个类型列,但它可能不需要是 pk 的一部分。 +1 代理键建议克林特。这就是在数据仓库中处理这些问题的方式。为代理键创建一个新的标识列,并对旧的 id 和 type 列设置唯一约束。
  • @ClintGood - 如果我理解,您建议以下:InvoiceId 身份、NaturalInvoiceId (InvoiceId+type)、FK 类型?在这种情况下,我不允许将例如 10001-2 和 10001-3 作为 NaturalInvoceId。也许我应该独立于 InvoiceId 设置 NaturalInvoiceId(根据类型递增最后一个 NaturalInvoiceId)
  • 在您的情况下,您可能需要一个复合自然键。在这种情况下,我同意您应该独立于 InvoiceId 设置 NatualInvoiceId。
【解决方案2】:

Microsoft SQL Server 不允许您通过 TSQL 轻松地在现有列上添加或更改标识。要更改原始种子值并重新设置任何现有行的种子,您必须删除标识列并重新创建它并指定新的种子值。当表包含数据时,标识号将添加到具有指定种子和增量值的现有行中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-21
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 2022-10-20
    相关资源
    最近更新 更多