كيفية تصميم جدول MySQL لسحابة العلامة؟
-
25-09-2019 - |
سؤال
لديّ مقالات على موقعي ، وأود إضافة علامات تصف كل مقال ، لكنني أواجه مشاكل في تصميم جدول MySQL للعلامات. لدي فكرتان:
- سيكون لكل مقالة حقل "علامات" ، وستكون العلامات بالتنسيق: "TAG1 ، TAG2 ، TAG3"
- إنشاء جدول آخر يسمى العلامات مع الحقول: tag_name ، article_id
لذلك عندما أريد علامات للمقالة مع ID 1 ، أود أن أركض
SELECT ... FROM tags WHERE `article_id`=1;
ولكن ، أود أيضًا أن أعرف 3 مقالات متشابهة من خلال مقارنة العلامات ، لذلك إذا كان لديّ مقال يحتوي على علامات "PHP ، MySQL ، Erlang" ، و 5 مقالات ذات علامات: "PHP ، MySQL" ، "Erlang ، Ruby" ، "php erlang" ، "mysql ، erlang ، JavaScript" ، سأختار 1. ، 3. و 4. ، لأن هؤلاء الثلاثة لديهم نفس العلامات مع المقالة الرئيسية.
أيضا سؤال آخر ، ما هي أفضل طريقة للحصول على 10 "العلامات الأكثر استخدامًا"؟
المحلول
بشكل عام ، لهذا النوع من العلاقة بين العديد من العدد ، هناك ثلاثة طاولات:
- ال "
article
" الطاولة- المفتاح الأساسي = المعرف
- ال "
tag
" الطاولة- المفتاح الأساسي = المعرف
- يحتوي على بيانات كل علامة:
- الاسم ، على سبيل المثال
- أ "
tags_articles
"الجدول ، الذي يعمل كجدول انضمام ، ويحتوي فقط على:id_article
: مفتاح خارجي يشير إلى مقالid_tag
: مفتاح خارجي يشير إلى علامة
وبهذه الطريقة ، لا يوجد ازدواج لبيانات أي علامة: لكل علامة ، هناك واحد ، وخط واحد فقط في tag
الطاولة.
وبالنسبة لكل مقال ، يمكنك الحصول على عدة علامات (أي عدة خطوط في tags_articles
الطاولة) ؛ وبالطبع ، لكل علامات ، يمكنك الحصول على العديد من المقالات.
الحصول على قائمة من العلامات لمقال ، مع هذه الفكرة ، هو مسألة استعلام إضافي ، مثل:
select tag.*
from tag
inner join tags_articles on tag.id = tags_articles.id_tag
where tags_articles.id_article = 123
سيعني الحصول على المقالات الثلاثة "الأكثر تشابهًا":
- حدد مقالات لها علامات لديها المقالة الأولى
- استخدم فقط تلك التي لديها أهم عدد من العلامات المتطابقة
لم يتم اختباره ، ولكن قد تكون الفكرة شيئًا يبدو مثل هذا:
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
في الأساس ، أنت:
- حدد معرفات المقالات لكل علامة موجودة في مقالتك الأولية
- نظرًا لوجود جمع داخلي ، إذا كان لدى مقال في DB علامتين يتطابقان مع
where
بند ، بدونgroup by
بند ، سيكون هناك سطران لهذا المقال - بالطبع ، أنت لا تريد إعادة تحديد المقالة التي لديك بالفعل-مما يعني أنه يجب استبعاده.
- نظرًا لوجود جمع داخلي ، إذا كان لدى مقال في DB علامتين يتطابقان مع
- ولكن ، كما تستخدم
group by article.id
, ، سيكون هناك سطر واحد فقط لكل مقالة- لكنك ستكون قادرًا على الاستخدام
count
, ، لمعرفة عدد العلامات التي تشترك فيها كل مقالة مع الأولي
- لكنك ستكون قادرًا على الاستخدام
- بعد ذلك ، إنها مسألة الفرز لكل عدد من العلامات ، والحصول على الأسطر الثلاثة الثالثة فقط.
نصائح أخرى
أولاً ، سترغب في استخدام اقتراح Pascal Martin حول تصميم الجدول.
أما بالنسبة للعثور على مقالات مماثلة ، فإليك شيء لتبدأ. بالنظر إلى أن article_id هي المقالة التي تريد العثور عليها من أجل ، و @tag1 ، @tag2 ، @tag3 هي علامات هذه المقالة:
SELECT article_id, count(*)
FROM tags_articles
WHERE article_id <> @article_id
AND tag_id IN (@tag1, @tag2, @tag3)
GROUP BY article_id
ORDER BY count(*) DESC
LIMIT 3
نعم ، لكنك لم تجيب على سؤالي الرئيسي ، وكيف تحصل على 3 مقالات متشابهة؟
الإجابة: فقط ابحث عن معرفات العلامة نفسها في الجدول المدمج (Tags_Articles). اجمعهم وإنشاء نمط.
على سبيل المثال: المادة 1 تحتوي على علامات: 1،2 المادة 2 تحتوي على علامات: 2،3،4 المادة 5 لديها علامات: 6،7،2 المادة 7 لديها العلامات: 7،1،2،3
إذا كنت تريد 3 مقالات متشابهة للمادة 1 ، فيجب عليك البحث عن العلامات 1،2. ستجد المادة 7 متشابهة و 2 و 5 لها بعض أوجه التشابه.