| Lesson 5 | One-to-one relationships, part 2 |
| Objective | Identify one-to-one relationships from business rules and choose an appropriate implementation. |
A one-to-one (1:1) relationship permits at most one related instance in each direction. To identify it, ask two questions: how many B instances may belong to one A, and how many A instances may belong to one B? Both maximums must be one. Whether either instance may exist without the other is a separate question about participation.
This lesson develops the Person and current Passport example from Lesson 4. It explains how to test the business rule, recognize misleading examples, and select constraints that enforce the intended relationship.
Begin with what the application must allow, rather than the rows currently stored. A table containing one related row today may still permit several tomorrow.
Review mandatory and optional participation for the distinction between a minimum of zero and a minimum of one.
| Statement | Question to resolve | Design implication |
|---|---|---|
| Each employee has one office. | May several employees share an office? | If yes, Office to Employee is 1:N. If sharing is forbidden and each employee has at most one office, it is 1:1. |
| A customer has one primary address. | Can the customer store additional addresses? | Customer to Address may be 1:N even though only one address is designated primary. |
| A company has one CEO at a time. | Does the table retain previous appointments? | A history contains multiple company-to-appointment rows. Uniqueness of the current appointment is a separate rule. |
| Every person currently has one passport row. | Does policy forbid a second current row? | Existing data alone does not establish 1:1. The permitted maximum and its constraints do. |
A filtered or partial unique index can enforce some selected-row rules in DBMSs that support it. For example, it can limit a customer to at most one address marked primary. That does not require a primary address to exist. Historical date ranges may also need overlap checks; uniqueness of a current flag alone does not prevent overlapping past appointments.
Place the reference according to ownership and participation. In the Person/Passport example, Passport is the dependent entity: a passport record cannot exist without its person, while a person can exist without a passport record.
Passport.PersonID must match an existing Person.PersonID.These constraints allow a Person row with no matching Passport row. Making the foreign key non-null does not make participation mandatory on the Person side. If both entities must always have a counterpart, an additional enforcement mechanism appropriate to the DBMS is needed, or the facts may belong in one table. Creating both rows in a transaction is useful, but it is not by itself a database-wide guarantee that every writer will obey the rule.
If either entity may exist independently, a nullable unique foreign key is one possible design. Check the DBMS's treatment of nulls in unique constraints; it varies between implementations. Choose the referencing side from the business rule rather than assuming the smaller table is always the correct choice.
For supporting concepts, review data integrity elements and constraint types.
A unique foreign key gives each table its own identifier. A Passport has a PassportID and a unique PersonID reference. This is the pattern used in the worked example below.
A shared primary key makes the dependent table's PersonID both its primary key and its foreign key. Because a primary key is unique and non-null, no second dependent row can use the same PersonID.
-- Alternative to the Passport definition below.
-- Create Person first; use only one Passport design.
CREATE TABLE Passport (
PersonID INT NOT NULL PRIMARY KEY,
PassportNumber VARCHAR(30) NOT NULL,
CONSTRAINT fk_passport_person
FOREIGN KEY (PersonID) REFERENCES Person(PersonID)
);
Both patterns enforce the same upper bound. Neither requires every Person to have a Passport. Decide deletion and retention behavior separately: removing a person does not automatically imply that a dependent record should be deleted. Use cascading deletion only when the business policy calls for it.
The system stores at most one current passport record per person. A person may have none; every passport record belongs to one person. This is the same simplified rule used in Lessons 3 and 4, rather than a universal rule about passports or citizenship. Supply identifiers explicitly in these examples.
CREATE TABLE Person (
PersonID INT NOT NULL PRIMARY KEY,
PersonName VARCHAR(100) NOT NULL
);
CREATE TABLE Passport (
PassportID INT NOT NULL PRIMARY KEY,
PersonID INT NOT NULL,
PassportNumber VARCHAR(30) NOT NULL,
CONSTRAINT uq_passport_person UNIQUE (PersonID),
CONSTRAINT fk_passport_person
FOREIGN KEY (PersonID) REFERENCES Person(PersonID)
);
| Operation | Expected result | Reason |
|---|---|---|
| Keep Ben without a passport row. | Allowed | Person participation is optional. |
| Create Passport 5001 for Person 101. | Allowed | Ava exists and has no passport row yet. |
| Then create Passport 5002 for Person 101. | Rejected | PersonID 101 would repeat in the unique foreign key. |
| Create a passport for PersonID 999, which does not exist. | Rejected | The foreign key requires an existing person. |
| Create a passport with a null PersonID. | Rejected | The foreign key column is NOT NULL. |
In the unique-foreign-key design, join the tables using Passport.PersonID = Person.PersonID. PassportID identifies a passport row; it does not have to equal the person's identifier. If all historical passports must be retained, revise the data model instead of using this uniqueness rule on the entire history.
A one-to-one association can reflect a distinct dependent entity or a deliberate division of information about the same entity. Separate tables may be useful when information has different access permissions, is rarely present, or follows a different retention policy. Permissions still need to be configured; placing sensitive columns in a second table does not protect them automatically.
Keep attributes together when they describe the same entity, are usually used together, and share the same access and retention rules. An additional table adds joins and maintenance work. Any performance benefit from splitting rows depends on the workload, indexes, and DBMS.
“Employees are assigned their own office” is incomplete until “own” is defined. A one-to-one rule would say: each employee may occupy at most one office, and each office may be occupied by at most one employee. Specify whether unassigned employees and empty offices are allowed.
If an office can be shared, the office-to-employee maximum becomes many. If an employee can occupy several offices and offices can be shared, the association becomes M:N. Discuss possible policy changes with stakeholders, but implement the confirmed rule rather than silently allowing sharing that the organization currently forbids.
Complete the one-to-one relationships exercise to practice interpreting business rules.