如何设计支持产品与其他收入行类型的SaleInvoiceDetails表
现有数据库表结构
SaleInvoices表
| InvoiceId | InvoiceDate | CustomerId |
|---|
Products表
| ProductId | ProductCode | ProductName |
|---|
OtherIncomes表
| OtherIncomeId | IncomeCode | IncomeName |
|---|
SaleInvoiceDetails表设计方案
针对区分产品与其他收入行类型的需求,推荐两种实用的设计方案:
方案一:类型标识+分离外键(强约束型)
这种方案逻辑清晰,能通过数据库约束保证数据合法性,适合对数据一致性要求高的场景。
表结构
| SaleInvoiceDetailId | SaleInvoiceId | LineType | ProductId | OtherIncomeId | Quantity | UnitPrice | Amount |
|---|---|---|---|---|---|---|---|
| 主键(自增) | 外键关联SaleInvoices.InvoiceId | 枚举值:PRODUCT/OTHER_INCOME | 外键关联Products.ProductId(可为空) | 外键关联OtherIncomes.OtherIncomeId(可为空) | 产品行必填,其他收入可选填 | 必填 | 必填 |
核心规则
LineType明确标记当前明细行的类型,避免歧义- 当
LineType为PRODUCT时,ProductId必须非空、OtherIncomeId必须为空;反之LineType为OTHER_INCOME时,OtherIncomeId非空、ProductId为空,可通过数据库检查约束或业务代码强制校验 Quantity仅产品行需要填写销售数量,其他收入行可根据业务需求决定是否保留
方案二:类型标识+通用关联ID(简洁拓展型)
这种方案字段更精简,适合业务层有完善校验逻辑,或未来可能扩展更多行类型的场景。
表结构
| SaleInvoiceDetailId | SaleInvoiceId | LineType | RelatedId | Quantity | UnitPrice | Amount |
|---|---|---|---|---|---|---|
| 主键(自增) | 外键关联SaleInvoices.InvoiceId | 枚举值:PRODUCT/OTHER_INCOME | 对应ProductId或OtherIncomeId | 产品行必填 | 必填 | 必填 |
核心规则
LineType标记行类型,RelatedId存储对应类型的主键ID- 业务层需根据
LineType判断关联的表(Products或OtherIncomes),并校验RelatedId在对应表中存在
内容的提问来源于stack exchange,提问作者aeGNoR
相关产品推荐
相关产品推荐

