Come progetteresti questa tabella?

2

Devo creare una tabella in cui ogni riga deve memorizzare 50 valori numerici. Ogni riga avrà sempre bisogno di memorizzare 50 valori numerici.

Se si trattasse di un numero inferiore di valori, vorrei solo creare campi per ciascuno dei valori, ma poiché ci sono 50, questo approccio sembra un po 'macchinoso (ma dal momento che saranno sempre 50 valori, forse questo è corretto approccio?).

C'è un modo per memorizzare una matrice di valori in un campo? Questa sembra una buona soluzione, ma il concetto è quasi identico alla creazione di un database relazionale.

    
posta sooprise 23.06.2011 - 21:35
fonte

8 risposte

7

Suggerisco di memorizzare ciascun numero in una riga separata, con la stessa chiave.

Quindi, per recuperare tutti i 50 valori, fai SELECT * FROM table WHERE key=:row_key . Che recupera tutti i valori, puoi scorrere attraverso di loro e posizionarli in un array o qualsiasi altra cosa.

Puoi anche aggiungere un numero di sequenza se devi conservare l'ordine o avere chiavi univoche.

KEY  VALUE
---  -----
 1    5
 1    8
 2    6
 2    45

Con numero di sequenza:

KEY  SEQUENCE  VALUE
---  --------  -----
 1      1        5
 1      2        8
 2      1        6
 2      2        45
    
risposta data 23.06.2011 - 21:44
fonte
7

Se stiamo parlando, per esempio, del tracciamento di 50 diverse proprietà distinte di un oggetto o oggetto, allora sì, crea 50 colonne diverse. Non è affatto ingombrante.

Se d'altro canto stai parlando di 50 valori indicizzati, da 1 a 50, ciò che Michael suggerisce potrebbe essere migliore in quanto ti consente di modificare il numero di elementi memorizzati per riga senza alterare lo schema del database.

    
risposta data 23.06.2011 - 22:05
fonte
2

Sono un fan dell'uso della struttura più naturale. Se si tratta di 50 attributi (ad esempio, si sta semplicemente registrando i dati), utilizzare una tabella ampia. Se pensi che il requisito cambierà, allora vai verticale.

L'approccio verticale richiederà più spazio per i dati e gli indici oltre a più I / O da leggere / scrivere. Ma sarà anche meglio bloccare le righe b / c bloccherai solo un attributo per aggiornare invece di tutti i 50. Questa è solo la teoria, tutto dipende esattamente da ciò che stai implementando e da ciò che devi fornire. YMMV

Non memorizzare una matrice in una colonna. Non è nemmeno la prima forma normale e non è possibile aggiornare / contare / sommare / min / max / etc un singolo attributo se lo si fa. Mantieni semplice e chiaro. Non vuoi che il tuo 'design eccellente' che 'risolve' sia un problema molto semplice che appare su thedailywtf.com tra qualche anno.

    
risposta data 24.06.2011 - 02:49
fonte
2

Innanzitutto, @GrandmasterB ha ragione quando dice "Sooprise, devi chiarire se stai parlando di 50 diverse proprietà (altezza, peso, costo, ecc.) o se stai parlando di un array di 50 elementi identici che differiscono solo per indice. "

In secondo luogo, se hai qualche tipo di ORM, puoi nascondere l'implementazione dietro a ciò. Ho alcuni casi in cui i dati originali sono stati de-normalizzati e ho utilizzato l'ORM per consentire l'accesso per indice, quindi non importa se memorizzi ogni valore in una colonna ( VALUE_00 ) o in una tabella figlio separata , il resto del tuo codice non gli interesserà.

Terzo, come hanno detto tutti gli altri, non cercare di memorizzare più di un valore in una colonna (una matrice in un campo). Il problema è che rubi il motore del database dalla possibilità di indicizzare e cercare in modo efficiente su quella colonna. (Ho visto un caso in cui qualcuno ha appena archiviato dati XML in un campo - e con le nuove versioni di SQL Server, può effettivamente analizzarlo, ma non lo considero comunque una buona idea.)

    
risposta data 24.06.2011 - 13:39
fonte
1

