Come gestire la progettazione di tabelle con colonne variabili


17

Ho uno scenario di progettazione della tabella e come tipo non DBA, vorrei opinioni su quale sia più scalabile.

Supponiamo che ti venga chiesto di registrare informazioni sulle case per un'area metropolitana, iniziando con un piccolo quartiere (200 case) ma alla fine crescendo fino a oltre 5000000 case.

È necessario memorizzare le informazioni di base: ID # (un lotto unico # che possiamo utilizzare come indice univoco), Addr, Città, Stato, CAP. Un tavolo semplice e raffinato lo gestirà.

Ma ogni anno ti verrà chiesto di registrare informazioni aggiuntive su tutte le case e QUALI informazioni cambieranno ogni anno. Quindi, ad esempio, il primo anno, ti viene chiesto di registrare il cognome e il metraggio dei proprietari. Il secondo anno, ti viene chiesto di mantenere il cognome, ma scarica il metraggio e inizia a raccogliere i nomi dei proprietari.

Infine, ogni anno il numero di colonne extra cambierà. Potrebbe iniziare con 2 colonne aggiuntive, quindi andare a 6 il prossimo anno, quindi tornare indietro a 2.

Quindi un approccio basato su una tabella consiste nel provare ad aggiungere le informazioni personalizzate come colonne nelle tabelle della casa in modo che vi sia una sola tabella.

Ma ho una situazione in cui qualcuno ha preparato i tavoli per questo come:

Colonne "Tavolo casa": ID, indirizzo, città, stato, CAP - con una riga per casa

ID   Addr              City     State  Zip 
-------------------------------------------
1    10 Maple Street   Boston      MA  11203

2    144 South Street  Chelmsford  MA  11304

3    1 Main Avenue     Lowell      MA  11280

Colonne "Tabella informazioni personalizzate": ID, Nome, Valore - con tabella simile a:

ID   Name             Value

1    Last Name        Smith

2    Last Name        Harrison

3    Last Name        Markey

1    Square Footage   1200

2    Square Footage   1930

3    Square Footage 

Quindi ci sono più file per ogni singolo record di casa. Ogni anno, quando le informazioni opzionali richiedono modifiche, questa tabella viene letteralmente ricostruita, quindi l'anno prossimo potrebbe apparire come:

1    Last Name    Smith

2    Last Name    Harrison

3    Last Name    Markey

1    First Name   John

2    First Name   Harry

3    First Name   Jim

Alla fine accumuli 100.000 file di case E un anno ci sono 10 informazioni extra; la seconda tabella ora contiene 1.000.000 di righe di informazioni, molte delle quali hanno informazioni ridondanti (descrizione). I requisiti generali del database sono che le persone dovranno ottenere le informazioni sulla riga della casa + i valori dei campi personalizzati associati migliaia di volte al giorno.

Quindi la mia domanda: sarebbe una cattiva (o orribile) pratica invece:

A) Disporre la tabella della casa con il numero massimo di colonne personalizzate (chiamato forse da "1" a "10") e inserire tali valori personalizzati nelle righe della casa

O

B) Archivia le informazioni personalizzate nella tabella della casa, ma ogni anno quando cambiano i requisiti, ricostruisci la tabella della casa con solo il numero di colonne necessarie per le informazioni personalizzate, con l'idea che i requisiti potrebbero impazzire e non sai mai quanti campi opzionali potrebbero essere richiesti?

Grazie, spero che abbia senso!


Ciao, come hai gestito il tuo problema? Sto eseguendo lo stesso tipo di scenario e sto per creare una tabella relazionale per ulteriori informazioni e renderla con le viste come una "tabella singola".
Benj,

Risposte:


15

Hai praticamente 4 scelte:

NoSQL - definizione Ogni record è memorizzato come un insieme di coppie chiave / valore. È molto flessibile e veloce. Non tutti gli autori di report supportano questo stile di archiviazione. Esistono molte implementazioni di database di esempio di NoSQL. Quello che sembra essere più popolare in questo momento, è MongoDB.

EAV - definizione Qui è dove si gira l'intera tabella o una porzione (in un'altra tabella) su un lato. Questa è una buona scelta se hai già un database relazionale interno da cui non puoi allontanarti facilmente. L'esempio di tabella di informazioni personalizzate che hai fornito è un buon esempio di tabella EAV.

Tabelle standard con colonne XML : pensate a questo come NoSQL incontra le tabelle relazionali. I dati memorizzati in una colonna XML possono essere in qualsiasi formato supportato da XML, inclusi più dati secondari correlati. Per le colonne che conosci saranno "normali", possono essere costruite come il tipo appropriato di colonna per archiviare i dati (Cognome, Indirizzo, Città, Stato, ecc.).

Tabelle standard con molte colonne extra : disponi di un database relazionale, non puoi utilizzare XML o EAV e NoSQL non è un'opzione. Aggiungi molte colonne extra di ogni tipo. Immagino che 30 o più varchar, 30 o più numeri interi, 15 o più numeri. E una volta che usi una colonna per un valore, non riutilizzarla . E non cancellare neanche la colonna .

Tra tutte queste soluzioni, la mia opinione è che troverai che l'approccio NoSQL o EAV sia il più efficace con il minor numero di refactoring del tuo codice e del tuo schema.

Avrai una situazione in cui raccoglierai i dati un anno, non il successivo, per poi raccoglierli successivamente. Cercare di aggiornare i dati più vecchi con le informazioni corrette è problematico e costoso. L'archiviazione non è né.


Ho sentito che puoi anche usare le tabelle pivot o qualcosa del genere
Alexander Mills,

2

Per rispondere alla tua domanda su queste 2 opzioni, nessuna delle due mi sembra giusta. A) ti bloccherà e B) è un sacco di lavoro. Lo schema corrente che descrivi non è troppo male (tranne per avere il nome di informazioni ("nome", "piede quadrato", ecc.) Come stringa anziché un ID a cui fa riferimento una tabella di ricerca.

Tuttavia, questo mi sembra un buon candidato per un database NoSQL ( http://en.wikipedia.org/wiki/NoSQL ). Anche se non ho mai lavorato con tale database, quello che descrivi è uno scenario tipico che questo risolve.


0

Se il numero simultaneo di colonne personalizzate è finito e i limiti sono noti (ad es. Non più di 10-20 colonne personalizzate per String, non più di x colonne per numeri interi ecc.)
È possibile utilizzare la tabella di base con campi aggiuntivi per tipo di dati e invece di ricostruire la tabella ogni anno creare una vista per quell'anno includendo solo le colonne personalizzate pertinenti e rinominando i campi generici per riflettere i contenuti per quell'anno.

House Table:
ID, Addr, City, State, Zip, custom_string1,cs_2,cs_3,custom_integer_1,ci_2,ci_3 ...

create view house_2014 as 
select ID, Addr, City, State, Zip,
custom_string1 as last_name,cs_2 as first_name ...

Il problema con questo approccio è che non si ha una cronologia ma si potrebbe facilmente fare una copia ogni anno prima di modificare i requisiti di colonna.

create table house_2014_archive as select * from house_2014;
drop house_2014;
create view house_2015 as "select column list for new year";

0

Puoi elencare tutti gli scenari per i quali desideri archiviare questi dati?

se esiste un numero finito di combinazioni di colonne che possono essere applicate alla tabella, quindi provare a modellare una "tabella di base" con colonne comuni che si stanno preparando per applicare a tutti gli scenari, quindi creare più tabelle (per implementare un qualche tipo di ereditarietà; questo è noto come sottotipo / supertipo in ERD e progettazione del database.)

una tabella per ogni scenario, in questo modo almeno manterrai le tabelle pulite e sarai in grado di evitare di avere l'indirizzo della strada memorizzato nella colonna "cognome" ...

Dai un'occhiata a questa domanda di design: /programming/554522/something-like-inheritance-in-database-design

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.