简体   繁体   中英

What is a good design for a derived database structure?

The input for filling the tables is a big file, which has unique animalIds, their names, their animal types and some other animal type specific values.

The database looks like this:

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...

I designed it this way, because my other source gives me an unique key (animalId, which identifies the single animal all over the world...like an uri) and i dont want to have one big single database with empty values (eg for hasCoat and hasDorsalFin) nor have to search in two type specific databases successively. Furthermore, i can easily extend this structure (table birds, with attribute hasWing, wingColor, etc...)

My (Java) program design looks like this:

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();

The Problem is, that Dog and Fish classes are Animals, but need to have a UUID for each database entry, because the unique animalId is used as PK in the animal table. Furthermore Dog and Fish should also extend Animal, because they need those data fields...but thats not possible in Java, because they allready extend the abstract DatabaseObject class.

A solution could be, that Dog and Fish get an Animal field as class member, but that seems to be a bad approach.

How would you solve this Problem and what are the pros for your design (database and program structure)?

edit: Since my assumption (...that a PK cant be used as a PK in another Table) is wrong, i could change dogId and fishId into animalId. Furthermore, such a database design is known as subtyping

Dont reinvent the wheel, use an ORM. If its ok for you to use Hibernate, there already is an Inheritance Mapping feature.

Your design resembles a design pattern known as Class Table Inheritance. You can visit the tag with the same name right here, or you can see Martin Fowler's treatment of the same topic by searching on the web.

There is one small change I would suggest for you. It may or may not work in your case. It's called "Shared Primary Key". You get rid of DogId and FishId. Instead, you make AminalID the PK for the dog and fish tables as well as the animal table. Note that AnimalID will be BOTH a PK and an FK. And you, of course, have to make it a true copy of the PK from Animal.

This has several advantages, among them simplicity and speed. But the big advantage is that it enforces the one-to-one nature of the IS-A relationship between each subclass and the superclass.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM