【问题标题】:Custom PrimaryKey Generation with autoincrement使用自动增量生成自定义主键
【发布时间】:2011-01-01 02:17:26
【问题描述】:

我需要为 2 个或更多表定义和生成主键。

表格包含相同类型的数据,但对于某些业务规则,我们必须将它们分开,比如

表 A = LOCAL_CUSTOMERS
表 B = INTERNATIONAL_CUSTOMERS

两者都包含相同的列,例如 CUSTOMER_ID C_NAME、CITY ....etc

在设计主键时,我希望这些键是 PREFIX 和自动生成的数字,就像自动递增的 int PK 一样。

例如,表“LOCAL_CUSTOMERS”的 CUSTOMER_ID (PK)

LOC1, LOC2, LOC3,...... LOC5000

和表“INTERNATIONAL_CUSTOMERS”的 CUSTOMER_ID (PK)

INT1、INT2、INT3、……INT5000

WHERE LOC 和 INT 是 LOCAL 、 INTERNATIONAL 的前缀。

我们可以使用 int 在“身份规范”中设置自动增量,但我该怎么做呢? 我需要为列设置“计算列规范”吗?

谢谢

【问题讨论】:

    标签: sql-server primary-key auto-increment


    【解决方案1】:

    您绝对可以使用计算列来做到这一点。

    如果你坚持使用你的两个表,你可以像这样简单地添加一个计算的、持久的列:

    ALTER TABLE Local_Customer
      ADD CustomerID AS 'LOC' + CAST(ID AS VARCHAR(7)) PERSISTED
    
    ALTER TABLE International_Customer
      ADD CustomerID AS 'INT' + CAST(ID AS VARCHAR(7)) PERSISTED
    

    如果您决定使用一个带有鉴别器列的表,例如BIT 类型的“IsDomestic”,您可以根据“IsDomestic”列的值创建一个使用“LOC”或“INT”作为前缀的计算列:

    ALTER TABLE Customer
      ADD CustomerID AS CASE IsDomestic WHEN 0 THEN 'INT' ELSE 'LOC' END + CAST(ID AS VARCHAR(7)) PERSISTED
    

    无论哪种方式 - 您的 INT IDENTITY 类型的“ID”字段将针对每一行自动增加,并且计算列将自动创建一个更易读的“CustomerID”,而无需您做任何进一步的努力。

    【讨论】:

    • 感谢伙伴理解问题并提供“解决方案”
    【解决方案2】:

    其他答案都是有效的。

    我想补充一点,因为似乎希望为本地和国际客户提供单独的序列,因此依赖任何特定的序列行为都是一个坏主意。特别是,对于标识列,如果插入失败并回滚,则可能存在间隙(标识立即为事务保留,但如果约束或触发器失败,则永远不会插入)。也可以更改种子和间距,也可以使用标识插入来插入非顺序值。

    我会提倡使用带有客户类型标志的真正代理身份列。您的身份列在所有客户中都是唯一的。如果您绝对想要单独的序列,您可以编写触发器以获得真正的非间隙序列或使用标识。然后,您可以按照您的建议使用持久计算列来构建组合键并根据您的需要在该列上放置索引。

    【讨论】:

      【解决方案3】:

      如果您提议的 2 个表具有相同的列,那么我认为您根本没有理由将它们分开。创建一个用于存储客户类型(国际或国内)的列并以这种方式进行跟踪。一张就够了,为什么还要用两张?

      【讨论】:

        【解决方案4】:

        您尝试实现的内容称为子类型:同种对象的特殊情况。有几种常见的实现方式:

        1. 制作一个包含两种类型所需的所有列的表。对那些不适用于所有类型的属性使用 NULLable 列,对所有其他属性使用强制列。只有一张桌子,所以只在pk上。
        2. 使用为所有常见属性(基本类型)生成的 pk 创建一个表。为每个子类型添加单独的表。这些表有一个 pk,它使用外键指向基本类型的 pk(因此,与基本类型具有 1:1 的关系)。所以这两种类型都来自同一组键值

        (还有更多方法,但这些方法最有用,也最流行)

        我强烈建议不要使用各种“智能”键。当然,您可以在表中使用“类型”列(用于基本类型的列)来快速确定您正在处理的内容。但是像您建议的关键方案只是使事情复杂化,没有真正的价值。

        【讨论】:

          【解决方案5】:

          我认为您应该尽可能将它们放在同一张表中,并添加另一列来区分本地客户和国际客户。使用 2 张桌子,您可以将将来在这些桌子上需要做的所有工作加倍。更不用说使用计算出的varchar id 值而不是简单生成的long id。

          【讨论】:

            【解决方案6】:

            您可以在区域 ID 和自动 ID 上使用复合键。

            还可以有一个触发器,在插入时将 pk 设置为自定义字符串。

            一般来说,最好将它们保存在同一个表中(因为它们具有相同的列)并且仅在本地与国际之间有所不同。

            【讨论】:

              猜你喜欢
              • 2012-04-16
              • 1970-01-01
              • 2014-06-17
              • 2019-08-29
              • 2013-02-15
              • 1970-01-01
              • 1970-01-01
              • 2014-04-21
              相关资源
              最近更新 更多