Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL:Comprensione delle tabelle di mappatura

Quando si utilizzano relazioni molti-a-molti, l'unico modo realistico per gestirlo è con una tabella di mappatura.

Diciamo che abbiamo una scuola con insegnanti e studenti, uno studente può avere più insegnanti e viceversa.

Quindi creiamo 3 tabelle

student
  id unsigned integer auto_increment primary key
  name varchar

teacher
  id unsigned integer auto_increment primary key
  name varchar

link_st
  student_id integer not null
  teacher_id integer not null
  primary key (student_id, teacher_id)

La tabella studenti avrà 1000 record
La tabella insegnanti avrà 20 record
La tabella link_st avrà tanti record quanti sono i collegamenti (NON 20x1000, ma solo per i collegamenti effettivi).

Selezione
Selezioni ad es. studenti per insegnante utilizzando:

SELECT s.name, t.name 
FROM student
INNER JOIN link_st l ON (l.student_id = s.id)   <--- first link student to the link-table
INNER JOIN teacher t ON (l.teacher_id = t.id)   <--- then link teacher to the link table.
ORDER BY t.id, s.id

Normalmente dovresti sempre usare un inner join qui.

Creare un collegamento
Quando assegni un insegnante a uno studente (o viceversa, è lo stesso) .Devi solo fare:

INSERT INTO link_st (student_id, teacher_id) 
   SELECT s.id, t.id 
   FROM student s 
   INNER JOIN teacher t ON (t.name = 'Jones')
   WHERE s.name = 'kiddo'

Questo è un po' un uso improprio di un inner join, ma funziona purché i nomi siano univoci.
Se conosci gli ID, puoi inserirli direttamente ovviamente.
Se i nomi sono non univoco, questo sarà un errore e non dovrebbe essere usato.

Come evitare link duplicati
È molto importante evitare link duplicati, se li hai accadranno ogni sorta di brutte cose.
Se vuoi evitare di inserire link duplicati nella tabella dei link, puoi dichiarare un unique indice sul link (consigliato)

ALTER TABLE link_st
  ADD UNIQUE INDEX s_t (student_id, teacher_id); 

Oppure puoi fare il controllo nella dichiarazione di inserimento (non consigliato, ma funziona).

INSERT INTO link_st (student_id, teacher_id) 
  SELECT s.id, t.id
  FROM student s
  INNER JOIN teacher t ON (t.id = 548)
  LEFT JOIN link_st l ON (l.student_id = s.id AND l.teacher_id = t.id)
  WHERE (s.id = 785) AND (l.id IS NULL)

Questo selezionerà solo 548, 785 se quei dati non sono già nel link_st tabella e non restituirà nulla se quei dati sono già in link_st. Quindi rifiuterà di inserire valori duplicati.

Se hai un tavolo scuole, dipende se uno studente può essere iscritto a più scuole (improbabile, ma supponiamo) e gli insegnanti possono essere iscritti a più scuole. Molto possibile.

table school
  id unsigned integer auto_increment primary key
  name varchar

table school_members
  id id unsigned integer auto_increment primary key
  school_id integer not null
  member_id integer not null
  is_student boolean not null

Puoi elencare tutti gli studenti di una scuola in questo modo:

SELECT s.name
FROM school i
INNER JOIN school_members m ON (i.id = m.school_id)
INNER JOIN student s ON (s.id = m.member_id AND m.is_student = true)