Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL:Zrozumienie tabel mapowania

Podczas korzystania z relacji wiele-do-wielu jedynym realistycznym sposobem radzenia sobie z tym jest użycie tabeli mapowania.

Powiedzmy, że mamy szkołę z nauczycielami i uczniami, uczeń może mieć wielu nauczycieli i odwrotnie.

Więc robimy 3 stoły

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)

Tabela uczniów będzie miała 1000 rekordów
Tabela nauczyciela będzie miała 20 rekordów
Tabela link_st będzie zawierać tyle rekordów, ile jest linków (NIE 20x1000, ale tylko dla rzeczywistych linków).

Wybór
Wybierasz m.in. uczniów na nauczyciela przy użyciu:

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

Zwykle zawsze powinieneś używać połączenia wewnętrznego tutaj.

Tworzenie linku
Gdy przypiszesz nauczyciela do ucznia (lub odwrotnie, to samo) .Wystarczy tylko:

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'

Jest to trochę niewłaściwe użycie wewnętrznego sprzężenia, ale działa tak długo, jak nazwy są unikalne.
Jeśli znasz identyfikatory, możesz po prostu wstawić je bezpośrednio.
Jeśli nazwy są nie wyjątkowy to będzie porażka i nie powinny być używane.

Jak uniknąć duplikatów linków
Bardzo ważne jest unikanie duplikatów linków, jeśli je posiadasz, mogą się zdarzyć różne złe rzeczy.
Jeśli chcesz zapobiec wstawianiu zduplikowanych linków do tabeli linków, możesz zadeklarować unikalny indeks na linku (zalecane)

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

Możesz też sprawdzić w instrukcji insert (niezalecane, ale działa).

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)

Spowoduje to wybranie tylko 548, 785 jeśli że dane nie znajdują się jeszcze w link_st table i nic nie zwróci, jeśli te dane są już w link_st. Więc odmówi wstawienia zduplikowanych wartości.

Jeśli masz szkoły stołowe, zależy to od tego, czy uczeń może być zapisany do wielu szkół (mało prawdopodobne, ale załóżmy), a nauczyciele mogą być zapisani do wielu szkół. Bardzo możliwe.

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

Możesz wymienić wszystkich uczniów w szkole w następujący sposób:

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)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Błędy hibernacji w nazwanych zapytaniach

  2. jak usunąć partycję bez upuszczania danych w MySQL?

  3. Wstaw dane do bazy danych MySQL

  4. Pole daty i godziny Django - w widoku przekonwertuj na strefę czasową

  5. Wstaw unikalne ciągi 8 losowych znaków