为了快点,这是我的问题,我一直在尝试搜索StackOverflow的答案,但我找不到满意的答案。
我有一个包含列(简化)的InvoiceHeader表:
InvoiceID : Int - PK Identity(1,1)
InvoiceDate : date
CustomerID : Int - FK to Customer table
等等...
我会经常向用户显示有关发票的信息。 当我向用户显示发票号时,我需要添加前缀和零填充 InvoiceID。
例如:
InvoiceID : 1
Invoice Number : INV0000001
我的问题是,我应该在InvoiceHeader
表格中设置全新 PERSISTED COMPUTED列,以保存格式化的发票号码,如下所示:
InvoiceNumber AS 'INV' + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)
或者我应该选择InvoiceID
并在运行时从我的应用程序处理INV0000001
?
我的困境:
编辑: 考虑到我每次需要时都需要手动格式化发票编号的许多地方(如果我不使用计算列),我现在几乎肯定会选择 Esperento57' s解决方案:
制作2个新专栏:
InvoiceID : int identity (PK)
Prefix : char(3) --> INV, etc
InvoiceNumber : Prefix + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)
但我不会让PK包含前缀,因为InvoiceID是identity
所以它本身就是唯一的。
我还在考虑@Matt关于分离关注点的观点,因为它有意义。
答案 0 :(得分:1)
您应该将其作为数值保存在数据库中并对其进行格式化,这将阻止您不必要地存储没有价值的数据并提高查询性能。您可以在应用程序中以较低级别应用格式,如果这会减少您需要格式化的位置数量,但根据应用程序的复杂程度,您不太可能需要多次编写此格式化逻辑。
其他答案中有一些有效点,例如:关于缺失数字的观点可能对你很重要,也可能不重要 - 只有你知道这是否相关。
将来改变前缀的问题我要警惕,除非你现在知道这是一个具体的要求。无论是将其存储在数据库中,还是在视图中或在UI /业务层中生成,都可以通过多种方式来改进前缀的更改。这是我向KISS和YAGNI建议的其中一项内容!
NB。 Martin Fowler在上面的文章中提出了一个非常好的观点,即关于构建推定功能和构建可扩展软件之间的区别。这是在考虑围绕这些类型问题进行设计时始终使用的重要措施 - 尽可能确保您拥有扩展点,但只能实现您所需要的功能。
答案 1 :(得分:1)
我的专栏建议:
InvoiceID:整数非空,带有自动增量(不需要序列,SQL Server可以完成工作)
前缀:varchar(10)在PREFIXTABLE上不为FK
InvoiceID和Prefix是主键
InvoiceNumber:计算并保留列=前缀+右('0000000'+ InvoiceID,7)
在InvoiceNumber
根据我的提议,你可以:
答案 2 :(得分:0)
我认为您应该从用户看到的字符串中分离内部ID
,它是主键并用于标识记录。
最终用户永远不应该看到IDENTITY
生成的ID,因为很容易出现差距。
因此,我有两个常规列:int InvoiceID
和char(10) InvoiceNumber
。是的,会有一个单独的方法来生成下一个发票编号。在SQL Server 2014中,我使用带有NO CACHE
选项的SEQUENCE
对象。
当您将内部ID与用户可见的发票编号分开时,您可以在以后轻松更改这些编号的格式。例如,在两年内,财务部门可能会决定引入另一个前缀ABC000001
。显然,所有现有的历史发票都应保留其编号。使用单独的发票编号列,没有问题。使用计算列,您将遇到问题。
答案 3 :(得分:0)
如果这是计算invoicenumber的公式,
InvoiceNumber : Prefix + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)
这里的invoicenumber之间的差距并不重要。
然后我只保留InVoiceID。显示我将以低级别或proc本身的方式格式化invoicenumber。 当用户搜索发票号时,我删除前缀并将其转换为int变量。
然后我会搜索invoiceID列。
但是如果前缀可能会改变,那么在invoicenumber之间就不应该有GAP,
i)在同一个表中保留前缀是个坏主意。
ii)另外,对于invoicenumber的计算也会改变,因为你必须保持连续性。
但是我不会让PK包括Prefix因为InvoiceID是身份所以 它本身就是独一无二的。
它取决于。根据我的说法,前缀也是不可能的。但InvoiceID可以是PK + CI或仅PK或仅限身份或仅CI。
你要检查每个选项。