【问题标题】:SQL Server - formatted identity columnSQL Server - 格式化的标识列
【发布时间】:2016-07-06 20:35:53
【问题描述】:

我想在格式为 FOO-BAR-[标识号] 的表中有一个主键列,例如:

FOO-BAR-1  
FOO-BAR-2  
FOO-BAR-3  
FOO-BAR-4  
FOO-BAR-5  

SQL Server 可以做到这一点吗?还是我必须使用 C# 来管理序列?如果是这种情况,我怎样才能使用 EntityFramwork 获得下一个 [identity number] 部分?

谢谢

编辑:

我需要这样做是因为此列表示发送给客户的通知的唯一标识符。

  • FOO 将是一个常量字符串
  • BAR 将根据通知的类型(检测、警告或强制执行)而有所不同

那么只有一个 int 标识列并在 C# 中的业务逻辑层中附加值会更好吗?

【问题讨论】:

  • 将 foo-bar 添加到主键可能毫无意义!你是说字符串是不变的吗?
  • 字符串会根据记录的类型而有所不同。例如 Foo-CategoryA-1 Foo-CategoryB-2 等
  • 为什么不将字符串作为另一列?
  • 如果您想将主列的第一部分设为常量(FOO-BAR-),您至少可以收到此表的性能问题。如果某些业务逻辑需要这个,您可以在此表中设置 int identity 主键,并在业务层将常量添加到该键中。
  • 我很想将标识字段保持原样,并可能查看计算列或计算字段以将您的前缀添加到标识列。

标签: c# sql sql-server identity-column


【解决方案1】:

如果您想在报告中使用这个“合成”字段,我建议您:

  1. 使用 INT IDENTITY 字段作为表中的 PK
  2. 为此表创建视图。在此视图中,您还可以使用字符串和类型生成所需的字段。
  3. 在您的报告中使用此视图。

但我仍然认为,数据库设计存在很大问题。我希望您尝试使用规范化重新设计。

【讨论】:

  • 计算列也可以工作,这不需要视图。计算列不应该是主键;最佳做法是不向用户提供您的主键。
  • 同意,可以是计算列,这种情况下不需要视图。
【解决方案2】:

您可以将任何内容设置为表中的 PK。但在这种情况下,我会将IDENTITY 设置为只是一个自动递增的 int,并根据使用它的原因在 SQL、BLL 或 UI 中手动将 FOO-BAR- 附加到它。如果FOOBAR 有商业原因,那么您还应该将它们设置为数据库行中的值。然后,您可以根据实际使用这些值的原因,在两三列之间的数据库中创建一个键。

但是 IMO 我真的认为没有真正的理由以这种方式连接 ID 并将其存储在数据库中。但话又说回来,我真的只使用int 作为我的 ID。

【讨论】:

    【解决方案3】:

    另一种选择是使用我以前所在的一个老团队,称为代码和值表。我们并没有为此使用它(我们使用它来代替自动递增标识以防止某些关键表的环境不匹配),但您可以这样做:

    1. 创建一个表,其中每个类别都有一行。行中有两(或更多)列 - 类别名称和下一个数字中的最小值。
    2. 当您在另一个表中插入一条记录时,您将运行一个存储过程来获取该类别的下一个可用标识号,将代码和值表中的数字加 1,然后将类别和数字连接在一起供您插入。

    但是,如果您的主表是一个包含大量插入的大容量表,那么您可能会遇到乱序的内容。

    无论如何,即使数量不高,我认为您最好重新审视一下为什么要这样做,看看是否有其他更好的方法来做到这一点(例如拥有业务层或正如其他人所建议的那样,用户界面会这样做)。

    【讨论】:

      【解决方案4】:

      使用这样的计算列是很有可能的:

      CREATE TABLE #test (
          id INT IDENTITY UNIQUE CLUSTERED,
          pk AS CONCAT('FOO-BAR-', id) PERSISTED PRIMARY KEY NONCLUSTERED,
          name NVARCHAR(20)
      )
      
      INSERT INTO #test (name) VALUES (N'one'), (N'two'), (N'three')
      
      SELECT id, pk, name FROM #test
      
      DROP TABLE #test
      

      请注意,pk 故意设置为 NONCLUSTERED,因为它是 VARCHAR 类型,而 IDENTITY 字段(无论如何都是唯一的)设置为 UNIQUE CLUSTERED。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-03
        • 1970-01-01
        • 2013-06-08
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        相关资源
        最近更新 更多