Una tabella di database che contiene statistiche su altri dati di tabella deve essere a colonne o a righe?

3

Uno dei nostri prodotti genera grandi quantità di log ragionevolmente dettagliati in una tabella di database e stiamo cercando di analizzarli, possibilmente creare un rapporto da loro. I report possono essere eseguiti su richiesta, il che rende questo scenario un buon candidato per eseguire l'analisi del registro una volta e archiviare i risultati; il set di risultati non cambierà una volta calcolato e i rapporti di test con > 20 minuti di run time hanno già dimostrato sciocco mettere SQLServer al fastidio di JSON decodificare milioni di righe di dati di log, cercando statistiche interessanti, ogni volta che il report è gestito

C'è un processo che viene eseguito già quando il registro è chiuso, che cancella alcune informazioni da esso. L'aggiornamento di quel processo per calcolare molte più statistiche è banale; questa domanda riguarda come memorizzare i risultati

Sono diviso tra avere una tabella con una colonna dedicata per ogni statistica e avere un gruppo di coppie chiave-valore che nominano una stat e ne forniscono il valore. Le statistiche sono tutti valori numerici e non è possibile calcolare statistiche di ogni tipo per ogni registro, a seconda del prodotto che ha generato i dati del registro (esempio: se si trattava di una chat video, non ci sarà alcuna statistica "numero di messaggi pubblicati"). Nuove statistiche possono essere aggiunte in futuro

Quindi, se la tabella assomiglia a:

ID | MessagesPosted | PeopleAttended | VideoStreamsRecorded
12 |             45 |              6 |                 NULL
13 |           NULL |              7 |                    4

o

ID | Name                   | Value
12 | 'MessagesPosted'       | 45
12 | 'PeopleAttended'       | 6
13 | 'VideoStreamsRecorded' | 4   
13 | 'PeopleAttended'       | 7

Apprezzo che sia possibile adattarsi dinamicamente a un numero variabile di righe o a un numero variabile di colonne nel codice di front-end e le operazioni di pivot possono capovolgere i dati colonnare a rowar e back senza problemi e il front-end può sembrare per valori specifici e gestire la loro assenza a prescindere, quindi suppongo che la scelta sia uno di "stringed typed, no nulls" o "strongmente typed, nulls". Renderlo rowar potrebbe rendere nHibernate un balk meno, poiché lo schema non è cambiando drasticamente quando il management decide di voler aggiungere 120 nuove statistiche, ma sembra più sporco come un giorno potrebbe non volere un valore numerico, e non voglio davvero entrare nella memorizzazione dei valori come stringa solo per mantenere una statistica "MostValuablePerson". .

Ci sono motivi validi per un metodo rispetto all'altro?

    
posta Caius Jard 11.07.2017 - 17:04
fonte

2 risposte

5

Vorrei appoggiarmi strongmente al tuo secondo esempio normalizzato (tre colonne) per i motivi che hai fornito:

...not every kind stat can be calculated for each log depending on which product generated the log data (example: if it was a video chat, there will be no "number of messages posted" stat). New stats may be added in future.

Entrambe queste situazioni saranno molto meglio servite con la flessibilità dello schema normalizzato.

Credo che l'approccio "stile foglio di calcolo" nel primo schema debba essere utilizzato solo quando si è ragionevolmente certi che non si aggiungeranno più colonne in qualsiasi momento.

Potrebbero esserci motivi tecnici per scegliere il primo schema, ma quelli sono probabilmente piuttosto rari.

    
risposta data 11.07.2017 - 17:30
fonte
0

Quello che stai chiedendo è tabelle di grasso vs tavoli magri, a volte grasso corto vs alto magro. Vedi qui , ad esempio.

Mentre direi che la duplicazione dei tipi di contenuto delle tabelle grasse viola la normalizzazione, c'è un po 'di dibattito su questo, ma ecco perché preferisco l'approccio skinny:

Prova a scrivere una query su sum o avg dei valori in entrambe le forme grasse e magre. Vedrai che per la forma grassa, è piuttosto complesso dato che devi nominare ogni colonna specifica, così come modificare la query ogni volta che la tabella viene estesa (per avere altre colonne). Mentre per l'approccio skinny, scrivi una query semplice e il gioco è fatto.

Ora aggiungi l'acquisizione di min e max in entrambi i moduli. Più difficile con il primo come devi aggiungere più colonne; facile con quest'ultimo, devi solo aggiungere quelle due colonne.

Ora prova a trovare il minimo del minimo o del massimo del massimo con entrambe le forme ...

Generalmente, la forma scarna ci consente di lavorare con colonne intere di valori che sono correlati tra loro molto meglio, ad es. per le statistiche. Per un altro esempio, è possibile enumerare facilmente i nomi con la tabella skinny, mentre con l'altro approccio, è necessario interrogare le tabelle di sistema per trovare i nomi delle colonne.

Tuttavia, alcuni preferiscono l'approccio "fat" quando si ha a che fare con una singola riga (che di solito rappresenta un evento di qualche tipo), e che può rendere più facile rilevare i valori mancanti o gestire l'evento nel suo complesso - mentre con l'approccio magro devi cercare valori mancanti o comporre più righe in un'unica entità che rappresenta l'evento.

Quindi, penso che dipenda dalla frequenza con cui cambia l'elenco delle acquisizioni e dalla manutenzione dei comandi e delle query a seguito delle modifiche apportate alla lista di cattura.

    
risposta data 11.07.2017 - 18:33
fonte

Leggi altre domande sui tag