1 to 0..1 relationship - which way should FK point?
Say I have a customer table with 1:0..1 relationship with another table, I would normally have a Nullable FK in the customer table pointing to the other table.
However, say the number of additional optional pieces of data related to a customer grows, and just for arguments sake, the number of tables is now 10. Would it be preferable to use the same architecture so that there are 10 additional columns in the customer table, all possibly null if no extra data has been stored or is it better to have the FK point to the customer table from the child? This model seems neater as I don't have tons of nullable columns, and I can extend the system gradually if need be by simply adding new tables and a new FK column po开发者_如何学Pythoninting to the customer in the new table. Only disadvantage is that it appears (looking at the db) that you can add more rows breaking the 1:0-1 relationship rule. However, my application would never insert an extra row anyway.
The 1st method requires me to tack a new column on the end of the customer table for every new table added to the system.
Which method is best in this scenario?
The answer is mechanically derived from the idea of functional dependence.
For a value to exist in one relation, it implies that a value must exist in the other. When this is true, there will be a foreign key constraint from the dependent table (the former) to the independent table (the latter)
Another way of looking at this is that a one to one relationship is actually just a special case of a one to many relationship; only instead of many, you are only allowed one.
in SQL:
CREATE TABLE independent (
id INTEGER PRIMARY KEY
);
CREATE TABLE dependent (
independent_id INTEGER UNIQUE NOT NULL FOREIGN KEY REFERENCES independent(id)
);
Like a one to many, the 'many' has a foreign key to the 'one', but to turn the 'many' into a 'one', just make it unique
. It's typically convenient to express all of this by making the foreign key column on the dependent relation the primary key for that relation:
CREATE TABLE dependent (
independent_id INTEGER PRIMARY KEY FOREIGN KEY REFERENCES independent(id)
);
Edit: I noticed your title asks a different question than your body seems to ask. The above answers the title.
From the point of view of database normalization, it's probably preferred to use multiple tables, as above, in favor of nullable attributes. Nulls are sort of an out of band way of saying that the value of a particular attribute is in some way 'special', but doesn't really enforce any particular interpretation of what that might mean. A null manager_id
probably means something totally different from a null birthdate
, even though they have the same mark.
Adding tables isn't considered in any way a bad thing, from a strictly abstract or academic point; neither is adding attributes. The choice should always be based on what kind of data you actually need to model.
That said, there are some very real practical reasons to use one or the other. The most obvious performance reason comes from the space cost of using one or the other. When an optional value is usually used, the extra space used by the foreign key and corresponding index doesn't pay for itself to well. Similarly, if an optional value is rarely used; it's more compact to put those values in another relation. Having a nullable attribute would consume space in the table that is hardly ever used.
Figuring out which basically requires actual data, and performance testing these (and maybe other) configurations to see which works best.
Partial answer:
Keep in mind that breaking a table in two with a 1-1 or 1-0..1 relationship, will always require an additional join between those tables.
If you frequently need to return data from both tables together, and those tables are heavily loaded, having "tons of NULL values" in a larger single table would perform better.
精彩评论