Domanda

Quello che segue è un esempio analogo (e semplificato) alla domanda di progettazione che sto affrontando:

Supponiamo di avere studenti, classi e voti.Gli studenti possono appartenere a molte classi diverse.Ogni classe ha molti studenti diversi.E ogni coppia (studente, classe) ha un voto.

Dovrei impaginare il database (database mysql) come:

Opzione 1)

students table - (student_id, student_name)
classes table - (class_id, class_name)
students_classes table - (student_class_id, student_id, class_id)
grades table - (student_class_id, grade)

Opzione 2)

students table - (student_id, student_name)
classes table - (class_id, class_name)
grades table - (student_id, class_id, grade)

O dovrebbe essere concepito come qualcos'altro?L'opzione 2 sembra più semplice ora, ma in futuro potrei aver bisogno di altre statistiche relative a ciascuna coppia (student_id,class_id) (nel qual caso, l'opzione 1 sembra un po' migliore?L'opzione 1 sembra ancora un po' eccessivamente complicata).

Che cosa mi consiglia?Grazie.

È stato utile?

Soluzione

L'opzione 3)

students table - (student_id, student_name)
classes table - (class_id, class_name)
students_classes table - (student_class_id, student_id, class_id, grade)

Grade essere un attributo di studenti di classe.

A meno di Grado ha la possibilità di diventare un'entità a tutti gli effetti. In questo caso:

L'opzione 4)

students table - (student_id, student_name)
classes table - (class_id, class_name)
students_classes table - (student_class_id, student_id, class_id)
grades table - (grade_id, grade, student_class_id)

Altri suggerimenti

Personalmente opterei per l'opzione 2.Non c'è niente di sbagliato con una chiave primaria composita per i voti e cattura le informazioni necessarie nel tuo modello dati.

Nell'opzione 1, students_classes non ha alcuno scopo se non quello di avere una chiave surrogata.

Modifica, dopo aver visto altre risposte:

  • 2NF:il voto (non chiave) dipende esclusivamente dallo studente/classe (chiave)
  • 3NF:Non si applica.Non hai dipendenze non chiave su dipendenze non chiave
  • BCNF:non si applica, hai solo una chiave candidata

Opzione 2 è corretta, tranne che dovrebbe essere chiamato student_class , che riflette la sua n :: n funzione o iscrizione come entità. e (student_id, class_id)is il PK.

Grade (come avete dimostrato) è una dipendenza 1 :: 1 su quella chiave composta (non su uno o l'altro elemento), e non altro, quindi è un attributo di student_class.

e thereforestudent_classis in 3NF.

Se le persone non iniziano attaccando alla cieca colonne Idiot su tutto ciò che si muoveva, come avete fatto con l'opzione 1, che sarebbe in grado di comprendere i dati migliori e quindi normalizzare meglio. Che (colonna Idiot in Opzione 1 come punto di partenza) interferito con il vostro intuito che era il the(student_id, class_id) Identifier; nessun ulteriore colonna Idiot al suo indice supplementare era necessaria. Poi, quando si ha intorno a evaluatinggrade, la sua dipendenza che PK è evidente.

colonne Idiot danneggia la capacità relazionale del database. Se si dispone di dire tre tabelle in una gerarchia, e avete bisogno di afferrare alcune colonne dalla parte superiore e tabelle in basso, si è costretti a passare attraverso il tavolo centrale. Se tu avessi relazionale identificatori, invece di colonne idiota, si ottiene dalla tabella in basso al tavolo con dover leggere il tavolo centrale.

E 'solo una mezza verità che ci sono così tanti unisce in un database "normalizzata". La verità è completo, dal momento che il database non è normalizzata in modo corretto, sì, si è costretti in molti di più si aggiunge che sono necessarie. In un database veramente normalizzata, con le stesse tabelle, il codice richiede molto meno si unisce.

Ecco un > Data Model per un Collegio < da un recente incarico, versione semplificata.

> IDEF1X notazione < per chi ha bisogno spiegazione dei simboli.

  • è richiesto nota solo una chiave surrogata.

    • Questo perché in subordine, (Cognome + FirstName + Initials_BirthDate + BithDate) sarebbe la persona PK, e che sarebbe stato trasportato come FK in 5 Bambino / tavoli nipote, che è di 81 byte, e che non è ragionevole.
      .
  • Vedere se è possibile apprezzare il fatto che gli identificatori (linee continue) vengono effettuate attraverso i figli e nipoti; che hanno, e trasmettere un significato

  • Sarebbe stupido aggiungere chiavi surrogate per TeacherId, StudentID, StaffID, quando abbiamo una perfetta buona PersonId, che è la chiave esterna e già unico. (Le colonne sono chiamati come tali per identificare i loro ruoli.)

  • Tutte le regole business sono stati attuati in DDL: Costrette FK; Controllare Vincoli; Regole.

    • La camera dispone di un composto chiave a 4 colonne; Offrendo ha un composto chiave a 3 colonne; i due insieme eliminare la doppia prenotazione.

    • L'Offerta PK e lo studente PK insieme formano la PK per iscrizione (identica a questa domanda, i PK sono composte da diverse colonne, che è tutto).

sono un fan di modulo di terze normale, dove si ha Student separato, tabelle di classe e grado e collegarli con molti-a-molti tavoli come ClassStudent e GradeClass.

Ma dipende da come si vuole mantenere in futuro. In definitiva si tratta di futura estensione e manutenibilità. È per questo che preferisco 3NF.

Modifica

è molto meglio del mio.

Tutto dipende, in realtà. Opzione 1 è probabilmente il modo più robusto di fare questa applicazione; l'opzione 2 potrebbe arrivare lì più veloce per questa iterazione. Sarà il passaggio da 'opzione 2 -> 1 che essere doloroso per il futuro? Come che si sono che sarà necessario che la flessibilità in più?

I consiglierei solo andando per l'opzione 1. Le domande non saranno molto più complicato e se si utilizza un ORM (come ActiveRecord per Rails, tra i tanti), quindi la differenza è praticamente nullo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top