【问题标题】:What is a good design for a derived database structure?派生数据库结构的好的设计是什么?
【发布时间】:2015-01-18 05:30:39
【问题描述】:

用于填写表格的输入是一个大文件,其中包含唯一的animalId、它们的名称、它们的动物类型和一些其他特定于动物类型的值。

数据库如下所示:

table animal:
- animalId(pk)
- name
- type(fk to animalType table)   

table dogs:         
- dogId(pk)         
- animalId(fk to animal)    
- hasCoat           
- etc...            

table fish:
- fishId(pk)
- animalId(fk to animal)
- animalId(fk to animal)
- dorsalFinCount
- etc...

我是这样设计的,因为我的其他来源给了我一个唯一的键(animalId,它标识了世界各地的单一动物......就像一个 uri),我不想有一个空值的大型单一数据库(例如对于 hasCoat 和 hasDorsalFin)也不必连续​​在两种类型的特定数据库中搜索。 此外,我可以轻松扩展这个结构(表鸟,具有属性 hasWing、wingColor 等...)

我的 (Java) 程序设计如下所示:

abstract class Animal
- animalId
- name
- type

class Dog extends DatabaseObject 
class Fish extends DatabaseObject 

abstract class DatabaseObject 
    private UUID id;
    public DatabaseObject(){this.uuid = UUID.randomUUID();}
    public UUID getId();

问题是,Dog 和 Fish 类是 Animals,但需要为每个数据库条目有一个 UUID,因为唯一的 animalId 在 animal 表中用作 PK。 此外,Dog 和 Fish 也应该扩展 Animal,因为它们需要那些数据字段……但这在 Java 中是不可能的,因为它们已经扩展了抽象的 DatabaseObject 类。

一个解决方案可能是 Dog 和 Fish 将 Animal 字段作为类成员,但这似乎是一种不好的方法。

您将如何解决这个问题以及您的设计(数据库和程序结构)有哪些优点?

编辑: 由于我的假设(...不能将 PK 用作另一个表中的 PK)是错误的,我可以将 dogId 和 fishId 更改为 animalId。此外,这种数据库设计被称为subtyping

【问题讨论】:

    标签: java design-patterns database-design derived-class


    【解决方案1】:

    不要重新发明轮子,使用 ORM。如果您可以使用 Hibernate,那么已经有一个 Inheritance Mapping 功能。

    【讨论】:

      【解决方案2】:

      您的设计类似于称为类表继承的设计模式。您可以在这里访问同名标签,也可以通过网络搜索看到 Martin Fowler 对同一主题的处理。

      我建议您做一个小改动。它可能适用于您的情况,也可能不适用。它被称为“共享主键”。你摆脱了 DogId 和 FishId。相反,您将 AminalID 设置为 dog 和 fish 表以及 animal 表的 PK。请注意,AnimalID 将是 PK 和 FK。当然,你必须让它成为Animal PK的真实副本。

      这有几个优点,其中包括简单和速度。但最大的优点是它强制每个子类和超类之间的 IS-A 关系的一对一性质。

      【讨论】:

        猜你喜欢
        • 2012-02-03
        • 1970-01-01
        • 2011-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-17
        • 1970-01-01
        相关资源
        最近更新 更多