Supertipo / Sottotipo che decide tra le categorie: sovrapposizione completa disgiunta o incompleta


11

Sto creando un database di inventario che memorizza l'hardware IT, come computer desktop, laptop, switch, router, telefoni cellulari, ecc. Sto usando il modello supertipo / sottotipo, in cui tutti i dispositivi sono memorizzati in una singola tabella e informazioni specifiche viene inserito nelle tabelle dei sottotipi. Il mio dilemma è scegliere tra i seguenti due design:

inserisci qui la descrizione dell'immagine

Nel diagramma in alto tutti i dispositivi condividono sottotipi comuni. Ad esempio, i computer desktop e portatili presenterebbero record nelle seguenti tabelle: Dispositivo, NetworkDevice. Uno switch avrebbe record in: Device, NetworkDevice. Un router avrebbe record in: Dispositivo, NetworkDevice, WANDevice. Qualsiasi dispositivo per il quale tracciamo la posizione avrà un record in Posizione. Alcuni pro e contro che ho pensato per questa configurazione:

  • Pro: SELEZIONARE i record in base a un campo comune, come Nome host o LocationID è più semplice.
  • Pro: nessun campo nullo.
  • Contro: le tabelle che dovrebbero essere incluse nelle operazioni CRUD per un determinato dispositivo non sono ovvie e potrebbero confondere i DBA futuri.

Nel diagramma in basso tutti i dispositivi hanno il proprio sottotipo (ci sono più classi di dispositivi che non sono mostrate qui). In questa situazione, è ovvio da quali record di tabelle vengono inseriti o selezionati. Computer desktop e laptop vanno in Computer, ecc. Alcuni pro e contro che ho pensato per questa configurazione:

  • Pro: è immediatamente ovvio quali tabelle utilizzare per le operazioni CRUD per i sottotipi.
  • Pro: utilizzare solo una tabella per le operazioni CRUD.
  • Contro: SELEZIONARE i record in base ai campi dei sottotipi comuni richiede la combinazione di tutte le tabelle, ad esempio la ricerca per nome host o LocationID.

In entrambe le situazioni, il campo ClassDiscriminator viene inserito nelle tabelle dei sottotipi per l'uso con un vincolo CHECK per controllare quali tipi possono essere inseriti.

Ci sono raccomandazioni per quale design è migliore o è completamente una questione di opinione e dipende dallo scopo previsto del database?

EDIT: una domanda specifica che ho riguarda la natura sovrapposta della tabella "NetworkDevice". Questa tabella è destinata a contenere le informazioni di rete per qualsiasi dispositivo con un nome host e / o un indirizzo IP, sia esso un computer, uno switch o un router. La natura sovrapposta di questa tabella è qualcosa che potrebbe causare problemi o va bene implementarla in questo modo?

Grazie in anticipo per qualsiasi input fornito. Si prega di chiedere se sono necessarie ulteriori informazioni.


Vedi dba.stackexchange.com/questions/15199/… per una domanda simile a cui è stata data una risposta
Stephen Senkomago Musoke,

Risposte:


15

L'implementazione fisica del sottotipo in un database è un problema complesso. A meno che tu non abbia una situazione in cui offra vantaggi convincenti (vedi sotto per uno o due esempi) aggiunge complessità all'implementazione fornendo un valore relativamente basso.

Dopo averlo fatto con un sottotitolo davvero complesso (domande e sentenze su un sistema di gestione dei casi giudiziari, strutture di contratti assicurativi commerciali a rischio combinato disparati), credo di avere alcune osservazioni al riguardo. Alcuni casi angolari significativi sono:

  • Se il numero totale di campi di database tra i sottotipi è relativamente basso (diciamo: meno di 100) o c'è una comunanza significativa tra i sottotipi, la suddivisione dei sottotipi in tabelle fisiche separate è probabilmente di scarso valore. Aggiungerà un notevole sovraccarico alle query e alle ricerche dei rapporti. Nella maggior parte dei casi è meglio avere un'unica tabella e gestire il sottotipo all'interno dell'applicazione. (Probabilmente il più vicino al tuo problema)

  • Se il sottotipo è molto disgiunto e diversi sottotipi hanno strutture di dati dipendenti dal tipo che pendono (ad esempio tabelle figlio o strutture più complesse), allora le tabelle di sottotipo hanno senso. In questo caso, ogni sottotipo ha probabilmente relativamente poca comunanza all'interno dell'applicazione (vale a dire che esiste probabilmente un intero sottosistema all'interno dell'applicazione dedicato a quel sottotipo). La maggior parte dei report e delle query si verificherà probabilmente all'interno di un determinato sottotipo, con query tra tipi principalmente limitate a una manciata di campi comuni. (Sistema di gestione dei casi giudiziari)

  • Se hai un gran numero di sottotipi con attributi diversi e / o un requisito per renderlo configurabile, una struttura generica e metadati supplementari potrebbero essere più appropriati. Vedi questa pubblicazione SO per un riassunto di alcuni possibili approcci. (Sistema di amministrazione della polizza assicurativa)

  • Se hai un numero molto grande di campi con poca comunanza tra i tuoi sottotipi e pochi requisiti per eseguire query tra le tabelle dei sottotipi (vale a dire niente di più rispetto ai join esterni a più vie rispetto alle tue tabelle dei sottotipi), allora le tabelle dei tipi possono aiutare a gestire l'espansione della colonna. (Versione patologicamente complessa del tuo problema)

  • Alcuni mappatori O / R possono supportare solo un approccio particolare alla gestione delle sottoclassi.

