Una tabella singola o due tabelle più piccole

-2

Al momento disponiamo di una tabella Users nel database, con alcune colonne al suo interno. Circa il 50% delle colonne è utilizzato a malapena nel sistema (solo su una o due pagine). Abbiamo discusso tra di noi se dividere questo tavolo in due tabelle, ad es. Users e UserSettings . Il nostro pensiero è anche che potremmo dividere anche gli oggetti C # per seguirne l'esempio.

Proviamo a pensare alle dimensioni dell'indice db e cose come la memorizzazione nella cache poiché gli oggetti utente sono memorizzati nella cache in Redis. So che in alcuni casi avremmo bisogno di un paio di query db per ottenere i dati invece di uno solo, ma poiché questa sarebbe l'eccezione, il salvataggio in qualsiasi altro luogo sarebbe di maggior beneficio.

    
posta Gaz 14.02.2018 - 21:24
fonte

4 risposte

3

Dall'esperienza con database Oracle molto più grandi (ma penso che la maggior parte del ragionamento si applichi anche ad altri DBMS):

Se dividere la classe Users rende il codice dell'applicazione più pulito, fallo. Ma non mi aspetterei problemi di preformance o spazio di archiviazione.

Le colonne VARCHAR occupano lo spazio solo in base alla lunghezza del contenuto effettivo e non al massimo dichiarato, pertanto le colonne per lo più vuote non sprecano una notevole quantità di spazio di archiviazione. Lo stesso vale per gli indici su queste colonne.

Assicurati che la tua tabella si adatti alla RAM del DBMS, in modo che le query possano essere servite senza I / O su disco (dopo un riscaldamento iniziale). Con alcune linee di 100k di forse 1 kByte ciascuna, ciò significherebbe meno di 1 GByte di RAM, quindi non dovrebbe essere un problema al giorno d'oggi.

    
risposta data 15.02.2018 - 11:54
fonte
2

We currently have a Users table in the database, this has quite a few columns in it.

E allora? Le tue query dovrebbero solo recuperare le colonne che richiedono, quindi avere altri in giro nella tabella è irrilevante.

We trying to think about db index size ...

A meno che tu non abbia una base di utenti grande come FacePlant o Twaddle, i dati delle tue impostazioni utente dovrebbero essere sminuiti dalle cose "reali" (ad esempio, non ti preoccupare).

I know in some cases we'd need a couple of db queries to the get the data instead of a single one

Sciocchezze.
Avresti due tabelle fisiche, entrambe digitate e indicizzate sullo stesso identificatore [utente] e dove hai bisogno di dati da entrambe le tabelle, dovresti unirti tra i due. Assolutamente non è necessario per più query.

    
risposta data 15.02.2018 - 12:43
fonte
0

Pugno, hai effettivamente identificato un problema reale? Puoi dimostrare che avere una tabella ampia causa qualche problema al sistema in termini di throughput, consumo di risorse, latenza o somesuch? La suddivisione della tabella causerà un sovraccarico di manutenzione, quindi è meglio accertarsi che sia giustificato.

We [sic] trying to think about db index size

La dimensione dell'indice è determinata dalle colonne chiave. Poiché la chiave non cambierà dopo la divisione, la dimensione dell'indice sarà la stessa. Nello specifico l'indice depth rimarrà lo stesso, ed è qui che entra in gioco un sacco di overhead. Inoltre, immagino che entrambe le tabelle avranno la stessa chiave (UserId?) Quindi il doppio del disco sarà usato per memorizzare l'indice.

Alcuni RDBMS implementano gli indici BTree in cui la foglia è l'intera riga. Per questi, la suddivisione della tabella consentirà di tenere più righe in una determinata quantità di RAM, migliorando le prestazioni. Tuttavia, non vedrai un miglioramento se il server DB non è sotto pressione di memoria, o la tabella utente viene toccata così frequentemente da non essere mai sfrattata dalla memoria al momento.

and things like caching as the user objects are cached in Redis.

Hai serializzato e messo in cache l'intero oggetto? Bene, fare meno lavoro è più veloce di fare più lavoro. Quindi spaccare è probabilmente vantaggioso. Ciò non richiede che la divisione venga eseguita nell'RDBMS, tuttavia, solo nel codice di gestione della cache Redis.

I know in some cases we'd need a couple of db queries to the get the data instead of a single one

Bene, forse. Una singola query può unirsi a molte tabelle e amp; restituire un singolo set di risultati. Una stored procedure può restituire più set di risultati. È possibile definire una vista che unisce le tabelle e la vista può essere referenziata dall'applicazione.

Ho l'impressione che sia coinvolto un ORM. Le tue opzioni qui potrebbero essere dettate da questo.

Uno dei principali inconvenienti della divisione è che ora hai due oggetti che assolutamente, sicuramente devono essere sincronizzati. Ciò richiederà codice di applicazione molto accurato o, più probabilmente, trigger di database. Questo complica il ragionamento sul sistema. Sarebbe mai accettabile avere un utente senza UserSettings corrispondenti? In quali circostanze può essere rimosso? Come imporre il vincolo della relazione "esattamente uno" tra le due tabelle? Questo è realizzabile ma richiede una pianificazione.

    
risposta data 27.02.2018 - 12:33
fonte
-1

Nella maggior parte dei database (se non tutti) un valore nullo occupa pochissimo spazio.

Una tabella separata ha il sovraccarico di una chiave esterna.

    
risposta data 15.02.2018 - 11:59
fonte