我有一个ERP应用程序,其中包含大约50个包含非事务数据的小型查找表。例如ItemTypes、SalesOrderStatues等。有很多不同的类型、类别和状态,每个新模块都会添加新的查找表。我有一个服务来提供这些表中的List对象。这些表通常只包含两列(Id和Description)。它们只有几排,最大为8-10排
我正在考虑将它们放在一个表中,其中包含ID、Description和LookupTypeID。有了这一张桌子,我就能去掉50张桌子。这是个好主意吗?坏主意?非常糟糕的主意?
是否有管理小型查找表的标准/最佳实践?
在一些专业人士中,单个通用查找表是您应该避免的设计错误。至少,它会降低性能。原因是公共表必须有一个复合主键,通过复合键进行查找的时间要比通过简单键进行查找长。
根据Anith Sen的说法,这是你应该避免的五个设计错误中的第一个。请参阅本文:五个简单的设计错误
如果您关心数据的完整性,合并查找表是个坏主意(而且您应该!):
- 它将允许"客户端"表引用它们不应该引用的数据。例如,DBMS不会保护您在只允许
ItemTypes
的情况下引用SalesOrderStatuses
——它们现在在同一个表中,您无法(轻松)分离相应的FK - 它将强制所有查找数据共享相同的列和类型
除非您由于过多的JOIN而出现性能问题,否则我建议您使用当前的设计。
如果您这样做了,那么您可以考虑在查找表中使用自然键而不是代理键。通过这种方式,自然键通过外键"传播"到"客户端"表,从而减少了对JOINing的需求,代价是增加了存储空间。例如,没有ItemTypes {Id PK, Description AK}
,只有ItemTypes {Description PK}
,并且您不再需要为了获得Description
而加入ItemTypes
——它会自动向下传播到FK。
您可以将它们存储在像Lucene这样的文本搜索(即nosql)数据库中。他们的速度快得离谱。
我已经实施了这项措施,效果非常好。不过请注意,有一些初始设置需要克服,但并不多。Lucene对id的查询很容易编写。
"一个大查找表"方法存在允许愚蠢值的问题——例如,当库存中只有带有"color:yellow"的汽车时,卡车的"color:yellow"。一个大查找表:只说不。
顺便说一句,我会使用查找表的自然键,除非出现"2012款CX300R是红色,但2010-2011款CX300R是蓝色(型号ID也表示颜色)"这样的情况。
传统上,如果你问DBA,他们会说你应该有单独的表。如果你问程序员,他们会说使用单一表格更容易。(只需制作一个网页并传递不同的LookupTypeID,而不是许多类似的页面,就可以非常容易地制作编辑状态网页)
然而,现在有了ORM,SQL和代码访问不同的状态表并不是什么额外的工作。
这两种方法我都用过,效果都很好。我必须承认,使用单个状态表是最简单的。我已经为小型应用程序和企业应用程序做过这样的操作,没有注意到对性能的影响。
最后,我通常喜欢在这些通用状态表上添加的另一个字段是OrderBy字段,因此如果需要,您可以根据描述以外的内容对UI中的状态进行排序。
听起来是个好主意。您可以将ID和LookupTypeID作为多属性主键。你只需要知道所有不同的LookupTypeID代表什么,你就应该像金子一样优秀。
编辑:至于标准/最佳实践,我真的没有答案。我只学了一个学期的SQL/数据库设计,所以我还没有完全接触到这件事。