具有多个关系和继承的实体的灵活数据库结构

时间:2019-03-13 16:41:32

标签: database database-design relational-database

我正在设计一个具有一些特定规则的数据库结构,并且试图定义一个合适的数据模型,基本上是一种适合那些规则的数据模型。

共有3个实体:

  1. 组(字段:subgroupsitems ...)
  2. 子组(字段:groupitems ...)
  3. 项目(字段:enableddescription ...)

这些实体具有关系:

  • 一个SubGroup属于一个Group(一个Group拥有几个SubGroup
  • Item可以属于GroupSubGroup(一次只能属于一个)

还有一些特殊规则:

  • 属于Item的{​​{1}}继承给所有相关的Group
  • SubGroup从其Item继承的SubGroup可以被覆盖(我称它为继承,因为那样子会被父辈继承并可以按原样覆盖或使用)
    • 我主要的替代用例是使用Group字段,因为在某些情况下我们可能想禁用通过继承获得的项
  • 请勿在数据库中复制内容(尤其是项)(在应用程序级别查询数据库模型时,应进行继承)
  

此示例保持简单,但实际情况有点复杂,可以有更多的“ SubGroup”级别,例如“ SubSubGroup”,因此结构也应适当地处理这些


尝试1

起初,我想到了一种传统的关系:

enter image description here

如果不是针对那些“特殊规则”,这将很好地工作。因为这种结构无法覆盖继承的enabled

因此,我也做了第二次尝试。


尝试2

我通过使用一种“代理”表进行了另一种设计尝试,该表基本上是一个名为Item的nn关系表(该名称太可怕了,但我没有发现更好的方法)除了现有实体(ItemOverrideGroupSubGroup

实体Item包含以下字段:

  • ItemId
  • EntityType(ItemOverrideGroup
  • EntityId(与所选SubGroup相关的ID)

实体EntityType扩展了ItemOverride实体,使其包含相同的字段,从而可以覆盖任何字段。

Item表中的内容示例:

ItemsOverride

此设计似乎提供了适当的结构,我添加了+--------+------------+----------+-----------------+---------------------+ | ItemId | EntityType | EntityId | Enabled | OverriddenHeight | +--------+------------+----------+-----------------+---------------------+ | 1 | group | 1 | true | null | | 2 | group | 2 | true | 20 | | 3 | subgroup | 1 | false | | +--------+------------+----------+-----------------+---------------------+ OverriddenWidth来说明覆盖的字段。关键是只存储被覆盖的内容,而将其他值保留为空,以便它依赖于实际的OverriddenHeight实体来获取这些值。

但是,我觉得它变得比需要的要复杂得多,我想知道是否有更好的方法来解决这个问题。

使用此结构可以看到一些潜在的痛点:

  • 如果实体Item继承了ItemOverride,则必须在Item表中设置不允许“ null”的字段,这将浪费空间,重复的内容和其他问题,因为这将使得很难从继承的内容中看到真正被覆盖的内容
  • 如果ItemOverrideItemOverride之间没有继承,则Item模型将“无用”地复制其大部分字段,并且必须完成添加/更新/删除字段在两个表而不是一个

因此,我不知道此设计是否“足够好”,或者可以改进/简化。如果您知道这样的继承/重写需求,我很想涉足类似的项目。


摘要:

我的第二次尝试似乎符合我的需求,这是我不得不立即开始使用的,因为我不知道如何改善它。

此设计没有数据冗余,但是当ItemOverride继承SubGroup的{​​{1}}时,如何处理数据覆盖仍然不清楚。如果将覆盖范围限制为Group字段,那么这很容易,但是如果有很多字段,则维护起来会有些复杂。使用模型/表继承也可能使事情复杂化,因为我们不想存储非覆盖值,因此希望允许Item表中的所有字段使用required(这可能是不可能的)如果我们在null实体中强制执行不可为空的规则,因为它们也会同样应用于ItemOverride

问题:是否有一种既可以使用继承又可以覆盖而不复制列配置或数据本身的方法?


为了记录,我使用的是Django。它强大的内部ORM优雅地处理Item和DynamicRelationship,它们允许使用模型的字段引用动态实体。 (我将其称为ItemOverride),这就是第二次尝试设计采用这种方式设计的原因之一(更容易依赖于我的框架提供的功能)。但是我对完全不同的可能性/选择持开放态度。

0 个答案:

没有答案