there is no way to tell just by looking at the query referencing the user_account_hubspot_object table that it is a one-to-one relationship
There is often no way to tell just by looking at a query what relationships hold between tables. This is information properly held by the schema, and writing a query with the correct semantics generally requires inspecting its schema, or even (gasp) its documentation. In cases where adding columns to the primary relation is undesirable for whatever reason, a unique foreign key from the side table to the primary entity’s table is sufficient and I think your alternative solutions complicate the issue unnecessarily.
And really, no constraints or naming schemes you add can prevent someone from doing nonsense joins.
If you follow normalization principles, not only you will very rarely make the wrong choice, but you also signal the intenet of your design semantically. Extending a table by placing an ID in it and adding an extra table does not mean semantically what the author is trying to do. The reasons being integraty and ocurrence of nulls. Which the author kind of hints he wants to avoid. Ultimately you will hur performance by not folowing well known and established principles.
It depends on a lot of things ofc, but I think you gotta ask how many users have hubspot ids. Like if only 5% have them, option A looks really bad. B-2 (& -3?) doesn’t bloat the original table at all, which seems rather nice. I’d say B-2 & B-4 are my favorites.
Another reason to use separate tables is if the fields are modified by different transactions/clients: even if a transaction only changes one field in a row, the whole row will be locked, and the whole row will be written out.
There is often no way to tell just by looking at a query what relationships hold between tables. This is information properly held by the schema, and writing a query with the correct semantics generally requires inspecting its schema, or even (gasp) its documentation. In cases where adding columns to the primary relation is undesirable for whatever reason, a unique foreign key from the side table to the primary entity’s table is sufficient and I think your alternative solutions complicate the issue unnecessarily.
And really, no constraints or naming schemes you add can prevent someone from doing nonsense joins.
Ouch… This looks much more complicated than it has to be.
The only way I know to strictly model a one-to-one relationship between tables in PostgreSQL is:
Of course now, you cannot insert in one table without insertin in the other, but thanks to deferred constraints you can do this in a transaction:
If you try to insert in one without inserting into the other you get:
Everything else is kinda of a hack which depends on client logic.
A bit weird that non standard practices are presented side by side with the canonical ones. With the latest not even being the first presented option.
Relational database normalization is a well researched field with established practices well motivated by science and enginnering. https://en.wikipedia.org/wiki/Database_normalization
If you follow normalization principles, not only you will very rarely make the wrong choice, but you also signal the intenet of your design semantically. Extending a table by placing an ID in it and adding an extra table does not mean semantically what the author is trying to do. The reasons being integraty and ocurrence of nulls. Which the author kind of hints he wants to avoid. Ultimately you will hur performance by not folowing well known and established principles.
Really good breakdown, in my opinion.
It depends on a lot of things ofc, but I think you gotta ask how many users have hubspot ids. Like if only 5% have them, option A looks really bad. B-2 (& -3?) doesn’t bloat the original table at all, which seems rather nice. I’d say B-2 & B-4 are my favorites.
Another reason to use separate tables is if the fields are modified by different transactions/clients: even if a transaction only changes one field in a row, the whole row will be locked, and the whole row will be written out.