Domanda

Il mio datore di lavoro, una piccola azienda di forniture per ufficio, è cambiando fornitori e non vedo attraverso il loro contenuto elettronico a venire con uno schema di database robusto; il nostro schema precedente era praticamente appena gettato insieme senza alcun pensiero a tutti, ed è praticamente portato ad un modello di dati insopportabile con corrotti, informazioni contraddittorie.

I dati del nuovo fornitore è molto meglio di quello vecchio di, ma i loro dati è quello che chiamerei hypernormalized . Ad esempio, la loro struttura categoria di prodotto ha 5 livelli: Maestro, Dipartimento, classe, sottoclasse, blocco del prodotto. Inoltre, il contenuto di blocco prodotto ha la descrizione lunga, termini di ricerca e nomi di immagine per i prodotti (l'idea è che un blocco prodotto contiene un prodotto e tutte le variazioni - per esempio una particolare penna potrebbe venire in inchiostro nero, blu o rosso; tutti questi articoli sono essenzialmente la stessa cosa, quindi applicabili ad un blocco unico prodotto). Nei dati mi è stata data, questo è espressa come la tavola prodotti (dico "tavolo", ma si tratta di un file flat con i dati) con un riferimento ID univoco del blocco del prodotto.

Sto cercando di venire con uno schema robusto per contenere i dati che sto dotato, dal momento che avrò bisogno di caricarlo relativamente presto, ei dati che mi hanno dato non sembra corrispondere al tipo dei dati che forniscono per la dimostrazione sul loro sito web del campione ( http://www.iteminfo.com ). In ogni caso, non sto cercando di riutilizzare la struttura di presentazione, quindi è un punto controverso, ma stavo dando un'occhiata al sito per avere alcune idee su come strutturare le cose.

Quello che io sono sicuro di è se o non dovrei conservare i dati in questo formato, o per esempio consolidare master / Dipartimento / Classe / Sottoclasse in un'unica tabella "Categorie", utilizzando una relazione autoreferenziale, e il collegamento che a un blocco prodotto (blocco prodotto deve essere tenuto separato in quanto non è una "categoria" in quanto tale, ma un gruppo di prodotti correlati per una data categoria). Attualmente, la tabella di blocchi di prodotto fa riferimento alla tabella sottoclasse, quindi questo cambierebbe in "category_id" se io consolidare insieme.

Io probabilmente ad essere la creazione di un negozio di e-commerce facendo uso di questi dati con Ruby on Rails (o questo è il mio piano, in ogni caso), quindi sto cercando di evitare di essere portato a casa più tardi o avere un'applicazione gonfio - forse sto dando troppo pensiero, ma preferirei essere sicuri che dispiaciuti; i nostri dati precedenti è stato un vero disastro e costano decine di società di migliaia di dollari in vendite perse a causa di dati incoerenti e imprecise. Inoltre ho intenzione di rompere con le convenzioni Rails un po 'facendo in modo che il mio database è robusto e fa rispettare i vincoli (ho intenzione di farlo a livello di applicazione, anche), di modo che è qualcosa che ho bisogno di prendere in considerazione pure.

Come vorresti affrontare una situazione come questa? Tenete a mente che non ho i dati da caricare già nel file flat che simulano una struttura di tabella (ho detto di documentazione che le colonne sono che e quali riferimenti sono impostati); Sto cercando di decidere se devo tenerli come normalizzata in quanto attualmente sono, o se devo cercare di consolidare; Ho bisogno di essere consapevoli di come ogni metodo influenzerà il modo in cui programmare il sito utilizzando Rails poiché se io consolidare, ci saranno essenzialmente 4 "livelli" di categorie in una singola tabella, ma che sembra decisamente più gestibile rispetto alle tabelle separate per ogni livello, poiché, a parte sottoclasse (che si collega direttamente ai blocchi di prodotto) non do nulla, se non mostrare il prossimo livello di categoria sotto di loro. Sono sempre una perdita per il modo "migliore" per gestire i dati come questo -. So che il detto "normalizzare fino a soffrire, allora denormalizzare fino a quando non funziona", ma non ho mai avuto per la sua attuazione fino ad ora

È stato utile?

Soluzione

Io preferirei l'approccio "hypernormalized" nel corso di un modello di dati denormal. La tabella di riferimento di sé che lei ha citato potrebbe ridurre il numero di tavoli giù e semplificare la vita in qualche modo, ma in generale questo tipo di rapporto può essere difficile da affrontare. query gerarchiche diventano un dolore, così come la mappatura di un modello a oggetti per questo (se si decide di seguire questa strada).

Un paio di più si unisce, non sta andando male e manterrà l'applicazione più gestibile. A meno che la prestazione diminuisce a causa del numero eccessivo di join, opterei per lasciare le cose come sono. Come bonus aggiuntivo se uno qualsiasi di questi livelli di tabelle necessarie funzionalità aggiuntive aggiunto, non sarà incorrere in problemi, perché tutti si fuse in tabella sé riferimento.

Altri suggerimenti

Sono completamente d'accordo con le critiche su strutture delle tabelle autoreferenziali per gerarchie padre-figlio. La struttura lista collegata rende più facile la programmazione dell'interfaccia utente e di business di livello e più gestibile nella maggior parte dei casi, dal momento che le liste collegate e gli alberi sono il modo naturale per rappresentare questi dati in lingue che l'interfaccia utente e di business strati sarebbero tipicamente essere attuate in.

La critica circa la difficoltà di mantenere vincoli di integrità dei dati su queste strutture è perfettamente valida, anche se la soluzione più semplice è quella di utilizzare una tabella di chiusura che ospita il più difficile controllare i vincoli. La tabella di chiusura è di facile manutenzione con i trigger.

Il compromesso è un po 'di complessità in più nel DB (tabella di chiusura e trigger) per molto meno complessità nella UI e lo strato di business codice.

Se ho capito bene, si vuole prendere loro tavoli separati e li trasformano in una gerarchia che è conservato in un unico tavolo con un'autoreferenziale FK.

Questo è generalmente un approccio più flessibile (ad esempio, se si desidera aggiungere un quinto livello), ma i modelli di dati SQL e relazionali non tendono a lavorare bene con liste collegate come questo, anche con la nuova sintassi del tipo MS SQL Server CTE. Certo, CTE rendono molto meglio però.

Può essere difficile e costoso per far rispettare le cose, come che un prodotto deve sempre essere al quarto livello della gerarchia, ecc.

Se si decide di farlo in questo modo, quindi sicuramente check out SQL di Joe Celko per Smarties , che credo abbia una sezione o due sulla modellazione e lavorare con le gerarchie in SQL o meglio ancora ottenere il suo libro che è dedicato al soggetto ( noreferrer Alberi e gerarchie di Joe Celko in SQL per Smarties ).

Normalization implica l'integrità dei dati, vale a dire:. Ogni forma normale riduce il numero di situazioni in cui i dati non è coerente

Come regola generale, denormalization ha un obiettivo di più veloce querying, ma porta ad una maggiore spazio, maggiore DML tempo, e, ultimo ma non meno importante, un maggiore impegno per rendere i dati coerenti.

Una solitamente scrive codice più veloce (scrive più veloce, non il codice più veloce) e il codice è meno soggetto a errori se i dati sono normalized.

Appartamenti riferimento a tabelle di girare quasi sempre per essere molto peggio per interrogare ed eseguire peggio di tabelle normalizzate. Non farlo. Può sembrare a voi di essere più elegante, ma non lo è ed è un pessimo tecnica di progettazione di database. Personalmente la struttura da te descritto suona bene a me non hypernormalized. Un database correttamente normalizzato (con i vincoli esteri chiave, nonché i valori di default, trigger (se necessario per le regole complesse) e dei vincoli di convalida dei dati) è anche molto più probabile di avere dati coerenti e precisi. Sono d'accordo di avere il database far rispettare le regole, probabilmente questo è parte del motivo per cui l'ultima applicazione doveva dati non validi perché le regole non sono state applicate nel posto giusto e le persone erano in grado di ottenere facilmente intorno a loro. Non che l'applicazione non dovrebbe controllare come bene (nessun punto anche l'invio di una data non valida, per esempio per la datbase a fallire su inserto). Dal youa riprogettazione, avrei messo più tempo e sforzo nella progettazione dei vincoli necessari e scegliendo i tipi di dati corretti (non memorizzare le date come i dati di stringa, per esempio), che nel tentativo di rendere la struttura normalizzata perfettamente normale aspetto più elegante.

Vorrei portarla in quanto più vicino al loro modello possibile (e se possibile, vorrei ottenere i file che corrispondono alla loro schema - non una versione appiattita). Se si mettono i dati direttamente nel modello, che cosa succede se i dati che inviano inizia a rompere le assunzioni nella trasformazione del modello dell'applicazione interna?

Meglio per portare i propri dati in, controlli di integrità correre e controllare che le assunzioni non siano violati. Poi, se si dispone di un modello specifico dell'applicazione, trasformarla in quella per un uso ottimale dalla vostra applicazione.

Non denormalizzare. Cercando di acheive un buon design dello schema denormalizing è come cercare di arrivare a San Francisco guidando lontano da New York. Non vi dice da che parte andare.

Nella tua situazione, si vuole capire che cosa uno schema normalizzato vorrebbe. È possibile basare che in gran parte lo schema di origine, ma è necessario imparare ciò che le dipendenze funzionali (FD) nei dati sono. Né lo schema di origine né le file appiattite sono garantiti per rivelare tutti i DF a voi.

Una volta che sapete che cosa uno schema normalizzato sarebbe simile, è ora necessario capire come progettare uno schema che soddisfi le vostre esigenze. E che schema è un po 'meno completamente normalizzata, così sia. Ma essere pronti per la difficoltà di programmare la trasformazione tra i dati nei file appiattite ei dati nello schema desgined.

Hai detto che i precedenti schemi a vostra azienda costano milioni a causa della inconsistenza e imprecisione. Il più normalizzato schema è, più protetto è da incoerenza interna. Questo lascia liberi di essere più vigilante circa inesattezza. dati coerenti che è costantemente sbagliato può essere fuorviante, in quanto i dati incoerenti.

è la tua vetrina virtuale (o quello che è si sta costruendo, non è molto chiaro su questo) sempre intenzione di utilizzare i dati da questa azienda? potrebbe mai cambiare fornitore o aggiungere ulteriori fornitori diversi?

in caso affermativo, di progettare uno schema generale che soddisfi tuoi le esigenze, e mappare i dati del fornitore ad essa. Personalmente preferirei subire la (incredibilmente minore) 'dolore' di una Categoria tavolo autoreferenziale (gerarchico) di mantenere quattro (apparentemente semi-inutile) livelli di Categoria varianti e poi l'anno prossimo scoprire che hanno aggiunto un 5 °, o introdotto una linea di prodotti con solo tre ...

Per me, la vera domanda è:? quello che si adatta meglio il modello

E 'come paragonare una tupla e un elenco.

  1. Le tuple sono una dimensione fissa e sono eterogenei -. Sono "hypernormalized"
  2. Elenchi sono di dimensioni arbitrarty e sono omogenei.

Io uso una tupla quando ho bisogno di una tupla e un elenco quando ho bisogno di una lista; hanno scopi fondamentalmente diverso server.

In questo caso, dal momento che il struttura del prodotto è già ben definito (e io non impegna destinata a cambiare) quindi vorrei rimanere con il "metodo Tuple". Il vero potere / uso di un elenco (o un motivo tabella ricorsiva) è quando ne avete bisogno di espandere per una profondità arbitraria, ad esempio per una distinta base o di un albero genealogico.

Io uso entrambi gli approcci in alcune delle mia base di dati a seconda della necessità. Tuttavia, v'è anche il "costo nascosto" di un modello ricorsivo che è che non tutti i ORM (non è sicuro su AR) sostenere bene. Molti DB moderni hanno il supporto per "join-through" (Oracle), ID gerarchia (SQL Server) o altri modelli ricorsivi. Un altro approccio è quello di utilizzare una gerarchia basata su set (che si basa generalmente su trigger / manutenzione). In ogni caso, se l'ORM utilizzato non supporta bene query ricorsive, allora ci può essere il "costo" extra di utilizzare il al DB caratteristiche direttamente - sia in termini di domanda / generazione di vista manuale o di gestione quali le clausole. Se non si utilizza un ORM funky, o semplicemente utilizzare un separatore di logica, come iBatis, quindi questo problema può anche non applicarsi.

Per quanto riguarda le prestazioni, il nuovo Oracle o SQL Server (e probabilmente altri) RDBMS, dovrebbe essere molto simile in modo che sarebbe l'ultima delle mie preoccupazioni: ma guarda che le soluzioni disponibili per le RDBMS e portabilità preoccupazioni.

Tutti coloro che raccomanda di non avere una gerarchia introdotta nel database, considerando solo la possibilità di avere un tavolo di auto-referenziato. Questo non è l'unico modo per modellare la gerarchia nel database. È possibile utilizzare un approccio diverso, che vi fornisce l'esecuzione di query più facile e veloce senza l'utilizzo di query ricorsive. Diciamo che avete un grande insieme di nodi (categorie) nella gerarchia:

  

Set1 = (Node1 Node2 Node3 ...)

Ogni nodo in questo set può anche essere un'altra serie di per sé, che contiene altri nodi o insiemi nidificati:

  

Nodo 1 = (nodo 2 Node3 = (Node4 Node5 = (Node6) Node7))

Ora, come possiamo modellare questo? Facciamo ogni nodo di avere due attributi, che fissano i confini dei nodi che esso contiene:

  

Node = {Id: int, Min: int, Max: int}

Per modellare nostra gerarchia, abbiamo solo assegnare tali valori min / max di conseguenza:

  

Nodo 1 = {Id = 1, Min = 1, Max = 10}
  Nodo2 = {Id = 2, Min = 2, Max = 2}
  Node3 = {Id = 3, Min = 3, Max = 9}
  Node4 = {Id = 4, Min = 4, Max = 4}
  Node5 = {Id = 5, Min = 5, Max = 7}
  Node6 = {Id = 6, Min = 6, Max = 6}
  Node7 = {Id = 7, Min = 8, Max = 8}

Ora, per interrogare tutti i nodi sotto il Set / Node5:

  

selezionare n. * Da nodi come n, nodi come s
  dove s.Id = 5 e s.Min

L'unica operazione in termini di risorse che consumano sarebbe se si desidera inserire un nuovo nodo, o spostare alcuni nodi all'interno della gerarchia, come molti record saranno interessati, ma questo va bene, come la gerarchia in sé non cambia molto spesso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top