数据库设计 - 多个查找/枚举表或一个大表?

时间:2009-05-18 02:20:12

标签: database-design saas

我有很多表对大多数列值使用Lookup / Enum引用。 例如:
人员表 - PersonID | RaceCode | HairColorCode | HairStyleCode | TeethConditionCode
位置表 - LocationID | SizeCode | ExteriorColorCode | ConditionCode
Race,Size,Color,Condition等之类的东西只是代码查找表的外键引用。此代码表包含其他字段,但对我的问题并不重要。该数据库用于SaaS应用程序,这意味着每个客户端都可以拥有自己的颜色,种族,条件等列表。有些代码是静态的,客户端无法更改。

拥有1个代码表或2种类型的代码表(DynamicCodeTable用于客户定义的代码表和StaticCodeTable用于那些更改的代码表)或者我应该为每种代码类型(RaceCodeTable,HairColorTable,Condition等)提供表格更好吗?

我最担心的是所有sql连接。我正在使用的Person表有20多个这些代码属性。加入20个不同的表VS连接到同一个表20次时,性能是否有差异?拥有多个表意味着每个表都会更小,查找“应该”花费更少的时间。但是拥有一张桌子也很快。有什么建议吗?

4 个答案:

答案 0 :(得分:24)

在过去的十五年里,在“One True Lookup Table”(缩写为OTLT)的主题下,已经详细讨论了这个主题。这种方法的优点跃向数据库新手。随着时间的推移出现了缺点。有关OTLT缺点,请参阅以下链接:

search OTLT可以找到更多讨论。

如果为它们创建了许多查找表和许多维护屏幕,则可以创建一个模拟OTLT的视图,方法是创建一个巨大的UNION,其中包含代码描述的表的每个代码,每个描述和名称。对存储。 如果您知道自己在做什么,就可以使用半自动方法生成这样的联合。我认为半自动方法可以让你为数百个查找表构建一个维护屏幕,然后在该屏幕和将在正确的表中插入新代码的表之间放置一些逻辑。

至于让用户引入新代码TYPES,而不仅仅是新代码VALUES,这会打开一大堆蠕虫。参见上面讨论EAV的文章。这非常诱人,因为它允许用户设计自己的底层数据结构。如果你忽视性能,这种方法很有效。无需从用户或主题专家那里学习数据结构,您就可以获得完美的通用数据库。

当它遇到真正的悲痛时,你会尝试使用数据,就像它是一个集成的数据库,而不仅仅是对数据的脱节观点。此时,当您的客户期望生成例行报告时,您将进入一些严肃的数据考古学。祝你好运。

(编辑将“数据挖掘”改为“数据考古学”)

答案 1 :(得分:13)

如果不了解有关应用程序或要求的更多信息,我建议为每种代码类型使用一个表。 IMO数据库设计会更清晰,自我记录,以便为您拥有的每种代码提供外键。

答案 2 :(得分:0)

在重新设计我们相当宽的表时,我错误地认为所有这些查找表都是个好主意。这么多的灵活性等等,但它最终变得难以编码,它无法导航,这只是一个痛苦的屁股。

那我学到了什么?

  • 对于静态值,只需使用枚举 - 它更快更方便。必须根据有多少其他表引用相同变量来做出此决定。
  • 坚持使用较少的查找表,而不是创建尽可能多的查找表。 JOIN慢得多。
  • 帮助自己导航,设计数据库VIEW。它会让你的生活更轻松。
  • 作为奖励,如果您不希望客户触摸某些表(即您的静态表)或触摸枚举列值,您可以使用MySQL(例如)细粒度权限来禁用对某些列的更改在某些表格中。很多人都没有意识到这些权限的灵活性。

答案 3 :(得分:0)

存在潜在的性能差异。

只有2行的表会在缓存中为这两个小行占用大量空间。

如果在一个表中有很多查找值,那么 - 有效地 - 将这些值更密集地打包到缓存中。