leo*_*ora 14 database-design database-schema
我有一个名为Calendar with fields 的数据库表
我有另一个名为CalendarType的表,其中包含字段
问题是我需要为日历类型为2的每个日历存储一个附加字段.(但此字段与任何其他日历类型无关).
我应该只在Calendar表中创建一个新字段,并忽略具有不同calendarTypeid的所有其他日历的该字段,或者是否有更好的方法来组织此模式以支持此需求.
Mos*_*cho 15
好的,这是你现在拥有的ER模型(省略基数):

现在,让我们关注Calendar和SubCalendar.显然,你有一个层次结构.但层次结构如何变成表格?有三种常见的方法可以做到这一点:
1)杀死父级并保留子级:在这种情况下,删除父实体并将该实体的所有字段发送给每个子级.在您的示例中,您只有一个子项,因此所有父项的属性将仅包含它.
优点:没有空值,因为每个表都具有它所需的全部功能.也不需要加入.如果您将运行仅搜索一种类型子项的查询,则此架构将非常有用,因为您不需要按类型过滤,因为每个表只存储一种类型
缺点:此架构不适用于具有重叠子项的情况.换句话说,如果父行在向每个子节点发送字段时可以有多个子节点,则父节点数据将在每个子节点中重复.不好,所以如果是这样的话,不要使用这种策略.另外,如果你有很多孩子,每个孩子的记录都很少,你就会有很多桌子,每个记录都很少,所以管理起来可能会有点困难.

2)杀死孩子并保留父母:在这种情况下,你删除所有孩子并将他们所有的属性发送给父母.由于父母现在是自己和所有孩子的混合体,因此需要一种方法来确定哪一行属于哪种类型的孩子.这是通过向父实体添加一个新属性来实现的,该属性将确定每一行的类型(无论数据类型如何).
优点:所有孩子只有一张桌子,因此易于管理.不需要加入.如果针对此表运行的大多数查询需要来自多个类型的子项的结果,则可能很有用.
缺点:同样,如果父级可以有一个与多个子级相关的行,则数据将被复制,因为每个子级将有一行,因此此解决方案存在限制.此外,必须添加新列作为元数据.表中的记录量将更大.必须将空值分配给子项具有的数据以及父项或其他子项具有的数据.

3)保持所有:最少血腥的解决方案不是杀死任何东西:)在这种情况下,层次结构被父级和每个子级之间的关系所取代.这样,子进程必须通过外键加入父表才能到达父进程的数据.
优点:没有数据重复,也没有空值.每个实体只有最少量的数据,其余的可以通过加入父表来获得.在这种情况下,父行可以链接到多个子项而不复制数据.如果将运行许多只能通过一个表(通常是父表)满足的查询,这是一个不错的选择.还有一件事是,很容易扩展到更多的日历,例如,如果要添加需要新字段的新日历,则必须添加新表,而不修改当前日历
缺点:需要最多的表(实际上比第一个表多一个).每个子项都需要一个连接,这会降低数据集所带来的性能.此外,还需要外键来连接两个表.如果大多数查询都需要来自父级和子级的数据,则此架构在性能方面将是最差的

现在,您询问哪个是best数据库架构.我认为现在很清楚它取决于要求,将要运行的查询类型,数据结构的方式等.
但是,我可以稍微分析一下.你说你有一个Calendar表,有时候其中一个需要更多的数据.所以我们可以说我们有两种类型的日历,父母和孩子.因此,我们可能会认为解决方案2很有可能,因为您将有2行代表每种类型,但我们会错.这是因为在这种情况下每个孩子都包含其父级.现在,如果我们可以假设if SubAttribute对于子节点将始终为非null而对于父节点为null,我们甚至可以删除CalendarType,这实际上将导致解决方案1.
最后,作为一个经验法则(主要是因为大多数查询在现实生活中有很多连接),如果你想专注于性能,你应该选择解决方案1,否则,如果你想专注于规范化设计你应该寻求解决方案3.
我希望这已经消除了一些疑虑,并可能产生其他人:)
小智 5
我可能会使用日历。我称它使Db表超载。当数据存储昂贵时,这就是犯罪。现在称为轻松解决问题并继续前进。除非您真的需要,否则不要过度设计。
但是,您没有明确说明类型ID为2的Calendar的每个实例的额外字段值是否有所不同。有时我的Type表具有子类型字段等,但是我假设情况是Type 2的Calendar实例在必填字段中将具有不同的值。
也许我看这个太简单了,但如果你坚持“重用前使用”的模型,那么正确的做法就是将可以为空的列添加到日历表中,并将检查约束添加回日历类型如果日历类型 = 2,则确保它不为 null。
它很简单,最重要的是它很容易测试。
我可能会对这个答案有所懈怠(可能不是最有效的),但这完全取决于您的解决方案的规模。现实情况是,这些限制在接下来的几个月内可能会发生很大的变化,当您还不知道那是什么时,您不想通过选择“正确”的方式将自己陷入困境。当您使用第 10 个日历类型时,完全有可能会出现一种模式,它确实会告诉您最好(或最正常)的方法来做到这一点。现在,只需保持简单,使其易于测试并易于以后更改。