1

我想在 Documents 表上创建一个复合键(这就是想法,但我愿意接受其他建议)。它将由两列组成,年份 (2010,...) 和一个 ID,这将是自动递增的,但它应该每年重新启动。

因此,像 2010-1、2010-2、...、2011-1、2011-2 等这样的键,最好也应该用于显示、打印和搜索。

虽然我不相信自动增量会起作用,但由于每年都会重置,所以我想我必须自己进行增量,不是吗?

还是我应该只创建一个 varchar 列并自己构建每个键,然后在该列上放置一个唯一的?

那么,我有哪些选择?

还请考虑我在选择的设计中可能遇到的未来设计问题,无论它是什么以及易于查询。

更新:

我真的开始考虑让应用程序构造密钥并在插入时提供它。但是,它需要在数据库中查找最后发布的 ID,这可能会导致大量使用的问题。

4

4 回答 4

3

将业务与数据存储结构分开是一种很好的做法。为什么?因为明天有人会决定改变业务逻辑:

  • 使用非整数文档顺序(1-AA、1-AB、1-AC...)
  • 包括年份和月份以构建一些月度报告
  • 任何其他变化...

你应该怎么做呢?

所以,我的解决方案是:

  • 使用主键(例如 int 或您喜欢的数据类型)与数据库中的其他表建立关系
  • 使用业务密钥 1.2.3 ...如您所愿(也许是一些标识符生成器)
  • 使用 datetime 字段存储添加文档的日期,您可以动态计算年份。
于 2010-08-04T22:24:54.023 回答
1

虽然我不相信自动递增会起作用,因为每年都会重置,所以我想我必须自己增加,不是吗?

是的。

我建议添加一列以生成重置值。IDENTITY 列是最好的;一个 DATETIME 可以保存记录创建时间,但彼此相隔 3.33 毫秒(0. 00333 秒)内的事务将具有相同的时间戳。

无论哪种方式,您都可以id使用以下方法生成值:

SELECT (SELECT COUNT(*)
          FROM DOCUMENTS t
         WHERE t.year = d.year
           AND t.col <= d.col) AS id,
        d.year
   FROM DOCUMENTS d

或者,如果您使用的是 SQL Server 2005+,则可以使用:

 SELECT ROW_NUMBER() OVER (PARTITION BY d.year ORDER BY d.col) AS id,
        d.year
   FROM DOCUMENTS d
于 2010-08-04T21:57:19.893 回答
1

为什么不添加一个实际的自动递增 id?复合键可以迅速增长到它们几乎无用的地方——尤其是出于性能原因,如果您必须加入表中。如果您还想记录 Document XYZ 是 2010 年存储的第一个文档,您仍然可以拥有您的YearOrder(或其他)列,但您的主键保持干净整洁。

于 2010-08-04T21:58:10.020 回答
1

如果您要麻烦创建一个自动递增键,我会放弃每年重置它的想法,而只使用 IDENTITY INT 列。

如果您想获取文档在一年内的序列号,可以使用 SQL 函数来执行此操作:

ROW_NUMBER() OVER (PARTITION BY ... ORDER BY...)

于 2010-08-04T22:06:40.327 回答