Tatsächlich heißt das von Ihnen beschriebene Design (gemeinsame Tabelle plus subtypspezifische Tabellen) Class Table Inheritance .
Konkrete Tabellenvererbung alle gemeinsamen Attribute in den Subtype-Tabellen dupliziert, und Sie hätten keine Supertype-Tabelle wie jetzt.
Ich bin strikt gegen EAV. Ich halte es für ein SQL-Antimuster. Es mag wie eine elegante Lösung erscheinen, weil es weniger Tische erfordert, aber Sie stellen sich später auf eine Menge Kopfschmerzen ein. Sie haben einige der Nachteile identifiziert, aber es gibt noch viele andere. IMHO wird EAV nur dann angemessen verwendet, wenn Sie es absolut nicht dürfen Erstellen Sie eine neue Tabelle, wenn Sie einen neuen Untertyp einführen oder wenn Sie eine unbegrenzte Anzahl von Untertypen haben (z. B. können Benutzer neue Attribute ad hoc definieren).
Sie haben viele Untertypen, aber immer noch eine begrenzte Anzahl davon, also würde ich bei diesem Projekt bei Klassentabellenvererbung bleiben . Möglicherweise haben Sie nur wenige Zeilen von jedem Untertyp, aber Sie haben zumindest eine gewisse Sicherheit, dass alle Zeilen in jedem Untertyp die gleichen Spalten haben, Sie können NOT NULL
verwenden Bei Bedarf können Sie SQL-Datentypen verwenden, Sie können referenzielle Integritätsbedingungen verwenden usw. Aus relationaler Sicht ist es ein besseres Design als EAV.
Eine weitere Option, die Sie nicht erwähnt haben, heißt Serialized LOB . Fügen Sie also eine BLOB-Spalte für eine halbstrukturierte Sammlung benutzerdefinierter Attribute hinzu. Speichern Sie XML, YAML, JSON oder Ihre eigene DSL in dieser Spalte. Sie können einzelne Attribute aus diesem BLOB nicht einfach mit SQL parsen, Sie müssen das gesamte BLOB zurück in Ihre Anwendung holen und einzelne Attribute im Code extrahieren. In gewisser Weise ist es also weniger bequem. Aber wenn das Ihre Nutzung der Daten zufriedenstellt, ist daran nichts auszusetzen.