La domanda è se credi che "ogni riga sempre abbia 50 valori". Chi ti sta dicendo questo? cosa stanno per memorizzare quei valori? è davvero la probabilità che il valore di questi valori cambi lo zero assoluto?

Ogni volta che mi è stato detto che qualcosa non cambierà mai, andrà e cambierà. Quindi è necessario esercitare un po 'dei propri criteri su questo.

Se credi ancora che sarà veramente 50 valori per riga (come, la tabella è per oggetti pentadecahedral, e i 50 valori sono i vertici o qualsiasi altra cosa), quindi, con tutti i mezzi, vai avanti e aggiungi 50 campi

    
risposta data 23.06.2011 - 23:02
fonte
1

Non userei una colonna di array. Se i 50 numeri rappresentano un singolo valore, potrebbe essere memorizzato come una stringa come un numero di telefono, ma sei limitato a ciò che puoi fare o costretto a disfare questo pasticcio troppo spesso.

Con 50 campi è facile eseguire una query, "mostra tutte le righe dove column5 = 12 e column27 = 36", ma è più difficile trovare "righe con qualsiasi valore di colonna = 27"

Il modo in cui i dati vengono inseriti in questo sistema può guidare il metodo che usi. Se arrivano in batch che non vengono aggiornati ma per lo più aggiunti, è possibile memorizzarli in entrambi i modi, ma lo spazio su disco è un problema.

In ogni caso, non penso che tu sia dipinto in un angolo. Se trovi che esiste un modo preferibile per recuperare i dati in tutte / la maggior parte delle tue query, cambialo. Più andrai avanti, più difficile sarà questo.

Che ne dici di alcuni dettagli su cosa pensi di fare con questi 50 numeri?

    
risposta data 24.06.2011 - 14:06
fonte
0

Se sarà necessario recuperare la maggior parte o tutti questi valori dal DB in una volta, non vedo alcun motivo per non creare semplicemente una tabella "ampia" contenente ciascun numero come una colonna su ogni riga. Se vuoi proiettarlo da e verso un array nel tuo codice, di solito è banale farlo usando un ORM.

Se in genere si devono recuperare solo uno o alcuni di questi numeri alla volta oppure è utile ottenere "colonne" di numeri su più record oppure non si dispone di strumenti avanzati di mappatura del dominio smaltimento, si può prendere in considerazione una struttura di tabelle "domanda-risposta-chiave". La "chiave" identifica un record più grande composto da più righe nella tabella. La "domanda" è un identificatore per una singola proprietà appartenente a un record (nel tuo caso l'ordinale di ciascuno dei 50 valori), e quando combinato con la "chiave" è un indice univoco. La "risposta" è il valore della proprietà data sul record dato. In assenza di un ORM flessibile per generare SQL e trasformare dati in oggetti per te, questo è probabilmente il modo migliore per estrarre in modo flessibile un set di numeri come "stream" che puoi utilizzare per compilare iterativamente un array con un codice molto piccolo.

    
risposta data 23.06.2011 - 22:29
fonte
0

Ok, se nessun altro lo dirà, io: prendere in considerazione l'utilizzo di un archivio dati NoSQL. C'è un numero che mi viene in mente:

Alla fine è necessario progettare il database (compresa la scelta dell'archivio dati) per rendere le query più importanti e frequenti dirette (e quindi anche veloci). Non c'è una risposta generale a questo.

Inoltre, dal tuo profilo ho dedotto che tu sei un programmatore C #. Ci dovrebbe essere un certo numero di framework di persistenza C # che prendono questa decisione per te, in base alla conoscenza che i loro sviluppatori hanno messo in loro.

Alla fine ti consiglio di incapsulare questo dettaglio, in modo che tu possa modificare i dettagli di questa implementazione con la modifica di una sola posizione del codice di accesso.

Per quanto riguarda SQL, vorrei andare con la soluzione proposta da Michael, perché è semplicemente più flessibile e i dati possono essere recuperati con un semplice join. Se in seguito ti rendi conto che questo è un collo di bottiglia delle prestazioni, puoi comunque spostare facilmente i dati direttamente nelle righe, a condizione che tu abbia incapsulato questa scelta.

    
risposta data 24.06.2011 - 12:55
fonte

Leggi altre domande sui tag