数据库设计问题

时间:2010-09-09 18:18:46

标签: mysql database database-design

我有一个表单,用户可以在其中提交不同的字段来创建事件。请求的字段数量和类型在每个表单上都有所不同,具体取决于事件的类别。设计此数据库的最佳方法是什么 - 如果事件包含所有可能的字段并且只是将未使用的字段置空? 谢谢!

4 个答案:

答案 0 :(得分:5)

如果您开始考虑Joel的建议,请转到here

here

here

如果你不相信任何一个,那么建立他提到的4个表。只有4,不需要很长时间。然后将一些数据加载到它们中......然后尝试编写您要编写的查询...

更改列含义:

这可以用基数估算来搞定。您的餐盘可能在4 - 20范围内,音乐会座位在1000 - 2000之间。一些基数计算从最小值到最大值并假设和平均分配(当缺少其他统计数据时)......

从4到2000意味着GENERIC_COLUMN = n,你要击中的行数百分比是总数的1/199。但实际上,如果你说EVNT_TYPE = Dinner和GENERIC_COLUMN = n,那真的是在4到20之间,或者总行数的1/16 ......所以卡估计的幅度很大。 (这可以通过直方图来修复,但显示自动化问题的关键只是强调如果它对机器来说是一个问题,它可能不是那么干净。)

所以,如果你这样做(比EAV更好,但......)

我建议为每个对象创建一个视图。

表EVENT(常用字段,Generic_Count) 查看DINNER(常用字段,Generic_Count as Plates)WHERE type = Dinner 查看CONCERT(常用字段,Generic_Count作为席位)WHERE type = Concert

然后选择NO ONE选择对抗EVENT

但是,这是你不首先从概念数据模型开始遇到麻烦的地方。

你有EVENT的ENTITY和DINNER的另一个,完全从EVENT继承,另一个继承完全从EVENT继承的CONCERT。然后你可以在继承对象中设置一个差异化列,让你设置“TYPE”列,然后你甚至可以通过轻击一个开关来决定要构建多少个表。 1张桌子,2张桌子或3张桌子..

至少你可以在powerDesigner中做到这一点。

为什么DDL被认为是那么糟糕?

EAV模型的创建和这样的问题围绕着要避免使用DDL的想法进行组织。为什么ALTER TABLE何时可以插入新的属性行?人们根据错误的效用函数做出糟糕的数据模型设计决策。这些函数类似于“无可空列”,“表越少越好”,“没有ddl只是添加新属性”。插入属性表而不是'。

想想这样的数据建模:雕刻家会说木头或石头已经有了块内的图形,它们只是去掉它的碎片以显示它。

您的问题空间已经有了数据模型,发现它只是您的工作......它将拥有所需数量的表和列。试图强制它符合上述实用功能之一是事情发生了可怕的错误。

在您的情况下,您是否想知道过去两周内添加的所有活动?现在想想可能的模型。每个事件类型一个表意味着在n个表上求和以找到答案,并且每个新事件类型添加一个新表,并且每个“所有事件”查询都将改变。您可以构建这些表的UNION ALL视图,但您必须记住将每个新表添加到视图中。通过这样的视图进行调试是一件痛苦的事。

假设您可能需要大量关于所有事件的指标,一个表更有意义(至少对于事件数据的某些常见部分 - 如事件名称,赞助商ID,场地ID,事件开始时间,事件结束时间,场地可用于设置时间等。)这些字段(我们的规定)对于每个事件都是通用的。

那么现在如何处理其他列呢?两个选项,可空字段或垂直分区表。后者是前者的优化。如果您阅读任何数据库优化书籍或博客,我从中获取的主要内容是过早优化会导致死亡。我看到人们在问题出现问题之前就已经实施了许多问题策略。一位同事对他希望我提供帮助的问题很慢。它加载了优化器提示。我删除了它们并且SQL尖叫了......我不知道为什么他暗示它但他没有有效地做到这一点我很确定他从未见过这个问题因此这只是过早的优化。

当您拥有大量数据并且有一些经常访问的数据和其他不太有用的数据时,您可以执行垂直分区。如果只包装一些公共区域,您可以打包一个包含更多块的表。每个块更多的行=更快的表格扫描...并不会真正影响通过索引查找单个行的速度。你可以看到垂直分区有一个特定的问题,它可以解决(其他人也像行链接),所以如果你确定要成为一个问题,那么一定要以这种方式开始。

答案 1 :(得分:1)

我会仔细考虑这个抽象,但您也可以拥有一个包含事件详细信息的链接表:

Table Event:  id, Name

Table EventDetail:  id, EventID, DetailFieldName, DetailText

一条Event条记录可以有多条EventDetail条记录。

这很灵活,但需要考虑权衡。您的查询会变得更复杂,并且呈现结果会有一个额外的间接层(您必须遍历特定EventDetail记录的所有Event记录以呈现整个事物。

如果需要,您可以全力以赴并将DetailFieldName规范化为EventDetailField表。

但是,您最终只能使用几个表,如果需要,可以完全删除NULL,并且不必为每个特定事件类型设计新表。

选择你的毒药。 ;)规范化有它的位置,但我也发现,如果你标准化太多,它会使某些任务变得非常困难。

答案 2 :(得分:0)

这取决于你的表格有多么不同。我说每个条目项都有不同的字段...有一个字段,其中有多个项目只会使查询更加困难。如果你的表单没有太大的不同,那么每个可能字段的1个表都可以,但是如果你的表中有20多个字段,那么我建议将这些表分开。我还建议使用带有“表单类型”字段的标题表来帮助搜索。

答案 3 :(得分:0)

您应尽可能规范化表,以减少数据库中的空值数。如果记录存储,记录应该是有意义的。一种方法可能是具有将1-> m与事件表相关联的类别表。然后你可以在表单中有一个预期字段表(给每个int id)。然后中间表将存储实际提交的数据。

catID|Category
 |
 --------------------
                    |
eventID | event | catID
 |
 ------------------------------
                     |        |
fldID | fldName | eventID     |
 |                            |
 -----------        -----------
           |        |
dataID | fldID | eventID | data