【发布时间】:2017-07-02 06:27:03
【问题描述】:
为了快点,这是我的问题,我一直在尝试在 StackOverflow 上搜索答案,但找不到满意的答案。
我有一个包含列的 InvoiceHeader 表(简化):
InvoiceID : Int - PK Identity(1,1)
InvoiceDate : date
CustomerID : Int - FK to Customer table
等等……
我会经常向用户显示有关发票的信息。 当我向用户显示发票编号时,我需要为 InvoiceID添加前缀和零填充。
例如:
InvoiceID : 1
Invoice Number : INV0000001
我的问题是,我是否应该在 InvoiceHeader 表中创建一个 BRAND NEW 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 的解决方案: p>
新建 2 列:
InvoiceID : int identity (PK)
Prefix : char(3) --> INV, etc
InvoiceNumber : Prefix + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)
但我不会让 PK 包含 Prefix,因为 InvoiceID 是 identity,所以它本身就是唯一的。
我还在考虑@Matt 关于关注点分离的观点,因为它很有意义。
【问题讨论】:
-
另一种选择:创建一个全新的列并使用插入触发器填充该列。
-
我认为如果我最终添加了一个新列,那么在这种情况下,持久化计算列会更好,因为计算列将保证值,而且它也被设置并忘记了。虽然触发器是另一个 sql 语句,所以它会比计算慢。 Cmiiw*.
标签: sql sql-server database-design sql-server-2014