假设我们有这种情况:
Artist ==< Album ==< Track
//ie, One Artist can have many albums, and one album can have many tracks
在这种情况下,所有3个实体都有基本相同的字段:
提供的解决方案的典型解决方案是三个表,在一对多关系字段中具有相同的字段(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的输入值是否与专辑相对应,可能有触发器吗?
答案 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的概念将会分歧。
一个更现实的模型可能不得不处理这样一个事实:多位艺术家可能会为专辑中的单曲创作...