SQL Server - 前缀和零填充 ID 列

标签 sql sql-server database-design sql-server-2014

简单地说,这是我的问题,我一直在尝试在 StackOverflow 中搜索答案,但找不到满意的答案。

我有一个包含列的 InvoiceHeader 表(简化):

InvoiceID   : Int - PK Identity(1,1)
InvoiceDate : date
CustomerID  : Int - FK to Customer table

等等...

我会经常向用户显示有关 Invoice 的信息。 当我向用户显示发票编号时,我需要为 InvoiceID 添加前缀和零填充。

例如:

InvoiceID : 1 
Invoice Number : INV0000001

我的问题是,我应该在 InvoiceHeader 表中创建一个全新 PERSISTED COMPUTED 列来保存格式化的发票号码,如下所示:

InvoiceNumber AS 'INV' + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)

或者我应该选择 InvoiceID 并在运行时从我的应用程序将其处理为 INV0000001 吗?

我的困境:

  • 如果我添加一个新的 PERSISTED COMPUTED 列(即 InvoiceNumber),那么我可以在 InvoiceNumber 处创建非聚集索引,这将在 WHERE 子句中使用 InvoiceNumber 进行查询时有所帮助。但这仍然需要覆盖索引或包含索引来获取其他列的值。另一个优点是我不必每次需要显示它时都将其“格式化”为 INV0000001。
  • 如果我在应用程序的 SELECT QUERY 中将 InvoiceID 格式化为 INV0000001,这将是太多“苦差事”,每次我想显示 InvoiceNumber 时都必须对其进行格式化。但我不需要另一列,它基本上与 InvoiceID 具有相同的值,并带有一些前缀和零填充。
  • 发票号码将被用户用于搜索,例如:给我找到一张号码为“1234”+“%”的发票。如果对 InvoiceID(整数列)执行此操作,它将进行隐式转换,是否会使查询变慢?查询计划还会使用 PK 索引吗?

编辑: 考虑到在很多地方我每次需要时都必须手动格式化发票编号(如果我不使用计算列),我现在几乎确信要使用Esperento57的解决方案:

创建 2 个新列:

InvoiceID      : int identity (PK)
Prefix         : char(3) --> INV, etc
InvoiceNumber  : Prefix + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)

但我不会让 PK 包含前缀,因为 InvoiceID 是身份,因此它本身是唯一的。

我还在考虑 @Matt 关于关注点分离的观点,因为它是有道理的。

最佳答案

我对您的专栏的建议:

  • InvoiceID:整数不为空,自动增量(序列不是必需的,SQL Server 可以完成这项工作)

  • 前缀:PREFIXTABLE 上的 varchar(10) 不为 null FK

  • InvoiceID 和 Prefix 为主键

  • InvoiceNumber:计算并保留的列 = Prefix + RIGHT('0000000'+ InvoiceID,7)

  • 在 InvoiceNumber 上添加索引

根据我的建议,您可以:

  1. 如有必要,请更改前缀
  2. 您对前缀很诚实
  3. 您拥有完整的 key 并保留真正的主 key
  4. 您不必重新计算完整的 key
  5. 在进行数据恢复时,您可以将序列跳转到您的 key 或仅选择其他前缀
  6. 您可以在 PREFIX 表中添加说明以解释您的前缀(以供 future 的开发人员举例)

关于SQL Server - 前缀和零填充 ID 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44868052/

相关文章:

sql - 尝试在特定条件下将行合并为一行

c# - 有什么方法可以将 SqlTypes 与 SqlDataAdapter 一起使用吗?

sql-server - Delphi 4 中的查询优化

jquery - 如何在 ajax 成功中将 id 传递到我的打印页面

SQL 条件 GROUP BY : how to do it?

mysql - 用于提高 MySQL 性能的 Varchar、Char 或 Binary

postgresql - Postgis 数据库结构 : Identical tables for multiple years?

database-design - 使用 CTP4 Code First 的外键作为 EF4 中的 TPH 鉴别器

sql - Oracle:删除所有满足条件的表空间

mysql - 查询难度更大的多对多关系