Nella maggior parte dei casi, le tabelle dei sottotipi fisici in uno schema DB sono un po 'una soluzione alla ricerca di un problema, poiché potenzialmente hanno effetti collaterali indesiderati.

Nel tuo caso, suppongo che tu abbia un numero relativamente modesto di sottotipi e un numero gestibile di attributi. Il diagramma e la domanda non indicano alcuna intenzione di appendere tabelle figlio dai record. Suggerirei di prendere in considerazione la prima opzione suggerita sopra e di mantenere una tabella e gestire la sotto-digitazione all'interno dell'applicazione.


Grazie per la tua risposta dettagliata. Inizialmente volevo mantenere tutto in una tabella, ma alcuni campi per i dispositivi non si applicano ad altri e finirei con un mucchio di campi nulli. Ad esempio, tutti i record di inventario avrebbero campi per tipo di circuito e fornitore di servizi specifici per i router. Tutti i record avrebbero anche un campo del numero di telefono che non ha senso a meno che il dispositivo non sia un telefono. Qualche suggerimento su come gestirlo?
TheSecretSquad

2
@reallythecrash - L'overhead per i campi nullable è di circa un byte per campo, quindi in termini di utilizzo delle risorse è molto meno overhead rispetto all'unione con le tabelle delle sottoclassi. L'unico inconveniente è che la tabella apparirà un po 'disordinata con molti null.
Preoccupato di

3
@reallythecrash - Se vuoi davvero (e il tuo DBMS lo supporta - non hai specificato cosa stai usando) potresti impostare vincoli di controllo basati sul discriminatore del tipo che impone null / not-null sui campi appropriati per il classe.
Preoccupato di

3

Considerare innanzitutto lo sviluppo di un solido modello di dati logici utilizzando le regole della gerarchia di classificazione dei modelli di dati presenti in Enterprise Model Patterns , un libro di David Hay. Quando si crea una gerarchia di classificazione, ogni occorrenza (riga) deve essere di uno e solo un sottotipo. Ciò significa che i sottotipi si escludono a vicenda. La classificazione deve basarsi su una caratteristica unica, fondamentale e immutabile. L'uso di questa regola di base fornirà molta chiarezza al tuo modello. Nel modello che hai, l'unica caratteristica su cui classificare è lo scopo del dispositivo: un telefono, uno switch di rete, un computer, un router, ecc. Ogni dispositivo deve essere di uno e solo uno di questi tipi. Ad esempio, la posizione non sarebbe un sottotipo. Attributi come l'indirizzo IP appartengono al super tipo.

Penso che scoprirai che il numero di tipi di dispositivi sarà abbastanza grande da giustificare un modello EAV come menzionato in un'altra risposta. Il libro di David Hay a cui faccio riferimento copre questo modello in modo molto efficace. Tuttavia, se il numero di sottotipi è limitato, è possibile stabilire una regola empirica per decidere di implementare solo una tabella di super tipi con molte colonne nullable, solo tabelle di sottotipi con colonne duplicate o entrambe. Se ogni sottotipo varia notevolmente nei suoi attributi e non ha relazioni a livello di super-tipo, è possibile utilizzare solo le tabelle dei sottotipi. Se è vero il contrario, potresti usare solo tabelle di super-tipi. Se esiste un mix, implementa entrambi.

Nota infine che puoi sempre implementare un modello EAV come uno schema di tabella di base e quindi creare un livello di astrazione della vista che presenta i dati all'applicazione come tabelle di super e sottotipi. Ciò offre flessibilità a livello di archiviazione ma capacità di comprensione a livello di visualizzazione dell'applicazione.


Grazie per l'informazione Todd. Una delle domande che ho riguarda la tabella "Dispositivo di rete". Tale tabella è destinata a contenere record per qualsiasi dispositivo che abbia un nome host e un indirizzo IP. Ciò significa che switch, computer e router avrebbero tutti i dati relativi alla rete memorizzati in quella tabella. Da quello che ho letto questo è chiamato un sottotipo sovrapposto in cui la tabella dei sottotipi contiene dati correlati per più di un tipo. Sai se questo è qualcosa che dovrebbe essere evitato o se sto bene implementando in questo modo?
TheSecretSquad

Todd, per quanto riguarda la tua affermazione "crea un livello di astrazione della vista che presenta i dati all'applicazione ...". Sembra un'ottima idea. Ho pensato di usare le viste esattamente come hai descritto, ma avevo alcune domande a riguardo. So che va bene usare le viste per interrogare e visualizzare i dati nella mia applicazione, ma è pratica comune usare le viste per inserti e aggiornamenti? So che ci sono alcune restrizioni su come le tue query devono essere strutturate (nessuna clausola di ordine per, ecc.) Per inserire / aggiornare usando una vista. Se la query è strutturata correttamente, è consigliabile utilizzare la vista per inserti e aggiornamenti?
TheSecretSquad

Nella mia esperienza i sottotipi sovrapposti confondono le cose a livello logico, motivo per cui stavo raccomandando di tornare prima a sviluppare un modello logico completo. È possibile utilizzare LDM per chiarire l'ambito e la comprensione prima di occuparsi dell'archiviazione. Nel modello attuale presentato, c'è una certa confusione di comprensione tra la natura fondamentale di una cosa - un dispositivo - e dove quel dispositivo vive nello spazio. Chiarire ciò nel LDM. Evita anche il sottotipo sovrapposto nel database fisico, a meno che non lo utilizzi per partizionare verticalmente le colonne, nel qual caso non sta scrivendo affatto.
Todd Everett,

Per quanto riguarda il livello di astrazione, è possibile utilizzare un trigger "anziché" per rendere aggiornabile una vista. Le restrizioni menzionate (nessun ordine per) sono restrizioni nella vista SQL stessa e non nel suo utilizzo. Per l'inserimento / l'aggiornamento non è comunque possibile ordinare. Altre opzioni che hai sono scrivere un modulo per gestire i dettagli dell'inserto / aggiornamento o scrivere una procedura memorizzata per gestirlo. Non vedo alcun problema nell'utilizzare nessuno di questi metodi poiché le prestazioni sono accettabili. Per le scritture di tipo singleton dovrebbe andare bene. Gli aggiornamenti di massa potrebbero essere un problema.
Todd Everett,

2

Un prodotto non è un inventario. Inventario e prodotti sono distinti.

Un prodotto è in realtà una specifica di un prodotto, non una cosa fisica.

La cosa fisica è un bene che la società possiede (o negozi). Puoi avere risorse che segui per numero seriale (risorse discrete) o risorse che segui solo per quantità (risorse di inventario).

Vorrei dare un'occhiata al volume di dati sul modello di dati di Silverston Vol 1. Ha un buon schema per orgogliosi, funzionalità, prezzi, inventario. Ti farà risparmiare un sacco di tempo.


1
+1 punto per menzionare il Data Book Resource Book di Silverston. Ho dato un'occhiata ed è stato illuminante. Non vedo l'ora di leggere più in dettaglio, come penso che chiunque abbia domande sulla modellazione dei dati dovrebbe. Grazie.
TheSecretSquad

0

Una delle domande che vorrei porre è perché stai monitorando i vari attributi dei tuoi articoli di inventario? - O, più specificamente, cosa stai facendo con queste informazioni sugli attributi?

Se si dispone di molti report o moduli che hanno un significato specifico di attributi particolari, è necessario utilizzare l'approccio consigliato da ConcernedOfTunbridgeWell. Se, d'altra parte, questi attributi vengono registrati al fine di elencarli o eventualmente di confrontarli con attributi simili di dispositivi simili, allora potresti effettivamente avere una (rara) buona scusa per usare EAV. So che "EAV è puro male" per molte ragioni, ad eccezione di casi molto rari in cui tali ragioni non sono importanti per un'applicazione specifica. La tua potrebbe essere una tale applicazione.

Dai un'occhiata a questa risposta per quanto riguarda la progettazione di un sistema di inventario dei dispositivi e questa risposta per quanto riguarda la progettazione di un sistema di catalogo prodotti per vedere come un approccio EAV potrebbe semplificare la tua applicazione insieme a una discussione su quali siano esattamente i rischi di EAV e come giudicare se tali rischi potrebbero non essere applicabili alla propria specifica applicazione.


Grazie per il tuo contributo. Ho considerato EAV, ma pensavo di poter ottenere un modello abbastanza buono senza dover ricorrere alle complessità coinvolte con EAV.
TheSecretSquad
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.