Książka Craiga Larmana „Zastosowanie UML za pomocą wzorców” opisuje 3 typowe rozwiązania tego problemu.
Twoje przykłady nie są szczególnie pomocne — nie ma logicznego powodu, aby mieć 3 różne sposoby zarządzania nazwiskiem osoby w swojej bazie danych (chociaż zdarza się to często z powodu dziwności importu/eksportu danych).
Jednak bardzo często występuje jednostka „osoba”, która może być pracownikiem (z identyfikatorem pracownika), kontaktem (z linkiem do tabeli potencjalnych klientów) lub klientem (z identyfikatorem klienta i linkiem do tabeli zamówień) .
W książce Larmana podaje 3 rozwiązania.
Jeden stół, by wszystkimi rządzić Tutaj tworzysz pojedynczą tabelę ze wszystkimi znanymi kolumnami. Tworzy to niechlujną tabelę i przenosi odpowiedzialność za znajomość zasad utrwalania każdej podklasy na warstwę aplikacji — baza danych nie wymusza na klientach konieczności posiadania identyfikatora klienta. Jednak znacznie ułatwia to sprzężenia — każda tabela, która musi łączyć się z osobą, może po prostu łączyć się z tabelą osoby.
Stół superklasy To czyści wszystko, wyodrębniając wspólne atrybuty do jednej tabeli - np. "person" - i wypycha pola specyficzne dla podklasy do tabel podklas. Tak więc możesz mieć „osobę” jako tabelę nadklasy oraz tabele „kontakt”, „pracownik” i „klient” z określonymi danymi podklasy. Tabele podklas mają kolumnę „person_id”, która łączy się z tabelą nadklas. Jest to bardziej złożone — zwykle wymaga dodatkowego sprzężenia podczas pobierania danych — ale także znacznie mniej podatne na błędy — nie można przypadkowo uszkodzić modelu danych błędem, który zapisuje nieprawidłowe atrybuty dla „pracownika”.
Tabela na podklasę - to właśnie opisałeś. Wprowadza sporą ilość duplikacji do modelu danych i często występują sprzężenia warunkowe — „dołącz do tabeli x, jeśli typ osoby =y”, co może utrudnić kod dostępu do danych.