Loading learning content...
Throughout this module, we've built a comprehensive understanding of 1:1 relationship characteristics, mapping strategies, and decision criteria. Now it's time to apply everything to realistic scenarios.
This page presents five detailed case studies, each walking through the complete process: understanding the domain, analyzing participation, applying the decision framework, implementing the schema, and explaining the rationale. These examples span different industries and demonstrate how the same principles apply universally while producing context-appropriate solutions.
By working through these examples, you'll develop the pattern recognition and analytical skills to confidently handle any 1:1 mapping challenge you encounter in practice.
By the end of this page, you will see the decision framework applied to real-world scenarios, understand how participation analysis drives strategy selection, recognize common 1:1 patterns across industries, and gain confidence in your ability to make and defend mapping decisions.
Domain: Hospital Patient Management System
A hospital system manages patients and their medical records. Each patient has a core demographic record (name, date of birth, contact information, insurance) and a comprehensive medical record (diagnoses, medications, allergies, visit history).
ER Model Analysis:
Participation Analysis:
Level 1 (Participation): Total-Total → Both merge and FK are viable Level 2 (Coupling): Strong lifecycle coupling (created together), but different access patterns Level 3 (Non-Functional): Different security requirements—admin staff access demographics, clinical staff access medical records
Decision: Foreign Key Approach
Despite total-total participation, we choose the foreign key approach because:
The FK goes in MEDICAL_RECORD since medical records are conceptually dependent on patients and created after the patient record.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
-- Demographics (accessible by administrative staff)CREATE TABLE patient ( patient_id INT PRIMARY KEY, mrn VARCHAR(20) UNIQUE NOT NULL, -- Medical Record Number first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, date_of_birth DATE NOT NULL, gender CHAR(1) CHECK (gender IN ('M', 'F', 'O')), address VARCHAR(200), phone VARCHAR(20), email VARCHAR(100), insurance_provider VARCHAR(100), insurance_policy VARCHAR(50), emergency_contact VARCHAR(100), registered_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP); -- Clinical data (accessible by clinical staff)CREATE TABLE medical_record ( record_id INT PRIMARY KEY, patient_id INT UNIQUE NOT NULL, -- 1:1 enforced by UNIQUE blood_type CHAR(3), allergies TEXT, chronic_conditions TEXT, current_medications TEXT, primary_physician VARCHAR(100), last_visit_date DATE, notes TEXT, CONSTRAINT fk_patient FOREIGN KEY (patient_id) REFERENCES patient(patient_id) ON DELETE RESTRICT -- Prevent accidental deletion ON UPDATE CASCADE); -- Grant different accessGRANT SELECT ON patient TO admin_staff;GRANT SELECT ON medical_record TO clinical_staff; -- Combined view for authorized usersCREATE VIEW v_patient_complete ASSELECT p.*, m.blood_type, m.allergies, m.current_medicationsFROM patient pJOIN medical_record m ON p.patient_id = m.patient_id; GRANT SELECT ON v_patient_complete TO attending_physicians;Domain: Online Shopping Platform
An e-commerce platform has user accounts with authentication credentials and profile settings (preferences, display options, notification choices).
ER Model Analysis:
Participation Analysis:
Decision Framework Application:
Decision: Merged Table Approach
All factors point toward merging:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
-- Merged user tableCREATE TABLE user_account ( user_id INT PRIMARY KEY AUTO_INCREMENT, -- Authentication attributes (originally USER_ACCOUNT) email VARCHAR(100) UNIQUE NOT NULL, password_hash CHAR(60) NOT NULL, -- bcrypt hash mfa_enabled BOOLEAN DEFAULT false, mfa_secret VARCHAR(32), email_verified BOOLEAN DEFAULT false, account_status VARCHAR(20) DEFAULT 'active' CHECK (account_status IN ('active', 'suspended', 'deleted')), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_login TIMESTAMP, -- Profile attributes (originally USER_PROFILE) display_name VARCHAR(50), avatar_url VARCHAR(255), bio TEXT, -- Preferences (also from USER_PROFILE) pref_theme VARCHAR(10) DEFAULT 'system' CHECK (pref_theme IN ('light', 'dark', 'system')), pref_language CHAR(5) DEFAULT 'en-US', pref_currency CHAR(3) DEFAULT 'USD', pref_timezone VARCHAR(50) DEFAULT 'UTC', -- Notification settings notify_email BOOLEAN DEFAULT true, notify_push BOOLEAN DEFAULT true, notify_sms BOOLEAN DEFAULT false, -- Metadata updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); -- Indexes for common queriesCREATE INDEX idx_user_email ON user_account(email);CREATE INDEX idx_user_status ON user_account(account_status); -- Application authentication query (very fast - single table)-- SELECT user_id, password_hash, mfa_enabled, mfa_secret-- FROM user_account WHERE email = ? AND account_status = 'active'; -- Page render query (all needed in one row)-- SELECT display_name, avatar_url, pref_theme, pref_language-- FROM user_account WHERE user_id = ?;Domain: Corporate Vehicle Assignment
A company manages a fleet of vehicles that may be assigned to employees. Not all employees have vehicles; not all vehicles are assigned.
ER Model Analysis:
Participation Analysis:
Partial-partial is the most challenging 1:1 pattern. Neither entity always participates, so a foreign key in either table creates NULLs. We must choose between accepting NULLs or using a cross-reference table.
Decision Framework Application:
Decision: Cross-Reference Table
Given the need for relationship attributes and potential history tracking, plus NULL avoidance, we choose the cross-reference table approach.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
-- Employees (no vehicle FK)CREATE TABLE employee ( employee_id INT PRIMARY KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, department VARCHAR(50) NOT NULL, hire_date DATE NOT NULL, position VARCHAR(100)); -- Company vehicles (no employee FK)CREATE TABLE company_vehicle ( vehicle_id INT PRIMARY KEY, license_plate VARCHAR(20) UNIQUE NOT NULL, make VARCHAR(50) NOT NULL, model VARCHAR(50) NOT NULL, year INT NOT NULL, vin CHAR(17) UNIQUE NOT NULL, vehicle_type VARCHAR(30), purchase_date DATE, status VARCHAR(20) DEFAULT 'available' CHECK (status IN ('available', 'assigned', 'maintenance', 'retired'))); -- Cross-reference table with relationship attributesCREATE TABLE vehicle_assignment ( assignment_id INT PRIMARY KEY AUTO_INCREMENT, employee_id INT UNIQUE NOT NULL, -- UNIQUE enforces 1:1 vehicle_id INT UNIQUE NOT NULL, -- UNIQUE enforces 1:1 -- Relationship attributes assigned_date DATE NOT NULL, assigned_by INT, assignment_reason VARCHAR(200), expected_return DATE, mileage_at_assign INT, CONSTRAINT fk_employee FOREIGN KEY (employee_id) REFERENCES employee(employee_id), CONSTRAINT fk_vehicle FOREIGN KEY (vehicle_id) REFERENCES company_vehicle(vehicle_id), CONSTRAINT fk_assigned_by FOREIGN KEY (assigned_by) REFERENCES employee(employee_id)); -- Query: Find an employee's assigned vehicleSELECT e.first_name, e.last_name, v.make, v.model, v.license_plateFROM employee eJOIN vehicle_assignment va ON e.employee_id = va.employee_idJOIN company_vehicle v ON va.vehicle_id = v.vehicle_idWHERE e.employee_id = ?; -- Query: Find unassigned employees (for eligibility check)SELECT e.*FROM employee eLEFT JOIN vehicle_assignment va ON e.employee_id = va.employee_idWHERE va.employee_id IS NULL; -- Query: Find available vehiclesSELECT v.*FROM company_vehicle vLEFT JOIN vehicle_assignment va ON v.vehicle_id = va.vehicle_idWHERE va.vehicle_id IS NULL AND v.status = 'available'; -- Trigger to update vehicle status on assignmentCREATE TRIGGER after_assignment_insertAFTER INSERT ON vehicle_assignmentFOR EACH ROW UPDATE company_vehicle SET status = 'assigned' WHERE vehicle_id = NEW.vehicle_id;Domain: Global Geographic Information System
A geographic database tracks countries and their capitals for diplomatic, logistics, and reference purposes.
ER Model Analysis:
Participation Analysis:
Important distinction: We're modeling CAPITAL_CITY as the capital attribute set, not as a general CITY entity. If cities were a separate entity with many cities per country (1:N), and some cities are capitals, the design would be different.
Decision Framework Application:
Decision: Merged Table Approach
The capital is effectively an attribute set of the country, not an independent entity. Merging is natural.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
-- Merged country table with capital attributesCREATE TABLE country ( country_id INT PRIMARY KEY, country_code CHAR(2) UNIQUE NOT NULL, -- ISO 3166-1 alpha-2 country_code_3 CHAR(3) UNIQUE NOT NULL, -- ISO 3166-1 alpha-3 country_name VARCHAR(100) NOT NULL, official_name VARCHAR(200), -- Core country data population BIGINT, area_km2 DECIMAL(12, 2), continent VARCHAR(20), region VARCHAR(50), currency_code CHAR(3), -- Capital attributes (merged from CAPITAL_CITY concept) capital_name VARCHAR(100) NOT NULL, capital_lat DECIMAL(9, 6), capital_lng DECIMAL(9, 6), capital_population INT, capital_timezone VARCHAR(50), capital_elevation INT, -- meters above sea level -- Metadata independence_date DATE, government_type VARCHAR(100), updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP); -- Sample dataINSERT INTO country ( country_id, country_code, country_code_3, country_name, population, area_km2, continent, capital_name, capital_lat, capital_lng, capital_population, capital_timezone) VALUES(1, 'FR', 'FRA', 'France', 67390000, 551695, 'Europe', 'Paris', 48.8566, 2.3522, 2161000, 'Europe/Paris'),(2, 'JP', 'JPN', 'Japan', 125800000, 377975, 'Asia', 'Tokyo', 35.6762, 139.6503, 13960000, 'Asia/Tokyo'),(3, 'BR', 'BRA', 'Brazil', 212600000, 8515767, 'South America', 'Brasília', -15.7942, -47.8825, 3055000, 'America/Sao_Paulo'); -- Typical queries are simple (no join needed)SELECT country_name, capital_name, capital_populationFROM countryWHERE continent = 'Europe'; -- Geographic queries straightforwardSELECT country_name, capital_name, capital_lat, capital_lngFROM countryWHERE capital_lat BETWEEN -10 AND 10; -- Countries with equatorial capitalsIf the system also tracked general cities (tourism data, airports, etc.), capital would be a 1:1 relationship between COUNTRY and a subset of CITY entities. In that case, a foreign key approach (capital_city_id in COUNTRY) would be appropriate, with the FK referencing the CITY table.
Domain: Legal Document Management
A law firm manages confidential documents that can be checked out for editing. Only one person can have a document checked out at a time to prevent conflicts.
ER Model Analysis:
Participation Analysis:
Decision Framework Application:
This is a clear case: participation type directly determines the approach.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
-- Document entity (partial participation - not all are checked out)CREATE TABLE document ( document_id INT PRIMARY KEY, title VARCHAR(200) NOT NULL, document_type VARCHAR(50) NOT NULL, client_id INT NOT NULL, case_number VARCHAR(50), security_level VARCHAR(20) DEFAULT 'confidential' CHECK (security_level IN ('public', 'internal', 'confidential', 'restricted')), created_date DATE NOT NULL, created_by INT NOT NULL, last_modified TIMESTAMP DEFAULT CURRENT_TIMESTAMP, version INT DEFAULT 1, file_path VARCHAR(500) NOT NULL); -- Checkout entity (total participation - every checkout is for a document)CREATE TABLE checkout_record ( checkout_id INT PRIMARY KEY AUTO_INCREMENT, document_id INT UNIQUE NOT NULL, -- FK + UNIQUE = 1:1 checked_out_by INT NOT NULL, checkout_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, expected_return TIMESTAMP, purpose VARCHAR(500), workstation VARCHAR(100), CONSTRAINT fk_document FOREIGN KEY (document_id) REFERENCES document(document_id) ON DELETE CASCADE, -- If document deleted, checkout record goes too CONSTRAINT fk_user FOREIGN KEY (checked_out_by) REFERENCES employee(employee_id)); -- Check if document is available for checkoutSELECT d.document_id, d.title, CASE WHEN cr.checkout_id IS NULL THEN 'Available' ELSE 'Checked Out' END AS status, cr.checked_out_by, cr.checkout_timeFROM document dLEFT JOIN checkout_record cr ON d.document_id = cr.document_idWHERE d.document_id = ?; -- Attempt to checkout (would fail if already checked out due to UNIQUE constraint)INSERT INTO checkout_record (document_id, checked_out_by, purpose)VALUES (?, ?, 'Client review edits');-- If document already checked out, UNIQUE violation error -- Check in document (delete the checkout record)DELETE FROM checkout_record WHERE document_id = ? AND checked_out_by = ?; -- Find all documents checked out by a userSELECT d.document_id, d.title, cr.checkout_timeFROM checkout_record crJOIN document d ON cr.document_id = d.document_idWHERE cr.checked_out_by = ?; -- Trigger to update document last_modified on checkoutCREATE TRIGGER after_checkout_insertAFTER INSERT ON checkout_recordFOR EACH ROW UPDATE document SET last_modified = CURRENT_TIMESTAMP WHERE document_id = NEW.document_id;Let's summarize the five examples to reinforce pattern recognition:
| Domain | Relationship | Participation | Strategy | Key Factor |
|---|---|---|---|---|
| Healthcare | Patient ↔ Medical Record | Total-Total | Foreign Key | Security divergence |
| E-Commerce | User ↔ Profile | Total-Total | Merged Table | Strong coupling, same security |
| Fleet Mgmt | Employee ↔ Vehicle | Partial-Partial | Cross-Reference | NULL avoidance, relationship attrs |
| Geopolitical | Country ↔ Capital | Total-Total | Merged Table | Capital is attribute set of country |
| Legal Docs | Document ↔ Checkout | Partial-Total | Foreign Key | Participation determines placement |
Notice how participation patterns strongly correlate with strategy choices:
• Total-Total → Evaluate coupling; merge if strong, FK if security/access diverges • Total-Partial or Partial-Total → Foreign key in total-participation side (nearly always) • Partial-Partial → Cross-reference if NULL-averse or relationship has attributes; otherwise FK with NULLs in lower-NULL-ratio side
Before concluding, let's highlight mistakes commonly made when mapping 1:1 relationships:
Through theory and practical examples, you've now developed comprehensive expertise in mapping 1:1 relationships from ER diagrams to relational schemas.
Congratulations!
You've completed the module on mapping 1:1 relationships. You now possess the knowledge to analyze any 1:1 relationship, apply the decision framework, implement the optimal strategy, and defend your design choices. This expertise forms a critical component of your overall database design capability.
In subsequent modules, we'll explore 1:N and M:N relationship mapping, building on the foundations established here.
You have completed Module 3: Relationship Mapping (1:1). You've mastered the semantic understanding of 1:1 relationships, all three mapping strategies, the systematic decision framework, and practical implementation across diverse domains. Apply this knowledge confidently in your database design work.