Duplicazione di una chiave in una tabella di mappatura invece di unirsi

1

Sto esaminando una struttura in cui viene eseguita una tabella di mappatura delle iscrizioni agli studenti. Mi chiedo se una colonna aggiuntiva ( class_category_id ) alla tabella di mapping possa diventare un problema o un vantaggio evidente. Quella chiave aggiuntiva sarebbe stata usata per filtrare molto spesso.

Ecco una struttura semplificata del database:

Categorie di classi

id  name
1   Math
2   Science

Classi

id  name  class_category_id
1   M101  1
2   M102  1
3   B101  2
4   P101  2

Iscrizioni allo studente

id  student_id class_id  *class_category_id*
1   1001       1         1
2   1002       1         1
3   1003       3         2
4   1004       4         2

Le query comuni includevano il filtraggio delle iscrizioni per la categoria di classe, senza l'effettiva necessità di ottenere le informazioni sulla classe stessa.

Non è chiaro al 100% se class_category_id possa avere vantaggi e svantaggi.

Una nota importante sarebbe che una categoria per una classe cambierà mai in modo da aggiornare più tabelle per l'aggiornamento che non sarebbero mai necessarie.

EDIT: Piccola nota, questa struttura reale della tabella sarebbe equivalente a questa, ma con molte più colonne (per le tabelle non di mappatura) e in realtà non in alcun modo correlate a classi / studenti.

    
posta Andrius 17.02.2017 - 10:39
fonte

1 risposta

4

L'aggiunta di quella colonna sarebbe una violazione della seconda forma normale. Sotto 2NF, tutti gli attributi (colonne non chiave) nella tabella devono essere attributi della chiave primaria intera , non solo parte della chiave. Nel tuo caso, la categoria della classe è un attributo di class , non enrollment .

Detto questo, non è del tutto raro che denormalizzi le tabelle per motivi di prestazioni. Se pensi che questo cambiamento sarà un enorme vantaggio, allora non è necessariamente "malvagio" farlo.

Per farti riflettere, ecco alcuni dei problemi che potrebbero fornire con questo tipo di cambiamento.

  1. La dimensione del database sarà maggiore, dal momento che stai duplicando i dati in due punti

  2. La quantità di I / O richiesta per recuperare i dati potrebbe essere più lunga in media, perché il set di lavoro sarà più grande e perché un numero inferiore di righe si adatta a una pagina di dati. Questo può influire sulle prestazioni.

  3. Se decidi di indicizzare la tabella class con l'ID della categoria, qualsiasi query che utilizza la tabella enrollment non trarrà alcun vantaggio da questo indice. Avresti bisogno di un indice separato, che consumerà più spazio e ridurrà le prestazioni di qualsiasi operazione di inserimento su enrollment .

  4. Qualcuno potrebbe commettere un errore e inserire un ID di categoria diverso in enrollment rispetto a class .

  5. Presumibilmente, class potrebbe finire per essere statico e completamente memorizzato nella cache, quindi potrebbe non essere molto costoso unirsi ad esso e recuperare l'ID della categoria. D'altra parte, enrollment sarà molto più grande e in costante flusso, quindi non trarrà beneficio da alcuna memorizzazione nella cache. Anche in questo caso, ciò potrebbe influire sulle prestazioni.

  6. Se le classi vengono riassegnate a diverse categorie (ad es. se il dipartimento di lingua greca si chiude e tutte le sue classi vengono spostate nel dipartimento di lingue antiche) avrai a disposizione la pulizia dei dati.

  7. Se la struttura della categoria cambia (ad esempio un giorno decide che una classe potrebbe appartenere a due o più categorie), la struttura della tabella non sarà compatibile con la relazione 1: M.

Se stai semplicemente facendo tutto questo perché non vuoi digitare JOIN per tutto il tempo, considera la possibilità di creare un Visualizza . Puoi pre-partecipare a tutte le tabelle che desideri nella vista, quindi utilizzare la vista nella tua clausola FROM .

    
risposta data 21.02.2017 - 03:19
fonte

Leggi altre domande sui tag