سؤال

لديّ مقالات على موقعي ، وأود إضافة علامات تصف كل مقال ، لكنني أواجه مشاكل في تصميم جدول MySQL للعلامات. لدي فكرتان:

  1. سيكون لكل مقالة حقل "علامات" ، وستكون العلامات بالتنسيق: "TAG1 ، TAG2 ، TAG3"
  2. إنشاء جدول آخر يسمى العلامات مع الحقول: 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 بند ، سيكون هناك سطران لهذا المقال
    • بالطبع ، أنت لا تريد إعادة تحديد المقالة التي لديك بالفعل-مما يعني أنه يجب استبعاده.
  • ولكن ، كما تستخدم 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 لها بعض أوجه التشابه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top