Secondo la mia interpretazione delle tue specifiche, vuoi trovare un metodo per implementare due diverse (ma connesse ) strutture di sottotipo-sottotipo .
Al fine di esporre un approccio per raggiungere il suddetto compito, aggiungerò allo scenario in questione i due classici tipi di entità ipotetici chiamati Foo
e Bar
, di cui parlerò in dettaglio.
Regole di business
Ecco alcune affermazioni che mi aiuteranno a creare un modello logico:
A Foo is either one Bar or one C
A Foo is categorized by one FooType
A Bar is either one A or one C
A Bar is classified by one BarType
Modello logico
E poi, il modello logico IDEF1X [1] risultante è mostrato nella Figura 1 (e puoi scaricarlo anche da Dropbox come PDF ):
L'aggiunta di Foo and Bar
Non ho aggiunto Foo
e Bar
per rendere il modello migliore, ma per renderlo più espressivo. Ritengo che siano importanti a causa di quanto segue:
Poiché A
e B
condividono l'attributo denominato E
, questa funzionalità suggerisce che si tratta di tipi di subentity di un tipo distinto (ma correlato) di concetto , evento , persona , misurazione , ecc., Che ho rappresentato per mezzo del Bar
tipo di superentity che, a sua volta, è un tipo di subentity di Foo
, che contiene l' D
attributo nella parte superiore della gerarchia.
Poiché C
condivide solo un attributo con il resto dei tipi di entità in discussione, vale a dire, D
questo aspetto insinua che si tratta di un tipo di subentità di un altro tipo di concetto , evento , persona , misurazione , ecc., Quindi ho rappresentato questa circostanza in virtù di il Foo
tipo di super entità.
Tuttavia, questi sono solo presupposti e poiché un database relazionale è pensato per riflettere accuratamente la semantica di un determinato contesto aziendale , devi identificare e classificare tutte le cose di interesse nel tuo dominio specifico in modo da poter, precisamente, acquisire più significato .
Fattori importanti in fase di progettazione
È abbastanza utile essere consapevoli del fatto che, mettendo da parte tutta la terminologia, un cluster esclusivo di sottotipo e sottotipo è una relazione ordinaria. Descriviamo la situazione nel modo seguente:
- Ogni occorrenza del tipo di superentity esclusivo è correlata a un solo complemento di tipo di subentity .
Pertanto, esiste una corrispondenza (o cardinalità) di uno a uno (1: 1) in questi casi.
Come sai dai tuoi post precedenti, l' attributo discriminatore (colonna, quando implementato) svolge un ruolo fondamentale durante la creazione di un'associazione di questo tipo, poiché indica l'istanza del sottotipo corretta con cui è collegato il supertipo . Anche la migrazione del PRIMARY KEY da (i) il supertipo a (ii) i sottotipi è di primaria importanza.
Struttura DDL in cemento
E poi ho scritto una struttura DDL basata sul modello logico presentato sopra:
CREATE TABLE FooType -- Look-up table.
(
FooTypeCode CHAR(2) NOT NULL,
Description CHAR(90) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
CONSTRAINT PK_FooType PRIMARY KEY (FooTypeCode),
CONSTRAINT AK_FooType_Description UNIQUE (Description)
);
CREATE TABLE Foo -- Supertype
(
FooId INT NOT NULL, -- This PK migrates (1) to ‘Bar’ as ‘BarId’, (2) to ‘A’ as ‘AId’, (3) to ‘B’ as ‘BId’, and (4) to ‘C’ as ‘CId’.
FooTypeCode CHAR(2) NOT NULL, -- Discriminator column.
D INT NOT NULL, -- Column that applies to ‘Bar’ (and therefore to ‘A’ and ‘B’) and ‘C’.
CreatedDateTime DATETIME NOT NULL,
CONSTRAINT PK_Foo PRIMARY KEY (FooId),
CONSTRAINT FK_from_Foo_to_FooType FOREIGN KEY (FooTypeCode)
REFERENCES FooType (FooTypeCode)
);
CREATE TABLE BarType -- Look-up table.
(
BarTypeCode CHAR(1) NOT NULL,
Description CHAR(90) NOT NULL,
CONSTRAINT PK_BarType PRIMARY KEY (BarTypeCode),
CONSTRAINT AK_BarType_Description UNIQUE (Description)
);
CREATE TABLE Bar -- Subtype of ‘Foo’.
(
BarId INT NOT NULL, -- PK and FK.
BarTypeCode CHAR(1) NOT NULL, -- Discriminator column.
E INT NOT NULL, -- Column that applies to ‘A’ and ‘B’.
CONSTRAINT PK_Bar PRIMARY KEY (BarId),
CONSTRAINT FK_from_Bar_to_Foo FOREIGN KEY (BarId)
REFERENCES Foo (FooId),
CONSTRAINT FK_from_Bar_to_BarType FOREIGN KEY (BarTypeCode)
REFERENCES BarType (BarTypeCode)
);
CREATE TABLE A -- Subtype of ‘Bar’.
(
AId INT NOT NULL, -- PK and FK.
X INT NOT NULL, -- Particular column.
CONSTRAINT PK_A PRIMARY KEY (AId),
CONSTRAINT FK_from_A_to_Bar FOREIGN KEY (AId)
REFERENCES Bar (BarId)
);
CREATE TABLE B -- (1) Subtype of ‘Bar’ and (2) supertype of ‘A’ and ‘B’.
(
BId INT NOT NULL, -- PK and FK.
Y INT NOT NULL, -- Particular column.
CONSTRAINT PK_B PRIMARY KEY (BId),
CONSTRAINT FK_from_B_to_Bar FOREIGN KEY (BId)
REFERENCES Bar (BarId)
);
CREATE TABLE C -- Subtype of ‘Foo’.
(
CId INT NOT NULL, -- PK and FK.
Z INT NOT NULL, -- Particular column.
CONSTRAINT PK_C PRIMARY KEY (CId),
CONSTRAINT FK_from_C_to_Foo FOREIGN KEY (FooId)
REFERENCES Foo (FooId)
);
Con questa struttura si evita la memorizzazione di segni NULL nelle tabelle di base (o relazioni ), il che introdurrebbe ambiguità nel database.
Integrità, coerenza e altre considerazioni
Una volta implementato il database, è necessario assicurarsi che (a) ogni riga di supertipo esclusivo sia sempre integrata dalla corrispondente controparte del sottotipo e, a sua volta, garantire che (b) tale riga di sottotipo sia compatibile con il valore contenuto nella colonna del discriminatore di supertipo . Pertanto, è abbastanza conveniente utilizzare ACID TRANSACTIONS
per assicurarsi che queste condizioni siano soddisfatte nel database.
Non dovresti rinunciare alla solidità logica, all'espressività e all'accuratezza del tuo database, questi sono aspetti che rendono decisamente più solido il tuo database.
Le due risposte precedentemente pubblicate includono già punti pertinenti che vale sicuramente la pena prendere in considerazione durante la progettazione, la creazione e la gestione del database e dei suoi programmi applicativi.
Recupero dei dati tramite le definizioni VIEW
È possibile impostare alcune viste che combinano colonne dei diversi gruppi di sottotipi e sottotipi , in modo da poter recuperare i dati disponibili senza, ad esempio, scrivere le clausole JOIN necessarie ogni volta. In questo modo, puoi SELEZIONARE facilmente DALLA VISTA (una relazione derivata o una tabella ) di interesse.
Come puoi vedere, "Ted" Codd era, senza dubbio, un genio. Gli strumenti che ha lasciato in eredità sono piuttosto forti ed eleganti e, naturalmente, sono ben integrati tra loro.
Risorse correlate
Se desideri analizzare alcuni database estesi che coinvolgono relazioni tra sottotipi e sottotipi, troverai di valore le straordinarie risposte proposte da @PerformanceDBA alle seguenti domande di Stack Overflow:
Nota
1. Integration Definition for Information Modeling ( IDEF1X ) è una tecnica di modellazione dei dati altamente raccomandabile che è stata stabilita come standard nel dicembre 1993 dal National Institute of Standards and Technology ( NIST ) degli Stati Uniti . Si basa solidamente sul (a) materiale teorico iniziale creato dal Dr. EF Codd; su (b) la visione Entity-Relationship dei dati, sviluppata dal Dr. PP Chen ; e anche su (c) la tecnica di progettazione del database logico, creata da Robert G. Brown. Vale la pena notare che IDEF1X è stato formalizzato mediante la logica del primo ordine.