如何建模与不同类型对象的关系


How to model relation to different type of objects

我正在开发一个用于创建和存储打印布局的软件。

  • 布局由一系列页面组成
  • 每个页面都有一列或多列
  • 在每个中将有一个或多个元素
  • 列中的元素是有序的:有固定的元素序列
  • 元素可以是"文本"或"图像"类型(为了简单起见,实际上还有更多类型)
  • 不同的元素具有不同的特性。图片有一个资源url,文本有一个字体。请参阅过帐末尾的示例代码

我的问题是关于建模柱和元素之间的关系。

想法#1:所有元素都有一张表

这将是非常直接的。将所有属性作为列添加到表中,并使用N:N关系对列和元素之间的关系进行建模。

关系可能看起来像这个

column_id element_id 订单kbd>0000000 10000000010009
0000000 100000000210012

这对我来说似乎不是很有吸引力,因为存储元素的表会被空条目污染,例如,图像元素的所有font列都是空的。如果我考虑所有不同的erlement类型(大约10种),情况会变得更糟。

优点:SQL查询相对简单:

select * from
  relation_table R inner join elements E
  on R.element_id = E.id
where R.column_id = FIXED_COLUMN_ID

想法#2:每种类型的元素都有一个表

建模元素非常简单,只需为类元素的所有属性创建一列,并添加特定元素类型(如图像)的属性。

但是,如何建模关系列:元素?

我的第一种方法是尝试在关系中添加一列,该列指定将直接映射到相关表的元素类型:

column_idelement_id>顺序element_type
0000000 10000000010012text
0000000 100000000 200003图像
0000000 20000000060005图像

这当然有效,但检索特定列的元素的所有sql查询都会变得相当复杂。

问题

有没有一种方法将Idea#1的sql查询的简单性与Idea#2的更准确的数据库建模相结合?

你是如何处理这个问题的?

附言:在其他情况下,我会切换到基于nosql的数据库,但这是不可能的:-(

<?php
// Sample code of element structure
class element {
    protected $id;
    protected $order;
    // more properties, getters and setters...
}
class image extends element {
    protected $image;
    // more properties, getters and setters...
}
class text extends element {
    protected $font;
    // more properties, getters and setters...
}
?>

我认为您最好从一个元素表开始,然后添加连接表,以获得各种元素类型所需的额外信息。

在数据库设计中,将数据建模为真实世界的实体通常是错误的,但退一步,根据数据的内部依赖性进行建模要好得多。这些通常是一致的(而且经常这样做,足以让现实世界的实体看起来很有吸引力),但当你遇到它们不一致的情况时,你会感到悲伤。

在这里,您有关于查询和排序的问题,这些问题在单个表中解决起来很琐碎,但在许多表中会让您头疼。

让我重点谈谈混乱的部分:"不同的元素有不同的属性。例如,图像有一个资源url,文本有一个字体。"正如你所说,这需要很多可以为null的列或很多不同的表。无论哪种情况,都是一团糟。

解决方案。。。将这些"不同的元素"放在一个JSON集合中。把它放在一列中,让应用程序对它进行解码并利用这些东西。

使用该解决方案,结构仍在数据库中,但细节留给应用程序。这似乎是一个公平的权衡。

参见EAV的其他讨论。