How to implement total disjoint specialization in database?

前端 未结 2 763
生来不讨喜
生来不讨喜 2020-12-18 14:47

Say there is a database for students and professors (a very simple one) and the relational database is the following:

GradStudent (_id_, name, gradStuff)
Und         


        
相关标签:
2条回答
  • 2020-12-18 15:16

    I cannot figure out how to make a foreign key from two different tables.

    You mean, a foreign key to/referencing two different tables. But there is no such foreign key in this design.

    We declare an SQL FOREIGN KEY for a table to say that (ie to tell the DBMS that) the values for a list of columns are also values of a list of corresponding columns (maybe the same list) that are unique in a table (maybe the same table). You don't have this here. You have a different constraint on your tables.

    If you want exactly those base tables then you have to use triggers in SQL to enforce your constraints.

    You can also have a design with:

    • base table Student with NOT NULL UNIQUE or PRIMARY KEY id
    • FOREIGN KEYs from GradStudent (id), UndergradStudent (id) and Teaches (stud_id) REFERENCES Student (id)
    • a constraint that the projection of Student on id is the disjoint union of the projections of GradStudent and UndergradStudent on id

    You could express part the latter constraint by a trigger. A triggerless way to express the disjointedness (but not the union) is:

    • a type discriminator/tag column student_type (say) in GradStudent, UndergradStudent & Student with additional FOREIGN (super) KEYs (id,student_type) from GradStudent and UndergradStudent to NOT NULL UNIQUE (id,student_type) in Student
    • GradStudent CHECK( student_type = 'grad' ) and UndergradStudent CHECK ( student_type = 'undergrad' )

    Rows in each of the two student subtype base tables are all the same (redundancy) and rows in Student are determined by their id (redundancy) but that's the cost in this case of having no triggers. Column student_type could be a computed column.

    There's really no pretty SQL way to enforce that every parent id is a child. Having only the LEFT JOIN of the above child tables instead of the parent and child tables enforces that every parent is a child but requires NULL columns and further constraints. One needs triggers to reasonably constrain SQL databases. One uses idioms to get what declarative constraints one can.

    For more on subtyping idioms see this answer and its links. Google 'stackoverflow database sql table' plus child/parent, super/subtables, super/subtypes, inheritance and/or polymorphism. Also multiple/many/two FKs/relationships/associations/references/links (although usually as in this question the constraint wanted is not a FK and the design should use subtypes instead). I googled "stackoverflow two foreign keys" and got this.

    0 讨论(0)
  • 2020-12-18 15:19

    If by "fetch the student id for the Teaches table", you mean you want Teaches.stud_id to be a FK that references "GradStudent or Undergradstudent as is the case", you can't. The target of a FK must be a key of a table that is not a view. You have no such table, ergo you have no such key either.

    Only way I see is to code a trigger that does the check upon inserts/updates to Teaches.

    0 讨论(0)
提交回复
热议问题