Nói chung, đối với loại mối quan hệ nhiều-nhiều này, có ba bảng:
- Bài viết "
article
"bảng- khóa chính =id
- Thẻ "
article
"bảng- khóa chính =id
- chứa dữ liệu của mỗi thẻ:
- tên chẳng hạn
- Một "
tags_articles
"bảng, hoạt động như một bảng nối và chỉ chứa:-
id_article
:khóa ngoại trỏ đến một bài báo -
id_tag
:khóa ngoại trỏ đến thẻ
-
Bằng cách này, không có sự trùng lặp dữ liệu của bất kỳ thẻ nào:đối với mỗi thẻ, có một và duy nhất một dòng trong thẻ article
bảng.
Và, đối với mỗi bài viết, bạn có thể có một số thẻ (tức là một số dòng trong tags_articles
bàn); và tất nhiên, đối với mỗi thẻ, bạn có thể có một số bài viết.
Lấy danh sách các thẻ cho một bài báo, với ý tưởng này, là vấn đề của một truy vấn bổ sung, như:
select tag.*
from tag
inner join tags_articles on tag.id = tags_articles.id_tag
where tags_articles.id_article = 123
Nhận được ba bài báo "giống nhau nhất" có nghĩa là:
- chọn các bài viết có thẻ mà bài viết đầu tiên có
- chỉ sử dụng những thẻ có số lượng thẻ giống hệt nhau quan trọng nhất
Chưa được thử nghiệm, nhưng một ý tưởng có thể giống như thế này:
select article.id, count(*) as nb_identical_tags
from article
inner join tags_articles on tags_articles.id_article = article.id
inner join tag on tag.id = tags_articles.id_tag
where tag.name in ('php', 'mysql', 'erlang')
and article.id <> 123
group by article.id
order by count(*) desc
limit 3
Về cơ bản, bạn:
- chọn id bài viết cho mỗi thẻ có trong bài viết đầu tiên của bạn
- vì có một liên kết bên trong, nếu một bài viết trong DB có 2 thẻ khớp với
where
mệnh đề, không có nhómgroup by
, sẽ có hai dòng cho bài viết đó - tất nhiên, bạn không muốn chọn lại bài viết mà bạn đã có - có nghĩa là nó phải bị loại trừ.
- vì có một liên kết bên trong, nếu một bài viết trong DB có 2 thẻ khớp với
- nhưng, khi bạn sử dụng
group by article.id
, sẽ chỉ có một dòng cho mỗi bài viết- nhưng bạn sẽ có thể sử dụng
count
, để tìm xem mỗi bài viết có bao nhiêu thẻ điểm chung với bài viết đầu tiên
- nhưng bạn sẽ có thể sử dụng
- sau đó, vấn đề chỉ là sắp xếp theo số lượng thẻ và chỉ lấy ba dòng thứ ba.