One-to-one relationships are sometimes used to split a table into multiple parts, and everything I have read says to have the "extra data" (address) use the primary key of the "main entity" (thing_with_address) along with a foreign key back to it.
thing_with_address
- id (PK)
- other_data
address (value object and not shared)
- id (PK, FK to thing_with_address.id)
- street
- city
- state_id (FK to state.id)
But what if I didn't have one thing_with_address, but several?
I obviously don't want to add multiple columns in address to reference each thing_with_address. Another option is to create a separate address table for each thing table, however, doing so is not desired.
One option is to make all the thing_with_address's supertype/subtype entities and then have address reference the common supertype. My only real concerns with this approach are adding address to an existing thing without an address will be a pain, and inheritance gets a little messing if there is more than one fork.
thing_with_address_super
- id (PK)
- discriminator
- other_common_data
thing_with_address_1
- id (PK, FK to thing_with_address_super.id)
- other_unique_data
thing_with_address_2
- id (PK, FK to thing_with_address_super.id)
- other_unique_data
address
- id (PK, FK to thing_with_address_super.id)
- street
- city
- state_id (FK to state.id)
Alternatively, one could supertype/subtype the value object. More tables but less of an issue if adding an existing thing without an address and less issues with inheritance.
thing_with_address_1
- id (PK)
- other_common_data
thing_with_address_2
- id (PK)
- other_common_data
address_super
- id (PK)
- street
- city
- state_id (FK to state.id)
address_1
- id (PK, FK to address_super.id)
- thing_with_address_1_id (FK to thing_with_address_1.id)
address_2
- id (PK, FK to address_super.id)
- thing_with_address_2_id (FK to thing_with_address_2.id)
Another option is to move the FK to the main table. My main concern with this approach is I've never seen it done and there probably is a good reason why. Expect it has to do with multiple things using the same address, and maybe more.
thing_with_address_1
- id (PK)
- address_id (FK to address.id)
- other_data
thing_with_address_2
- id (PK)
- address_id (FK to address.id)
- other_data
address
- id (PK)
- street
- city
- state_id (FK to state.id)
How should this be modelled when the entity address could and could not be NULL?