2009-05-18 4 views
15

Ho molte tabelle che usano i riferimenti Lookup/Enum per la maggior parte dei loro valori di colonna. Ad esempio:
Tabella persone - PersonID | RaceCode | HairColorCode | HairStyleCode | TeethConditionCode
Tabella delle posizioni - LocationID | SizeCode | ExteriorColorCode | ConditionCode
Cose come Razza, Dimensione, Colore, Condizione, ecc. Sarebbero solo riferimenti a chiavi esterne a una tabella di ricerca del codice. Questa tabella di codici ha altri campi ma non è importante per la mia domanda. Il database è per un'applicazione SaaS, il che significa che ogni cliente può avere il proprio elenco di colori, razze, condizioni, ecc. Ci sono alcuni codici che sarebbero statici e che i client non potevano modificare.

E 'meglio avere 1 tavolo codice o 2 tipi di tabelle dei codici (DynamicCodeTable per i più definito dei clienti e StaticCodeTable per coloro che un cambio) o dovrei avere una tabella per ogni tipo di codice (RaceCodeTable, HairColorTable, Condizione, eccetera) ?

La cosa che mi preoccupa di più è l'unione di SQL. La tabella Persona con cui lavoro ha oltre 20 di questi attributi di codice. C'è una differenza nelle prestazioni quando si uniscono a 20 tavoli diversi che si uniscono alla stessa tabella 20 volte? Avere più tabelle significa che ogni tabella sarebbe più piccola e la ricerca "dovrebbe" richiedere meno tempo. Ma avere un solo tavolo potrebbe essere anche veloce. Eventuali suggerimenti?Progettazione database: tabelle Ricerca/Enum multiple o una tabella grande?

risposta

13

Senza ulteriori informazioni sull'applicazione o sui requisiti, si consiglia di disporre di una tabella per ogni tipo di codice. IMO la progettazione del database sarebbe più chiara e autodocumentante per avere chiavi esterne per ogni tipo di codice che hai.

0

Ho fatto un errore nel pensare che tutte queste tabelle di ricerca sarebbero state una grande idea quando si ridisegnavano i nostri tavoli piuttosto ampi. Tanta flessibilità, ecc. Ma alla fine è diventato molto più difficile da codificare, era impossibile spostarsi, ed era solo un rompicapo.

Quindi cosa ho imparato?

  • per valori statici, basta usare un enum: è molto più veloce e più conveniente. Questa decisione deve essere presa in base a quante altre tabelle possono fare riferimento alla stessa variabile.
  • bastone con un numero minore di tabelle di ricerca anziché creare quante più immagini possibili. I JOIN sono molto più lenti.
  • per aiutare te stesso a navigare in giro, progettazione VIEW database. Renderà la tua vita molto più facile.
  • come bonus, se non si desidera che i client tocchino determinate tabelle (ad esempio quelle statiche) o toccando i valori della colonna enum, è possibile utilizzare le autorizzazioni a granularità di MySQL (ad esempio) per disabilitare le modifiche a determinate colonne in alcune tabelle. Un sacco di gente non si rende conto di quanto queste autorizzazioni possano essere flessibili.
+1

La mia lamentela con questo: se si usa solo enumerazioni, poi sono parte di un solo vostra applicazione. Ciò significa 1) è necessario rilasciare una nuova versione ogni volta che qualcosa nei valori di ricerca cambia e 2) non si ha alcun modo sul database per imporre l'integrità (o si deve "kludge" muoversi con vincoli CHECK disordinati). Pertanto, direi di utilizzare le tabelle di ricerca per TUTTI i valori di ricerca oltre a un campo vero/falso. –

+1

Oppure definire le tabelle di ricerca, con integrità referenziale come di consueto, ma generare le definizioni enum dal database. In questo modo programmi contro l'enumerazione e corrispondono al DB. – GalacticCowboy

0

C'è una potenziale differenza di prestazioni.

Una tabella con solo 2 righe lega un sacco di spazio nella cache per quelle due righe minuscole.

Se si dispone di molti valori di ricerca in una singola tabella, si impacchettano questi valori in modo più denso nella cache.

+1

Ogni tabella di ricerca sarebbe più grande di quella. Ogni cliente può avere il proprio set di codici HairColor. Quindi, ogni cliente potrebbe avere i propri 10 colori, 10 condizioni, 10 dimensioni. La domanda è: metto questi 30 codici in una tabella o in tre? Questi numeri sono per un cliente, e idealmente ne avremmo molti. Quindi un centinaio di clienti potrebbero avere il proprio set di 10 codici per ciascun attributo. – Vyrotek

+0

Non sono affatto d'accordo - se una tabella ha solo due colonne, ad esempio id e valore, allora molte più righe si adatteranno a qualsiasi pagina 8k. Non vedo come sprecheresti la memoria in quel modo. Direi che è un progetto più pulito, più "individuabile" per avere tabelle di ricerca distinte e distinte, in particolare per i valori di ricerca che potrebbero cambiare tra le versioni o che devono essere modificati dall'utente finale in un dato momento. –

+1

@marc_s: molte righe "possono" adattarsi a una pagina 8k. Se hai solo due righe nella ricerca, quelle due righe si trovano su quella pagina, insieme a NULLA altro. Sprecare efficacemente un sacco di spazio nella cache. –

24

Questo argomento è stato ampiamente discusso negli ultimi quindici anni, sotto l'argomento "One True Lookup Table" (abbreviato OTLT). I vantaggi di tale approccio saltano fuori dal novizio del database. Gli svantaggi emergono nel tempo. Vedere questi collegamenti per svantaggi OTLT:

O search per OTLT di trovare più discussioni.

Se si creano molte tabelle di ricerca e molte schermate di manutenzione per loro, è possibile creare una vista che simula l'OTLT creando un UNION gigantesco che include ogni codice, ogni descrizione e il nome della tabella in cui il codice- la coppia di descrizione è memorizzata. È possibile generare tale unione usando metodi semiautomatici, se sai cosa stai facendo. Immagino che i metodi semiautomatici ti permettano di costruire una singola schermata di manutenzione per centinaia di tabelle di ricerca, e quindi mettere un po 'di logica tra quella schermata e le tabelle che inseriscono un nuovo codice nella tabella corretta.

Come lasciare che gli utenti introducano nuovi TIPI di codice, e non solo nuovi VALORI di codice, che aprano un'intera grande quantità di worm. Vedi l'articolo sopra che parla dell'EAV. Questo è molto seducente, perché consente agli utenti di progettare la propria struttura dati sottostante. Se trascuri le prestazioni, funziona abbastanza bene per un po '. Si ottiene un database perfettamente generale senza dover imparare la struttura dei dati dagli utenti o dagli esperti in materia.

Quando si verifica un vero e proprio dolore è quando si tenta di utilizzare i dati come se fosse un database integrato, e non solo un miscuglio di opinioni sconnesse sui dati. A questo punto, ti troverai in una seria archeologia dei dati, quando i tuoi clienti si aspettano una generazione di report di routine. In bocca al lupo.

(Editted per cambiare "data mining" per "archeologia dei dati")