根据Anith Sen 应该避免的五个简单数据库设计错误,使用通用查找表来存储实体的可能状态是一个常见的错误.
编辑+答案: Anith文章中的数字没有很好的标注 - 我认为图1和图2都是糟糕设计的例子,而图2是好的设计.P,在那里担心了一会儿.
我将在下面提出我的问题以供参考.
"你失去了确保准确数据的手段;约束.通过将不同的实体组合到一个表中,你没有声明方法来约束某个类别的值."
限制价值如何失去准确性?"您必须将每种数据类型表示为具有此类通用查找表的字符串."
如果我想表示另一种数据类型,我可以在其查找表中添加一列."你致力于坚强和随后的复杂性."
怎么样?第四,也是最后,您面临着物理实现问题.
我不明白为什么.
我不同意给出的大多数理由,并希望对我的错误进行一些客观的批评?逻辑.
引用维修服务中的工作示例,其中包含许多可能具有自然流动的可能状态,让我们采取一个JobStatus表格:
可以说,这些状态中的一些可以标准化为表格Couriered Items,Completed Jobs并且Quotes(具有待定/接受/拒绝状态),但这感觉就像不必要的模式复杂化.
另一个常见示例是OrderStatus限制订单状态的表:
状态标题和描述在一个地方进行编辑,并且易于作为带有外键的下拉列表用于动态数据应用程序.这对我来说过去很有用.如果业务规则规定了新订单状态的创建,我可以将其添加到OrderStatus表中,而无需重建我的代码.
为什么这是一个不好的做法?
编辑:我在我的问题中加入了Anith的理由,并试图保持客观.
-
APC*_*APC 12
Anith Sen建议反对的是所有查找代码都有一个查找表.这是category他的例子中的专栏的意义.每个类别都有一个单独的表是绝对可行的方法.
这是因为:
在您的示例中,JobStatus和OrderStatus是单独的类别.适用于单独的实体.这就是为什么他们需要不同的查找表.在几个不同的数据表中共享相同的代码表甚至没有问题.当问题出现时,我们有一些单独的数据表(实体),其中某些状态是不合适的:这是将代码拆分成单独的查找表的时间.
编辑
我看到你编辑了你的帖子,引用了所有Anith的观点.我认为最重要的一点是关于约束的第一点.如果要将ORDERS.STATUS列限制为具有OrderStatus类别中的值,则必须使用单独的表来强制执行外键.您的替代方案是:
从数据库的角度来看,所有这些选项都很糟糕.
你已经有了正确的答案,所以这句话是额外的.
OTLT(一个真正的查找表)的一个大问题是,您最终将来自不同域的值放在同一列中,然后使用单独的列来消除歧义.
在您的示例中,您使用了每个状态描述旁边的数字.如果这些数字是数字代码,我认为它们必须是,那么你不希望值4,意思是"等待客户确认"在与值4相同的列中,意思是"已取消".如果您这样做,那么您不能将此列用作您的一个真实查找表的PK.
如果你给你的一个真正的查找表另一列,称之为"CodeType"并使用"CodeType"和"Code"作为复合PK,你通过为每个代码类型设置一个单独的查找表,引入了比你介绍的更多的复杂性.
简短的回答是:不要将来自不同域的值放在同一列中.它总是比它节省更多的麻烦.
顺便说一句,可以创建一个视图,将所有单独的查找表组合成一个看似单个巨型查找表的视图.这在某些非常特殊的情况下非常有用.