数据库设计:赞成抽象还是外键约束?

问题描述:

说我们有这样的场景:数据库设计:赞成抽象还是外键约束?

Artist ==< Album ==< Track 
//ie, One Artist can have many albums, and one album can have many tracks 

在这种情况下,所有3个实体具有基本相同的字段:

  • ID
  • 名称
  • 的一对多关系的外国到相应的孩子(艺术家专辑和专辑跟踪

对于提供的解决方案,一个典型的解决方案是三个表,在一对多关系字段中具有相同的字段(ArtistID,AlbumID等)和外键约束。

但是,我们可以在这种情况下,纳入一种形式的继承,以避免重复相同的领域?我说的那种东西:

Table: EntityType(EntityTypeID, EntityName) 
     This table would hold 3 entities (1. Artist, 2. Album, 3. Track) 

Table: Entities(EntityID, Name, RelField, EntityTypeID) 
     This table will hold the name of the entity (like the name of 
     an artist for example), the one-many field (foreign-key 
     of EntityID) and EntityTypeID holding 1 for Artist, 2 for Album 
     and so on. 

你觉得上面的设计是什么?在这个DB场景中加入“OOP概念”是否有意义?

最后,你更喜欢有第一种场景的外键约束还是更通用的(具有将艺术家链接到Track的风险,例如,因为没有检查来查看输入的外键价值真的是一张专辑)的方法?

..btw,想一想,我想你实际上可以检查一个艺术家的RelField的输入值是否对应一个专辑,触发器可能是什么?

+0

难道不关你的专辑有多位艺术家?你的曲目中是否有多个艺术家?你也没有录制像乐队(管弦乐队)演奏音乐,独奏者,指挥,作曲家,编曲者等等的东西。啊,这只是一个问题,但要小心过度简化。 – 2009-04-08 03:19:14

我最近看到这个抽象概念一致地实现,应用程序和它的数据库变成了一个怪物来维护和排除故障。我会远离这种技术。越简单,越好,就是我的口头禅。

在各个实体中不可避免地积累的附加字段将非常少有机会成为必要条件。没有以相当接近的方式反映现实,从而无法获得。

我不认为你甚至可能会混淆这些实体在你的常规OO设计中。

这让我想起了一次尝试在一个表(名为“Entity”)中实现所有事情的尝试(但名称为“Attributes”)以及它们之间的联结表。

+1

这种抽象的最终目标是EAV模型(实体,属性,值),其中绝对一切都可以塞进一个只有三列的表格。无论主题如何变化,模式都不会改变。这是一场噩梦。 – 2009-06-28 11:12:51

我同意乐dorfier,你可能会从基础实体(ID,名称)的概念中得到一些重用,但超出这一点的艺术家,专辑和曲目的概念将会发生分歧。

和更逼真的模型可能会不得不面对的事实,多位艺术家可能有助于专辑上的单轨...

通过stucking所有三个在一起,你让你的查询少readble(除非然后将这三个类别分解为视图),并且使搜​​索和索引更加困难。

另外,在某些时候,你会希望将属性添加到一个类别,这是不为其他属性。将所有三者结合在一起给你没有改变你的系统块的空间。

不要让你这么聪明,让自己绊倒。

我可以看到在你的OOP方式做的唯一好处是如果在未来的(即不是艺术家,专辑和曲目等)添加其他元素类型。在这种情况下,您不需要架构更改。

不过,我倾向于选择非面向对象的方式,只是改变在这种情况下的模式。您使用OOP解决方案时遇到的一些问题有:

  • 如果要添加艺术家的生日日期,该怎么办?
  • 如果您想存储专辑和曲目的持续时间,该怎么办?
  • 如果想存储轨道类型,该怎么办?

基本上,如果你想存储的东西仅仅是一种或两种元素类型,那该怎么办?

如果您到这样的事情的时候,再采取PostgreSQL看看表继承。

create table Artist (id integer not null primary key, name varchar(50)); 
create table Album (parent integer foreign key (id) references Artist) inherits (Artist); 
create table Track (parent integer foreign key (id) references Album) inherits (Artist);