Cuốn sách "Áp dụng UML với các mẫu" của Craig Larman mô tả 3 giải pháp phổ biến cho vấn đề này.
Các ví dụ của bạn không đặc biệt hữu ích - không có lý do hợp lý nào để có 3 cách khác nhau để quản lý tên của một người trong cơ sở dữ liệu của bạn (mặc dù điều này thường xuyên xảy ra do nhập / xuất dữ liệu kỳ lạ).
Tuy nhiên, rất phổ biến khi có một thực thể "người" có thể là nhân viên (với worker_id), người liên hệ (có liên kết đến bảng khách hàng tiềm năng) hoặc khách hàng (với customer_id và liên kết đến bảng đơn hàng) .
Trong cuốn sách của Larman, ông đưa ra 3 giải pháp.
Một bảng để thống trị tất cả Tại đây, bạn tạo một bảng duy nhất với tất cả các cột đã biết. Điều này tạo ra một bảng lộn xộn và đẩy trách nhiệm biết các quy tắc duy trì từng lớp con cho lớp ứng dụng - cơ sở dữ liệu sẽ không bắt buộc khách hàng phải có customer_id. Tuy nhiên, nó làm cho việc tham gia dễ dàng hơn nhiều - bất kỳ bảng nào cần liên kết với một người đều có thể liên kết với bảng người đó.
Bảng siêu lớp Điều này làm sạch mọi thứ bằng cách trích xuất các thuộc tính chung vào một bảng duy nhất - ví dụ:"person" - và đẩy các trường dành riêng cho lớp con vào bảng lớp con. Vì vậy, bạn có thể có "người" làm bảng lớp cha và bảng "liên hệ", "nhân viên" và "khách hàng" với dữ liệu lớp con cụ thể. Các bảng lớp con có một cột "person_id" để liên kết trở lại bảng lớp cha. Điều này phức tạp hơn - nó thường yêu cầu một phép nối bổ sung khi truy xuất dữ liệu - nhưng cũng ít bị lỗi hơn nhiều - bạn không thể vô tình làm hỏng mô hình dữ liệu với lỗi ghi các thuộc tính không hợp lệ cho "nhân viên".
Bảng cho mỗi lớp con - đây là những gì bạn đã mô tả. Nó tạo ra một lượng lớn trùng lặp vào mô hình dữ liệu và bạn thường có các phép nối có điều kiện - "tham gia trên bảng x nếu người loại =y", điều này có thể làm cho mã truy cập dữ liệu trở nên phức tạp.