Khi sử dụng mối quan hệ nhiều-nhiều, cách thực tế duy nhất để xử lý điều này là sử dụng bảng ánh xạ.
Giả sử chúng ta có một trường học với giáo viên và học sinh, một học sinh có thể có nhiều giáo viên và ngược lại.
Vì vậy, chúng tôi lập 3 bảng
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)
Bảng học sinh sẽ có 1000 bản ghi.
Bảng giáo viên sẽ có 20 bản ghi.
Lựa chọn
Bạn chọn ví dụ:học sinh trên mỗi giáo viên sử dụng:
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
Thông thường, bạn nên luôn sử dụng inner join
tại đây.
Tạo liên kết
Khi bạn chỉ định một giáo viên cho một học sinh (hoặc ngược lại, điều đó cũng giống như vậy) .Bạn chỉ cần làm:
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'
Đây là cách sử dụng sai phép nối bên trong một chút, nhưng nó hoạt động miễn là các tên là duy nhất.
Nếu bạn biết id, tất nhiên bạn có thể chèn trực tiếp những tên đó.
Nếu tên là không phải là duy nhất, đây sẽ là một thất bại và không nên được sử dụng.
Cách tránh các liên kết trùng lặp
Điều rất quan trọng là tránh các liên kết trùng lặp, tất cả những điều tồi tệ sẽ xảy ra nếu bạn có những liên kết đó.
Nếu bạn muốn ngăn việc chèn các liên kết trùng lặp vào bảng liên kết của mình, bạn có thể khai báo một unique
lập chỉ mục trên liên kết (được khuyến nghị)
ALTER TABLE link_st
ADD UNIQUE INDEX s_t (student_id, teacher_id);
Hoặc bạn có thể kiểm tra trong câu lệnh chèn (không thực sự được khuyến khích, nhưng nó hoạt động).
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)
Điều này sẽ chỉ chọn 548, 785 nếu dữ liệu đó chưa có trong link_st
và sẽ không trả về gì nếu dữ liệu đó đã có trong link_st. Vì vậy, nó sẽ từ chối chèn các giá trị trùng lặp.
Nếu bạn có một bảng trường học, điều đó phụ thuộc vào việc một học sinh có thể được đăng ký vào nhiều trường (không chắc, nhưng hãy giả sử) và giáo viên có thể được đăng ký vào nhiều trường. Rất có thể.
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
Bạn có thể liệt kê tất cả học sinh trong một trường như vậy:
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)