Skip to content
Advertisement

Include one table’s values in multiple other tables and allow FK references

I’m still a relative novice when it comes to designing SQL databases, so apologies if this is something obvious that I’m missing.

I have a few tables of controlled vocabularies for certain values that I’m representing as FKs referencing the controlled vocab tables (there are few distinct vocabularies I’m trying to represent). My schema specification allows each of these vocabularies to also allow a controlled set of values for “unknown” information (coming from DataCite). Here is an example using a table dates that must specify a date_type, which should be either a value from date_types or unknown_values. I have a few more tables with this model as well, each with their own specific controlled vocabularies, but should also allow values from unknown_values. So the values in unknown_values should be shared among many tables of controlled vocabularies with similar structure to date_types.

My first thought was a view that creates a union of date_types and unknown_values, but you cannot make FK references onto a view, so that’s not suitable.

The “easiest” solution would be to duplicate the values from unknown_values in each controlled vocabulary table (date_types etc.), but this feels incorrect to have duplicated values.

I also thought about a single table for all the controlled vocabularies with a third field (something like vocabulary_category with values like 'date'), so all my tables could reference that one table, but then I would likely need a function and a CHECK constraint to ensure that the value has the right “category”. This feels inelegant and messy.

I’m stumped about the best way to proceed, or what to search for to find help. I can’t imagine this is too rare of a requirement, but I can’t seem to find any solutions online. My target DB is SQLite, but I’d be interested in solutions that would be possible in PostgreSQL as well.

Advertisement

Answer

What you are requesting is the ability for a FK to have optional referenced table. Also as discovered Postgres nor SQLite(?) provides this option (afaik neither does any other RDBMS). Postgres at lease offers a work around, I do not know it its doable in SQLite. You need to:

  • drop the not null constraint on the currently defined FK
  • add a FK column referencing the unknown_values table
  • add check constraint that requires exactly 1 on the columns date_type and the new FK column to be null. See the num_nulls function.

Changes you need: ( see demo )

Note: Postgres does not support the autoincrement key word. The same is accomplished using a generated column generated always as identity (for older varsions use serial).

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement