Implementazione del sottotipo di un sottotipo nel modello di progettazione tipo / sottotipo con sottoclassi reciprocamente esclusive


20

introduzione

Affinché questa domanda sia utile per i futuri lettori userò il modello di dati generico per illustrare il problema che devo affrontare.

Il nostro modello di dati è composto da 3 entità, che devono essere etichettate come A, Be C. Per semplificare le cose, tutti i loro attributi saranno di inttipo.

Entità Aha le seguenti caratteristiche: D, Ee X;

Entità Bha le seguenti caratteristiche: D, Ee Y;

L'entità Cha i seguenti attributi: De Z;

Poiché tutte le entità condividono un attributo comune D, ho deciso di applicare il tipo / sottotipo di progettazione.

Importante: le entità si escludono a vicenda! Ciò significa che l'entità è A o B o C.

Problema:

Entità Ae Bhanno ancora un altro attributo comune E, ma questo attributo non c'è nell'entità C.

Domanda:

Vorrei utilizzare le caratteristiche sopra descritte per ottimizzare ulteriormente il mio design, se possibile.

Ad essere sincero, non ho idea di come farlo, né dove iniziare a provare, quindi questo post.

Risposte:


6

Nella misura in cui questa domanda è una continuazione di La mia implementazione del modello di progettazione tipo / sottotipo (per sottoclassi reciprocamente esclusive) è corretta? , che è di per sé una continuazione di Non so come trasformare un'entità variabile in una tabella relazionale , vorrei chiedere: che cosa stai esattamente cercando di ottimizzare? Conservazione? Il modello a oggetti? Complessità della query? Prestazioni della query? Ci sono dei compromessi quando si ottimizza un aspetto rispetto a un altro poiché non è possibile ottimizzare tutti gli aspetti contemporaneamente.

Sono completamente d'accordo con i punti di Remus riguardanti:

  • Ci sono pro e contro per ogni approccio (cioè il sempre presente fattore "dipende"), e
  • La prima priorità è l'efficienza del modello di dati (un modello di dati inefficiente non può essere corretto con un codice app pulito e / o efficiente)

Detto questo, la scelta che affronti è tra le seguenti, disposte in ordine dalla meno normalizzazione alla maggior parte della normalizzazione:

  • promozione della proprietà Enella tabella di tipo base
  • mantenendolo in più tabelle di sottotipi
  • normalizzare completamente Everso una nuova tabella di sottoclasse intermedia, allo stesso livello di quella C, Ae Bsarà direttamente sottoclasse di ( risposta di @MCCCCL )

Diamo un'occhiata a ciascuna opzione:

Sposta la proprietà Enella tabella di tipo base

Professionisti

  • La complessità della query ridotta per le query che necessità E, ma non X, Y, o Z.
  • Potenzialmente più efficiente per le query che necessità E, ma non X, Yo Z(query particolare aggregato) a causa di non aderire.
  • Potenziale di creazione di un indice su (D, E)(e in tal caso, potenzialmente un indice filtrato su (D, E)dove EntityType <> C, se tale condizione è consentita)

Svantaggi

  • Impossibile contrassegnare EcomeNOT NULL
  • Hai bisogno di extra CHECK CONSTRAINTsulla tabella dei tipi di base per assicurarti che E IS NULLquando EntityType = C(anche se questo non è un grosso problema)
  • È necessario educare gli utenti del modello di dati sui motivi per cui Edevono essere NULLe devono essere ignorati del tutto, quando EntityType = C.
  • Leggermente meno efficiente quando si Etratta di un tipo a lunghezza fissa e gran parte delle righe sono per EntityType di C(ovvero non si utilizza Equindi è NULL) e non si utilizza né l' SPARSEopzione sulla colonna né Compressione dati nell'indice cluster
  • Potenzialmente meno efficiente per le query che non sono necessarie in Equanto la presenza di Enella tabella dei tipi di base aumenterà la dimensione di ogni riga che a sua volta diminuisce il numero di righe che possono rientrare in una pagina di dati. Ma questo dipende fortemente dal tipo di dati esatto di E, FILLFACTOR, dal numero di righe nella tabella del tipo di base, ecc.

Mantenere la proprietà Ein ciascuna tabella dei sottotipi

Professionisti

  • Modello di dati più pulito (ovvero non devi preoccuparti di educare gli altri sul perché la colonna Enella tabella dei tipi di base non dovrebbe essere utilizzata perché "non è davvero lì")
  • Probabilmente assomiglia più da vicino al modello a oggetti
  • Può contrassegnare la colonna come NOT NULLse fosse una proprietà obbligatoria dell'entità
  • Non è necessario alcun extra CHECK CONSTRAINTsulla tabella dei tipi di base per garantire che E IS NULLquando EntityType = C(sebbene questo non sia un guadagno enorme)

Svantaggi

  • Richiede JOIN per sottotipo di tabella (s) per ottenere questa proprietà
  • Potenzialmente leggermente meno efficiente quando necessario E, a causa del JOIN, a seconda di quante righe di A+ Bhai rispetto a quante righe Cci sono.
  • Leggermente più difficile / complesso per le operazioni che riguardano esclusivamente entità Ae B(e non C ) lo stesso "tipo". Ovviamente, potresti astrarre questo tramite una vista che fa UNION ALLtra una SELECTdelle tabelle JOINed Ae un'altra SELECTdelle tabelle JOINed per B. Ciò ridurrà la complessità delle query SELECT ma non sarà così utile INSERTe per le UPDATEquery.
  • A seconda delle query specifiche e della frequenza con cui vengono eseguite, questa potrebbe essere una potenziale inefficienza nei casi in cui avere un indice (D, E)attivo aiuterebbe davvero una o più query utilizzate di frequente, poiché non possono essere indicizzate insieme.

Normalizza Ealla tabella intermedia tra la classe base e A&B

(Nota che mi piace la risposta di @ MDCCL come alternativa praticabile, a seconda delle circostanze. Quanto segue non è inteso come una critica rigorosa a tale approccio, ma come mezzo per aggiungere alcune prospettive - la mia, ovviamente - valutando nello stesso contesto delle due opzioni che avevo già proposto. Ciò renderà più facile chiarire ciò che vedo come la differenza relativa tra la piena normalizzazione e l'attuale approccio della normalizzazione parziale.)

Professionisti

  • il modello di dati è completamente normalizzato (non può esserci nulla di intrinsecamente sbagliato in questo, dato che è ciò che RDBMS è progettato per fare)
  • ridotta complessità delle query per le query che richiedono Ae B, ma non C(ovvero nessuna necessità di due query unite tramite UNION ALL)

Svantaggi

  • occupa leggermente più spazio (la Bartabella duplica l'ID e c'è una nuova colonna BarTypeCode) [trascurabile, ma qualcosa di cui essere consapevoli]
  • leggero aumento della complessità della query in quanto JOINè necessario un ulteriore per accedere a AoB
  • maggiore superficie per il blocco, principalmente attiva INSERT( DELETEpuò essere gestita in modo implicito contrassegnando le chiavi esterne come ON CASCADE DELETE) poiché la transazione verrà mantenuta aperta leggermente più a lungo sul tavolo della classe base (ovvero Foo) [trascurabile, ma qualcosa di cui tenere conto]
  • nessuna conoscenza diretta del tipo effettivo - Ao B- all'interno della tabella della classe base Foo; conosce solo tipi Brche possono essere Ao B:

    Significato, se è necessario eseguire query sulle informazioni di base generali ma è necessario classificare in base al tipo di entità o filtrare uno o più tipi di entità, la tabella della classe di base non dispone di informazioni sufficienti, nel qual caso è necessario LEFT JOINil Bartavolo. Ciò ridurrà anche l'efficacia dell'indicizzazione della FooTypeCodecolonna.

  • nessun approccio coerente all'interazione con A& Bvs C:

    Ciò significa che se ogni entità si collega direttamente alla tabella della classe base in modo tale che esiste un solo JOIN per ottenere l'entità completa, allora tutti possono acquisire familiarità più rapidamente e facilmente in termini di lavoro con il modello di dati. Ci sarà un approccio comune alle query / Stored procedure che le renderà più veloci da sviluppare e con meno probabilità di avere bug. Un approccio coerente rende inoltre più semplice e veloce l'aggiunta di nuovi sottotipi in futuro.

  • potenzialmente meno adattabile alle regole aziendali che cambiano nel tempo:

    Significato, le cose cambiano sempre ed è abbastanza facile passare Ealla tabella della classe base se diventa comune a tutti i sottotipi. È anche abbastanza facile spostare una proprietà comune fuori dai sottotipi se i cambiamenti nella natura delle entità rendono tale cambiamento utile. È abbastanza semplice suddividere un sottotipo in due sottotipi (basta creare un altro SubTypeIDvalore) o combinare due o più sottotipi in uno. Al contrario, cosa succederebbe se in Eseguito diventasse una proprietà comune di tutti i sottotipi? Quindi lo strato intermedio della Bartabella sarebbe privo di significato e la complessità aggiunta non varrebbe la pena. Certo, è impossibile sapere se un tale cambiamento avverrebbe tra 5 o anche 10 anni, quindi la Bartabella non è necessariamente, e neppure altamente probabile che sia una cattiva idea (motivo per cui ho detto " potenzialmente meno adattabile"). Questi sono solo punti da considerare; è una scommessa in entrambe le direzioni.

  • raggruppamento potenzialmente inappropriato:

    Significato, solo perché la Eproprietà è condivisa tra i tipi di entità Ae Bnon significa che Ae B dovrebbero essere raggruppati insieme. Solo perché le cose "sembrano" uguali (cioè stesse proprietà) non significa che siano uguali.

Sommario

Proprio come decidere se / quando denormalizzare, come affrontare al meglio questa particolare situazione dipende dal considerare i seguenti aspetti dell'uso del modello di dati e assicurarsi che i benefici superino i costi:

  • quante righe avrai per ogni EntityType (guarda almeno 5 anni lungo la strada, ipotizzando una crescita superiore alla media)
  • quanti GB ciascuna di queste tabelle (tipo di base e sottotipi) sarà tra 5 anni?
  • quale tipo di dati specifico è proprietà E
  • è solo una proprietà o ce ne sono poche o addirittura diverse
  • quali domande ti occorrono Ee con quale frequenza verranno eseguite
  • quali domande avrai bisogno di quelle che non ti servono Ee con quale frequenza verranno eseguite

Penso di tendere di default a mantenere Ele tabelle dei sottotipi separate perché è, almeno, "più pulito". Vorrei considerare di passare Ealla tabella dei tipi di base IF: la maggior parte delle righe non erano per EntityType di C; e il numero di righe era almeno in milioni; e il più delle volte ho eseguito query che necessitavano Ee / o le query che avrebbero beneficiato di un indice in caso di (D, E)esecuzione molto frequente e / o richiedono risorse di sistema sufficienti in modo tale che avere l'indice riduca l'utilizzo complessivo delle risorse, o almeno prevenga picchi di consumo di risorse che superano livelli accettabili o durano abbastanza a lungo da causare blocchi eccessivi e / o aumenti dei deadlock.


AGGIORNARE

OP ha commentato questa risposta che:

I miei datori di lavoro hanno cambiato la logica aziendale, rimuovendo del tutto E!

Questa modifica è particolarmente importante perché è esattamente quello che ho predetto potrebbe accadere nella sottosezione "CON" della precedente sezione "Normalizza Everso la tabella intermedia tra la classe base e A& B" (6 ° punto). Il problema specifico è quanto sia facile / difficile riformattare il modello di dati quando si verificano tali cambiamenti (e lo fanno sempre). Alcuni sosterranno che qualsiasi modello di dati può essere refactored / modificato, quindi inizia con l'ideale. Ma mentre è vero a livello tecnico che qualsiasi cosa può essere riformulata, la realtà della situazione è una questione di scala.

Le risorse non sono infinite, non solo CPU / Disco / RAM, ma anche risorse di sviluppo: tempo e denaro. Le aziende stabiliscono costantemente priorità sui progetti perché tali risorse sono molto limitate. E abbastanza spesso (almeno nella mia esperienza), i progetti per ottenere efficienza (sia le prestazioni del sistema sia lo sviluppo più rapido / meno bug) sono prioritari rispetto ai progetti che aumentano la funzionalità. Mentre è frustrante per noi tecnici perché comprendiamo quali sono i vantaggi a lungo termine dei progetti di refactoring, è proprio la natura del business che i meno tecnici, i professionisti hanno un tempo più facile a vedere il rapporto diretto tra nuove funzionalità e nuove reddito. Ciò che si riduce è: "torneremo per risolvere il problema in seguito" == "

Tenendo presente ciò, se la dimensione dei dati è abbastanza piccola da consentire una modifica delle query e / o si dispone di una finestra di manutenzione che è abbastanza lunga da non solo apportare le modifiche, ma anche di ripristinare se qualcosa va sbagliato, quindi la normalizzazione Ein una tabella intermedia tra la tabella della classe di base e le tabelle della sottoclasse A& Bpotrebbe funzionare (sebbene ciò non ti lasci ancora una conoscenza diretta del tipo specifico ( AoB) nella tabella della classe base). MA, se ci sono centinaia di milioni di righe in queste tabelle e un'incredibile quantità di codice che fa riferimento alle tabelle (codice che deve essere testato quando vengono apportate modifiche), di solito paga essere più pragmatico che idealistico. E questo è l'ambiente che ho dovuto affrontare per anni: 987 milioni di righe e 615 GB nella tabella di classe base, distribuita su 18 server. E così tanto codice ha colpito queste tabelle (tabelle di classe base e sottoclasse) che c'era molta resistenza - principalmente dalla direzione ma a volte dal resto del team - ad apportare modifiche a causa della quantità di sviluppo e Risorse di QA che dovrebbero essere allocate.

Quindi, ancora una volta, l'approccio "migliore" può essere determinato solo situazione per situazione: è necessario conoscere il proprio sistema (ovvero quanti dati e come tutte le tabelle e il codice sono collegati), come realizzare il refactoring e le persone con cui lavori (il tuo team e possibilmente il management - puoi ottenere il loro buy-in per un tale progetto?). Ci sono alcuni cambiamenti che ho menzionato e pianificato da 1 a 2 anni e che ho richiesto più sprint / release per implementare forse l'85% di essi. Ma se hai solo <1 milione di righe e non molto codice legato a queste tabelle, allora probabilmente sei in grado di iniziare dal lato più ideale / "puro" delle cose.

Ricorda, in qualunque modo tu scelga di andare, presta attenzione a come funziona quel modello almeno nei prossimi 2 anni (se possibile). Presta attenzione a ciò che ha funzionato e a ciò che ha causato dolore, anche se all'epoca sembrava l'idea più grande (il che significa che devi anche permetterti di accettare di sbagliare - lo facciamo tutti - in modo da poter valutare onestamente i punti di dolore ). E presta attenzione al motivo per cui determinate decisioni hanno funzionato o meno in modo da poter prendere decisioni che hanno maggiori probabilità di essere "migliori" la prossima volta :-).


17

Secondo Martin Fowler, ci sono 3 approcci al problema dell'ereditarietà delle tabelle:

  • Ereditarietà di una singola tabella : una tabella rappresenta tutti i tipi. Gli attributi non utilizzati sono NULLed.
  • Eredità di tabella concreta : una tabella per tipo di calcestruzzo, ciascuna colonna di tabella per ogni attributo del tipo. Nessuna relazione tra le tabelle.
  • Ereditarietà delle tabelle di classe : una tabella per tipo, ogni tabella ha attributi solo per attributi nuovi, non ereditati. Le tabelle sono correlate in base alla gerarchia dell'ereditarietà del tipo effettivo.

Puoi iniziare con questi come punto di partenza per cercare vantaggi e svantaggi di ciascun approccio. L'essenza di ciò è che tutti gli approcci presentano grandi svantaggi e nessuno ha alcun vantaggio schiacciante. Meglio conosciuto come disadattamento dell'impedenza relazionale dell'oggetto , questo problema deve ancora trovare una soluzione.

Personalmente trovo che il tipo di problemi che può portare a una cattiva progettazione relazionale siano ordini di grandezza più gravi del tipo di problemi derivanti da una cattiva progettazione di tipo . Una cattiva progettazione del database porta a query lente, anomalie di aggiornamento, esplosione delle dimensioni dei dati, deadlock e app non rispondenti e decine di centinaia di Gigabyte di dati affondati nel formato sbagliato . Una cattiva progettazione del tipo comporta difficoltà a mantenere e aggiornare il codice , non il runtime. Pertanto, nel mio libro, la corretta progettazione relazionale supera ogni volta la purezza del tipo di OO.


@AlwaysLearningNewStuff Penso che questa domanda sia un follow-up su dba.stackexchange.com/questions/139092 , giusto? Nell'implementazione lì si fare avere ereditarietà delle tabelle.
Remus Rusanu,

Sì, prima di porre questa domanda volevo assicurarmi di aver capito bene come implementare prima il design del tipo / sottotipo. Ora devo affrontare il problema sopra descritto quando alcune sottoclassi (ma non tutte!) Hanno attributi condivisi. Mi chiedevo se c'è qualcosa che posso fare per ottimizzare il modello di dati in quel caso, invece di ignorare quella sfumatura ...
AlwaysLearningNewStuff

6

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 Fooe 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 ):

Figura 1 - Modello di dati ipotetici tra i sottotipi e i sottotipi

L'aggiunta di Foo and Bar

Non ho aggiunto Fooe Barper rendere il modello migliore, ma per renderlo più espressivo. Ritengo che siano importanti a causa di quanto segue:

  • Poiché Ae Bcondividono 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 Bartipo di superentity che, a sua volta, è un tipo di subentity di Foo, che contiene l' Dattributo nella parte superiore della gerarchia.

  • Poiché Ccondivide solo un attributo con il resto dei tipi di entità in discussione, vale a dire, Dquesto 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 Footipo 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 TRANSACTIONSper 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.


I miei datori di lavoro hanno cambiato la logica aziendale, rimuovendoli del Etutto! La ragione per accettare la risposta dell'utente srutzky è perché fornisce buoni punti che mi aiutano a prendere la mia decisione di scegliere il percorso più efficiente. Se non fosse per questo accetterei la tua risposta. Ho votato prima la tua risposta. Grazie ancora!
AlwaysLearningNewStuff,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.