我们正在针对最初针对C++代码设计的遗留Oracle数据库编写现代C#代码。历史上的惯例是,我们对整数值使用NUMBER(10)
,尽管实际上这些值从来都不是负数。
ExternalId : NUMBER(10)
在许多情况下,我们也没有很好地强制执行NULL/非NULL,并且由于该字段在原始代码中会映射到C++整数类型,因此我们有将NULL
视为0的长期约定。
如果我们在新的C#代码中严格执行DDL,那么我们就会有一个类属性,比如:
public int? ExternalId { get; set;}
这让我觉得很混乱/很臭,可能是对可为null的语言功能的滥用(它只在C#8中引入(,但我们遇到了一个分歧——SQL设计还是业务/系统规则?
我很乐意回答如何决定在我们的情况下哪一个是最好的。修改数据库在短期内不是一个现实的提议。
对此没有一般的答案。这取决于用例。例如,如果0美元的价格是有效价格(意味着物品是免费的(,同时可能有未确定的价格(NULL(,那么您必须能够区分0
和NULL
。在其他情况下,可能不需要这样做。
在一个好的设计中,DB中的可空性应该与前端中的可零性相匹配。
如果您必须处理一个设计糟糕的遗留DB,其中的列可以为NULL,只是因为没有人愿意考虑可为NULL的问题,并且0和NULL被一视同仁,那么前端的不可为NULL类型是可以的。
在理想的情况下,您可以更改DB模式并使这些列不为NULL,但这并不总是可行的,因为这会破坏与其他应用程序的兼容性。