sql >> Database >  >> RDS >> Sqlserver

Hoe kunt u overerving in een database weergeven?

@Bill Karwin beschrijft drie overervingsmodellen in zijn SQL Antipatterns-boek, wanneer hij oplossingen voorstelt voor het SQL Entity-Attribute-Value antipatroon. Dit is een kort overzicht:

Overerving van één tabel (ook bekend als overerving van tabellen per hiërarchie):

Het gebruik van een enkele tabel zoals in uw eerste optie is waarschijnlijk het eenvoudigste ontwerp. Zoals je al zei, moeten veel attributen die specifiek zijn voor een subtype een NULL krijgen waarde op rijen waar deze kenmerken niet van toepassing zijn. Met dit model zou u één beleidstabel hebben, die er ongeveer zo uit zou zien:

+------+---------------------+----------+----------------+------------------+
| id   | date_issued         | type     | vehicle_reg_no | property_address |
+------+---------------------+----------+----------------+------------------+
|    1 | 2010-08-20 12:00:00 | MOTOR    | 01-A-04004     | NULL             |
|    2 | 2010-08-20 13:00:00 | MOTOR    | 02-B-01010     | NULL             |
|    3 | 2010-08-20 14:00:00 | PROPERTY | NULL           | Oxford Street    |
|    4 | 2010-08-20 15:00:00 | MOTOR    | 03-C-02020     | NULL             |
+------+---------------------+----------+----------------+------------------+

\------ COMMON FIELDS -------/          \----- SUBTYPE SPECIFIC FIELDS -----/

Het ontwerp eenvoudig houden is een pluspunt, maar de belangrijkste problemen met deze aanpak zijn de volgende:

  • Als het gaat om het toevoegen van nieuwe subtypes, zou u de tabel moeten aanpassen aan de kenmerken die deze nieuwe objecten beschrijven. Dit kan snel problematisch worden als je veel subtypen hebt, of als je van plan bent om regelmatig subtypen toe te voegen.

  • De database kan niet afdwingen welke attributen van toepassing zijn en welke niet, aangezien er geen metadata is om te bepalen welke attributen bij welke subtypes horen.

  • U kunt NOT NULL ook niet afdwingen op attributen van een subtype dat verplicht zou moeten zijn. Je zou dit in je applicatie moeten verwerken, wat over het algemeen niet ideaal is.

Overerving van betonnen tafel:

Een andere benadering om overerving aan te pakken, is door voor elk subtype een nieuwe tabel te maken, waarbij alle gemeenschappelijke kenmerken in elke tabel worden herhaald. Bijvoorbeeld:

--// Table: policies_motor
+------+---------------------+----------------+
| id   | date_issued         | vehicle_reg_no |
+------+---------------------+----------------+
|    1 | 2010-08-20 12:00:00 | 01-A-04004     |
|    2 | 2010-08-20 13:00:00 | 02-B-01010     |
|    3 | 2010-08-20 15:00:00 | 03-C-02020     |
+------+---------------------+----------------+
                          
--// Table: policies_property    
+------+---------------------+------------------+
| id   | date_issued         | property_address |
+------+---------------------+------------------+
|    1 | 2010-08-20 14:00:00 | Oxford Street    |   
+------+---------------------+------------------+

Dit ontwerp lost in principe de problemen op die zijn geïdentificeerd voor de methode met één tafel:

  • Verplichte attributen kunnen nu worden afgedwongen met NOT NULL .

  • Om een ​​nieuw subtype toe te voegen, moet een nieuwe tabel worden toegevoegd in plaats van kolommen aan een bestaande toe te voegen.

  • Er is ook geen risico dat een ongepast kenmerk wordt ingesteld voor een bepaald subtype, zoals de vehicle_reg_no veld voor een vastgoedbeleid.

  • Het type is niet nodig attribuut zoals in de enkele tabel methode. Het type wordt nu gedefinieerd door de metadata:de tabelnaam.

Dit model heeft echter ook enkele nadelen:

  • De gemeenschappelijke attributen zijn vermengd met de subtype-specifieke attributen, en er is geen gemakkelijke manier om ze te identificeren. De database zal het ook niet weten.

  • Bij het definiëren van de tabellen zou u de gemeenschappelijke kenmerken voor elke subtypetabel moeten herhalen. Dat is zeker niet DROOG.

  • Zoeken naar alle beleidsregels, ongeacht het subtype, wordt moeilijk en vereist een heleboel UNION v.

Dit is hoe u alle beleidsregels zou moeten opvragen, ongeacht het type:

SELECT     date_issued, other_common_fields, 'MOTOR' AS type
FROM       policies_motor
UNION ALL
SELECT     date_issued, other_common_fields, 'PROPERTY' AS type
FROM       policies_property;

Merk op dat voor het toevoegen van nieuwe subtypen de bovenstaande zoekopdracht moet worden aangepast met een extra UNION ALL voor elk subtype. Dit kan gemakkelijk leiden tot bugs in uw applicatie als deze handeling wordt vergeten.

Overerving van klassentabel (ook bekend als overerving van tabel per type):

Dit is de oplossing die @David in het andere antwoord noemt. U maakt een enkele tabel voor uw basisklasse, die alle algemene kenmerken bevat. Dan zou je voor elk subtype specifieke tabellen maken, waarvan de primaire sleutel ook als refererende sleutel voor de basistabel dient. Voorbeeld:

CREATE TABLE policies (
   policy_id          int,
   date_issued        datetime,

   -- // other common attributes ...
);

CREATE TABLE policy_motor (
    policy_id         int,
    vehicle_reg_no    varchar(20),

   -- // other attributes specific to motor insurance ...

   FOREIGN KEY (policy_id) REFERENCES policies (policy_id)
);

CREATE TABLE policy_property (
    policy_id         int,
    property_address  varchar(20),

   -- // other attributes specific to property insurance ...

   FOREIGN KEY (policy_id) REFERENCES policies (policy_id)
);

Deze oplossing lost de problemen op die zijn geïdentificeerd in de andere twee ontwerpen:

  • Verplichte attributen kunnen worden afgedwongen met NOT NULL .

  • Om een ​​nieuw subtype toe te voegen, moet een nieuwe tabel worden toegevoegd in plaats van kolommen aan een bestaande toe te voegen.

  • Geen risico dat een ongepast kenmerk is ingesteld voor een bepaald subtype.

  • Geen behoefte aan het type attribuut.

  • Nu worden de gemeenschappelijke attributen niet meer gemengd met de subtype-specifieke attributen.

  • We kunnen eindelijk DROOG blijven. Het is niet nodig om de gemeenschappelijke kenmerken voor elke subtypetabel te herhalen bij het maken van de tabellen.

  • Een automatisch oplopende id beheren want het beleid wordt eenvoudiger, omdat dit kan worden afgehandeld door de basistabel, in plaats van dat elke subtypetabel ze onafhankelijk genereert.

  • Zoeken naar alle beleidsregels, ongeacht het subtype, wordt nu heel eenvoudig:Nee UNION s nodig - alleen een SELECT * FROM policies .

Ik beschouw de klassentafelbenadering als de meest geschikte in de meeste situaties.

De namen van deze drie modellen komen uit Martin Fowler's boek Patterns of Enterprise Application Architecture.



  1. Oplossingen voor INSERT OF UPDATE op SQL Server

  2. Meerdere kolommen bijwerken in MySQL

  3. Meerdere geparametriseerde variabelen toevoegen aan een database in c#

  4. Grootte van alle tabellen in de database ophalen