数据库设计:支持抽象或外键约束?

时间:2009-04-08 03:09:57

标签: language-agnostic database-design oop entity-relationship

假设我们有这种情况:

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. 

您如何看待上述设计?在这个数据库场景中加入“OOP概念”是否有意义?

最后,您是否更喜欢第一个场景的外键约束或更通用(例如,将艺术家与Track链接的风险,因为没有检查输入器外键值真的是一张专辑)的方法吗?

..顺便说一句,想想看,我想你实际上可以检查艺术家的RelField的输入值是否与专辑相对应,可能有触发器吗?

6 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

在各种实体上不可避免地累积的额外字段几乎没有机会。没有以合理的方式反映现实,无法获得任何好处。

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

这让我想起了(但只是略微)一次尝试用一个表(名为“Entity”)和另一个表(名为“Attributes”)以及它们之间的联结表来实现一个表中的所有内容。

答案 2 :(得分:1)

通过将所有三个组合在一起,您可以减少查询的可读性(除非您将这三个类别分解为视图)并且使搜索和索引更加困难。

另外,在某些时候,您需要将属性添加到一个类别,这些属性不是其他类别的属性。将所有这三个粘在一起使您无需更换系统中的空间即可进行更改。

不要那么聪明你绊倒自己。

答案 3 :(得分:1)

我可以看到以OOP方式进行的唯一优势是,如果将来添加其他元素类型(即,除艺术家,专辑和曲目之外)。在这种情况下,您不需要更改架构。

但是,我倾向于选择非OOP方式,只是在这种情况下更改架构。您对OOP解决方案的一些问题是:

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

基本上,如果你想存储一些仅仅属于一种或两种元素类型的东西会怎么样?

答案 4 :(得分:1)

如果您正在处理此类问题,请查看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);

答案 5 :(得分:0)

我同意le dorfier,您可能会从基本实体(ID,Name)的概念中获得一些重用,但除此之外,Artist,Album和Track的概念将会分歧。

一个更现实的模型可能不得不处理这样一个事实:多位艺术家可能会为专辑中的单曲创作...