ট্যাগ সিস্টেম কীভাবে প্রয়োগ করা যায়


90

আমি ভাবছিলাম যে কোনও পদ্ধতিতে এসও তে ব্যবহৃত ব্যবহারের মতো একটি ট্যাগ সিস্টেম বাস্তবায়ন করার সর্বোত্তম উপায় কী। আমি এটি ভাবছিলাম কিন্তু আমি একটি ভাল স্কেলেবল সমাধান দিয়ে আসতে পারি না।

আমি বেসিক 3 টেবিল সমাধানের কথা ভাবছিলাম: একটি tagsটেবিল, একটি articlesটেবিল এবং একটি tag_to_articlesটেবিল থাকা।

এটিই কি এই সমস্যার সর্বোত্তম সমাধান, না বিকল্প রয়েছে? এই পদ্ধতিটি ব্যবহার করে টেবিলটি সময়মতো চূড়ান্ত আকার ধারণ করবে এবং এটি অনুসন্ধান করার জন্য আমি ধারনা করি না। অন্যদিকে, ক্যোয়ারীটি দ্রুত সম্পাদন করে এমনটি গুরুত্বপূর্ণ নয়।


উত্তর:


119

আমি বিশ্বাস করি আপনি এই ব্লগ পোস্ট আকর্ষণীয় পাবেন: ট্যাগ্স: ডেটাবেস স্কিমা

সমস্যা: আপনি একটি ডাটাবেস স্কিমা রাখতে চান যেখানে আপনি যতগুলি ট্যাগ বুকমার্ক (বা একটি ব্লগ পোস্ট বা যা কিছু) আপনার নিজের পছন্দ মতো ট্যাগ করতে পারেন। তারপরে, আপনি কোনও ইউনিয়ন বা ট্যাগের ছেদকে বুকমার্কগুলিকে সীমাবদ্ধ রাখতে কোয়েরি চালাতে চান। আপনি অনুসন্ধান ফলাফল থেকে কিছু ট্যাগ বাদ ((বিয়োগ: বিয়োগ)) করতে চান।

"মাইকিউএসকিউলিস" সমাধান

এই সমাধানে, স্কিমাটি কেবল একটি টেবিল পেয়েছে, এটি অস্বীকৃত। এই ধরণেরটিকে "মাইএসকিউসিলিউশন সমাধান" বলা হয় কারণ মাইএসকিউএসএল এই কাঠামোর সাথে একটি টেবিলের মধ্যে ডেল.সিও.ইউস ডেটা আমদানি করে।

এখানে চিত্র বর্ণনা লিখুনএখানে চিত্র বর্ণনা লিখুন

ছেদ (এবং) "অনুসন্ধান + ওয়েবসার্ভিস + সেমওয়েব" এর জন্য অনুসন্ধান:

SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags LIKE "%semweb%"

ইউনিয়ন (OR) "অনুসন্ধান | ওয়েবসার্ভিস | সেমওয়েব" এর জন্য অনুসন্ধান:

SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
OR tags LIKE "%webservice%"
OR tags LIKE "%semweb%"

"অনুসন্ধান + ওয়েবসার্ভিস-সেমওয়েব" এর জন্য বিয়োগ প্রশ্ন

SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags NOT LIKE "%semweb%"

"Scuttle" সমাধান

স্কটল তার ডেটা দুটি টেবিলগুলিতে সংগঠিত করে। সেই টেবিলটি "স্ক্যাসিগ্রাফিকেশনগুলি" হল "ট্যাগ"-টেবিল এবং "বুকমার্ক"-টেবিলের জন্য একটি বিদেশী কী পেয়েছে।

এখানে চিত্র বর্ণনা লিখুন

ছেদ (এবং) "বুকমার্ক + ওয়েবসার্ভিস + সেমওয়েব" এর জন্য অনুসন্ধান:

SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
HAVING COUNT( b.bId )=3

প্রথমত, সমস্ত বুকমার্ক-ট্যাগ সংমিশ্রণগুলি অনুসন্ধান করা হয়, যেখানে ট্যাগটি "বুকমার্ক", "ওয়েবসার্ভিস" বা "সেমওয়েব" (সি। ক্যাটাগরি ইন ইন ('বুকমার্ক', 'ওয়েবসার্ভিস', 'সেমওয়েব')) রয়েছে, তারপরে কেবল বুকমার্কগুলি যা অনুসন্ধান করা তিনটি ট্যাগই অ্যাকাউন্টে নেওয়া হয়েছে (হ্যাভিং COUNT (বি.বিআইডি) = 3)।

ইউনিয়ন (ওআর) "বুকমার্ক | ওয়েবসার্ভিস | সেমওয়েব" এর জন্য অনুসন্ধান: কেবলমাত্র অনুচ্ছেদটি ছেড়ে দিন এবং আপনার মিল রয়েছে :

SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId

বিয়োগ (বাদ দেওয়া) "বুকমার্ক + ওয়েবসার্ভিস-সেমওয়েব" এর জন্য ক্যোয়ারী, এটি: বুকমার্ক এবং ওয়েবসার্ভিস এবং নয় সেমওয়েব।

SELECT b. *
FROM scBookmarks b, scCategories c
WHERE b.bId = c.bId
AND (c.category IN ('bookmark', 'webservice'))
AND b.bId NOT
IN (SELECT b.bId FROM scBookmarks b, scCategories c WHERE b.bId = c.bId AND c.category = 'semweb')
GROUP BY b.bId
HAVING COUNT( b.bId ) =2

HAVING COUNT এড়িয়ে যাওয়া "বুকমার্ক | ওয়েবসার্ভিস-সেমওয়েব" এর অনুসন্ধানের দিকে নিয়ে যায়।


"টক্সি" সমাধান

টক্সি তিনটি টেবিল কাঠামো নিয়ে এসেছিল। টেবিলের মাধ্যমে "ট্যাগম্যাপ" বুকমার্কগুলি এবং ট্যাগগুলি এন-টু-মি সম্পর্কিত। প্রতিটি ট্যাগ একসাথে বিভিন্ন বুকমার্ক এবং বিপরীতে ব্যবহার করা যেতে পারে। এই ডিবি-স্কিমাটি ওয়ার্ডপ্রেস দ্বারাও ব্যবহৃত হয়। প্রশ্নগুলি "স্কটল" সমাধানের মতো একই।

এখানে চিত্র বর্ণনা লিখুন

ছেদ (এবং) "বুকমার্ক + ওয়েবসার্ভিস + সেমওয়েব" এর জন্য অনুসন্ধান

SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
HAVING COUNT( b.id )=3

ইউনিয়ন (OR) "বুকমার্ক | ওয়েবসার্ভিস | সেমওয়েব" এর জন্য অনুসন্ধান

SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id

বিয়োগ (বাদ দেওয়া) "বুকমার্ক + ওয়েবসার্ভিস-সেমওয়েব" এর জন্য ক্যোয়ারী, এটি: বুকমার্ক এবং ওয়েবসার্ভিস এবং নয় সেমওয়েব।

SELECT b. *
FROM bookmark b, tagmap bt, tag t
WHERE b.id = bt.bookmark_id
AND bt.tag_id = t.tag_id
AND (t.name IN ('Programming', 'Algorithms'))
AND b.id NOT IN (SELECT b.id FROM bookmark b, tagmap bt, tag t WHERE b.id = bt.bookmark_id AND bt.tag_id = t.tag_id AND t.name = 'Python')
GROUP BY b.id
HAVING COUNT( b.id ) =2

HAVING COUNT এড়িয়ে যাওয়া "বুকমার্ক | ওয়েবসার্ভিস-সেমওয়েব" এর অনুসন্ধানের দিকে নিয়ে যায়।


4
এখানে যে ব্লগ পোস্ট লেখক। ব্লগ আর ক্রোম দ্বারা অবরুদ্ধ করা হয়নি (বোকা ওয়ার্ডপ্রেস দুর্বলতা, এখন tumblr এ সরানো হয়েছে)। এটিকে
মার্কডাউনে

হাই @ ফিলিপ ঠিক আছে, আমার উত্তর সম্পাদিত। বিটিডাব্লু, ডাটাবেস ট্যাগ সিস্টেমে দুর্দান্ত পোস্টের জন্য ধন্যবাদ।
নিক ডানডৌলাকিস

4
ঠিক যেমন একটি নোট: আপনি যদি 'বুকমার্ক' এবং 'ওয়েবসার্ভিস' অনুসন্ধান করেন তবে টক্সি সমাধানের জন্য ছেদ কোয়েরিটি বুকমার্কটি প্রদর্শন করতে চাইলে আপনাকে "হ্যাভিং COUNT (বি। আইডি) = 3" থেকে পরিবর্তন করতে হবে 3 থেকে "আকারে (অ্যারে ('বুকমার্ক', 'ওয়েবসার্ভিস'))"। আপনি যদি এটিকে গতিশীল ট্যাগ ক্যোয়ারী ফাংশন হিসাবে ব্যবহার করার পরিকল্পনা করেন তবে কেবলমাত্র একটি ছোট্ট বিশদ।
toxicate20

4
পোস্টে উল্লিখিত বিভিন্ন সমাধানের জন্য পারফরম্যান্স তুলনার জন্য কোনও লিঙ্ক?
কাম্পাতা

@ কম্পাতা, না, আমার কোনও লিঙ্ক নেই।
নিক ডানডৌলাকিস

8

আপনার তিন-সারণির সমাধানটিতে কোনও সমস্যা নেই।

আর একটি বিকল্প হ'ল কোনও নিবন্ধে প্রয়োগ করা যেতে পারে এমন ট্যাগগুলির সংখ্যা সীমাবদ্ধ করা (এসও তে 5 এর মতো) এবং সেগুলি সরাসরি আপনার নিবন্ধের সারণিতে যুক্ত করুন।

হার্ড-ওয়্যারিংয়ের জিনিসগুলিকে যেমন এক টেবিলের মধ্যে রাখা যেমন সুবিধাগুলি এবং ত্রুটিগুলি রয়েছে তেমনি ডিবিকে সাধারণকরণেরও এর সুবিধা এবং ত্রুটি রয়েছে।

কিছুই বলে না যে আপনি দুটোই করতে পারবেন না। তথ্য পুনরাবৃত্তি করতে এটি রিলেশনাল ডিবি দৃষ্টান্তগুলির বিরুদ্ধে যায়, তবে লক্ষ্যটি যদি পারফরম্যান্স হয় তবে আপনাকে দৃষ্টান্তগুলি ভেঙে যেতে পারে।


হ্যাঁ নিবন্ধগুলিতে সরাসরি ট্যাগগুলিতে রাখাই নিশ্চিতভাবেই একটি বিকল্প হতে পারে, যদিও এই পদ্ধতির কয়েকটি ত্রুটি রয়েছে। আপনি যদি 5 টি ট্যাগ কমা দ্বারা বিচ্ছিন্ন ক্ষেত্রের মতো (ট্যাগ 1,2,3,4) সঞ্চয় করেন তবে এটি একটি সহজ পদ্ধতি হবে। প্রশ্নটি যদি অনুসন্ধানে আরও দ্রুত চলে যায়। উদাহরণস্বরূপ, কেউ ট্যাগ 1 সহ সমস্ত কিছু দেখতে চায়, আপনাকে পুরো নিবন্ধের সারণীতে গর্ত করতে হবে। এটি ট্যাগ_ টু_আর্টিকাল সারণীতে ট্রাটে যাওয়ার পরে কম হবে। তবে তারপরে, ট্যাগ_ টু_আর্টিকাল টেবিলটি স্লিমার। আরেকটি বিষয় হ'ল আপনাকে পিএইচপিতে প্রতিবার বিস্ফোরণ করতে হবে, আমি জানি না এটি সময় নেয় কিনা।
সাইফ বেকহান

যদি আপনি উভয়ই করেন (ট্যাগ ডাব্লু / নিবন্ধ, এবং পৃথক সারণিতে) তবে এটি আপনাকে পোস্ট-কেন্দ্রিক অনুসন্ধান এবং ট্যাগকেন্দ্রিক অনুসন্ধানের জন্য উভয়ই পারফরম্যান্স দেয়। বারবার তথ্য বজায় রাখার বোঝা হ'ল ট্রেড অফ। এছাড়াও, ট্যাগগুলির সংখ্যা সীমাবদ্ধ করে আপনি প্রত্যেককে তার নিজস্ব কলামে রাখতে পারেন। যেখানে XXXXX আছে এবং নিবন্ধগুলি থেকে কেবল * নির্বাচন করুন; কোন বিস্ফোরণ প্রয়োজন।
জন

6

আপনার প্রস্তাবিত তিনটি সারণী বাস্তবায়ন ট্যাগিংয়ের জন্য কাজ করবে।

ওভারফ্লো ব্যবহার স্ট্যাক, তবে, বিভিন্ন বাস্তবায়ন। তারা সরল পাঠ্যে পোস্ট টেবিলের উপর ভারচার কলামে ট্যাগগুলি সঞ্চয় করে এবং ট্যাগগুলির সাথে মেলে এমন পোস্টগুলি আনতে সম্পূর্ণ পাঠ্য সূচী ব্যবহার করে। উদাহরণস্বরূপ posts.tags = "algorithm system tagging best-practices"। আমি নিশ্চিত যে জেফ এটি কোথাও উল্লেখ করেছেন তবে আমি কোথায় ভুলে গিয়েছি।


4
এটি অত্যন্ত অদক্ষ মনে হচ্ছে। ট্যাগ অর্ডার সম্পর্কে কি? বা সম্পর্কিত ট্যাগ? (যেমন "প্রক্রিয়া" "অ্যালগরিদম" বা এর মতো কোনও কিছুর অনুরূপ)
রিচার্ড ডিউর

3

প্রস্তাবিত সমাধানটি হ'ল ট্যাগ এবং নিবন্ধগুলির মধ্যে বহু থেকে বহু সম্পর্কের সমাধানের জন্য আমি ভাবতে পারি এমন একমাত্র ব্যবহারিক উপায় নয়। সুতরাং আমার ভোট 'হ্যাঁ, এটি এখনও সেরা' for যদিও আমি যে কোনও বিকল্পে আগ্রহী।


আমি রাজী. এই ট্যাগ এবং ট্যাগম্যাপ টেবিলগুলির ছোট রেকর্ড আকার থাকে এবং যখন সঠিকভাবে সূচিযুক্ত হয় তখন নাটকীয়ভাবে কর্মক্ষমতা হ্রাস করা উচিত নয়। আইটেম প্রতি নম্বর ওড ট্যাগ সীমাবদ্ধ করা ভাল ধারণা হতে পারে।
পানজানেক

2

যদি আপনার ডাটাবেস ইনডেক্সযোগ্য অ্যারেগুলিকে সমর্থন করে (উদাহরণস্বরূপ পোস্টগ্র্রেএসকিউএল), তবে আমি একটি সম্পূর্ণ অস্বীকৃত সমাধানের প্রস্তাব দেব - একই টেবিলে স্ট্রিংগুলির অ্যারে হিসাবে ট্যাগগুলি সঞ্চয় করুন। যদি তা না হয় তবে একটি দ্বিতীয় টেবিলকে ট্যাগগুলিতে ম্যাপিং করাই সেরা সমাধান। আপনি যদি ট্যাগগুলির তুলনায় অতিরিক্ত তথ্য সঞ্চয় করতে চান তবে আপনি একটি পৃথক ট্যাগ টেবিল ব্যবহার করতে পারেন, তবে প্রতিটি ট্যাগ দেখার জন্য দ্বিতীয় যোগদানের কোনও অর্থ নেই।


পোস্টগ্র্রেএসকিউএল কেবলমাত্র পূর্ণসংখ্যার অ্যারেতে সূচিগুলি সমর্থন করে: postgresql.org/docs/current/static/intarray.html
মাইক চেম্বারলাইন

4
নাওডিস এটি পাঠ্যের পক্ষেও সমর্থন করে: postgresql.org/docs/9.6/static/arrays.html
ভাগ্যডোনাল্ড

2

আমি আরও ভাল পারফরম্যান্সের জন্য অপ্টিমাইজড মাইএসকিউএসএলকে পরামর্শ দিতে চাই এর আগে টক্সির (3 টেবিল) সমাধানের ত্রুটিগুলি

যদি আপনার কয়েক মিলিয়ন প্রশ্ন থাকে এবং এর প্রতিটিতে 5 টি ট্যাগ থাকে তবে ট্যাগম্যাপের টেবিলে 5 মিলিয়ন এন্ট্রি থাকবে। তাই প্রথমে আমাদের ট্যাগ অনুসন্ধানের ভিত্তিতে 10 হাজার ট্যাগম্যাপ এন্ট্রি ফিল্টার করতে হবে এবং আবার সেই 10 হাজারের সাথে মিলে যাওয়া প্রশ্নগুলি ফিল্টার করতে হবে। সুতরাং ফিল্টারিংয়ের সময় যদি শৈল্পিক আইডিটি সহজ সংখ্যাসূচক হয় তবে তা ঠিক আছে তবে এটি যদি ইউইউইড (32 বর্ণের) ধরণের হয় তবে ফিল্টার আউটকে সূচকযুক্ত হওয়া সত্ত্বেও আরও বড় তুলনা করা দরকার।

আমার সমাধান:

যখনই নতুন ট্যাগ তৈরি হবে, তখন কাউন্টারে ++ (বেস 10) করুন এবং সেই কাউন্টারটিকে বেস 64 এ রূপান্তর করুন। এখন প্রতিটি ট্যাগ নামের বেস 64 আইডি থাকবে। এবং নামের সাথে এই আইডিটি ইউআইতে দিন। আমাদের সিস্টেমে 4095 ট্যাগ তৈরি না হওয়া পর্যন্ত আপনি সর্বোচ্চ দুটি চর আইডি পাবেন। এখন প্রতিটি প্রশ্ন টেবিল ট্যাগ কলামে এই একাধিক ট্যাগ একত্রীকরণ। পাশাপাশি ডিলিমিটার যুক্ত করুন এবং এটি বাছাই করুন।

সুতরাং টেবিলটি দেখতে এমন দেখাচ্ছে

এখানে চিত্র বর্ণনা লিখুন

জিজ্ঞাসা করার সময়, আসল ট্যাগ নামের পরিবর্তে আইডিতে ক্যোয়ারী। যেহেতু এটি বাছাইযুক্ত , তাই andট্যাগের শর্তটি আরও কার্যকর ( LIKE '%|a|%|c|%|f|%) হবে।

নোট করুন যে একক স্পেস ডিলিমিটার পর্যাপ্ত নয় এবং আমাদের মতো ট্যাগের আলাদা করতে ডাবল ডিলিমিটার প্রয়োজন sqlএবং mysqlকারণ ফলাফলগুলিও LIKE "%sql%"ফিরে আসবে mysql। হতে হবেLIKE "%|sql|%"

আমি জানি যে অনুসন্ধানটি আনডেক্সড নয় তবে এখনও আপনি লেখক / তারিখের মতো নিবন্ধের সাথে সম্পর্কিত অন্যান্য কলামগুলিতে সূচি রেখেছেন অন্য কোনওটি পুরো টেবিল স্ক্যানের দিকে পরিচালিত করবে।

অবশেষে এই সমাধানের সাথে, অভ্যন্তরীণ যোগদানের দরকার নেই যেখানে মিলিয়ন শুল্কগুলিকে যোগ দেওয়ার শর্তে 5 মিলিয়ন রেকর্ডের সাথে তুলনা করতে হবে।


দল, দয়া করে মন্তব্যে এই সমাধানের অপূর্ণতা সম্পর্কে আপনার ইনপুট সরবরাহ করুন।
কানগাভেলু সুগুমার

@ নিক ডানডৌলাকিস দয়া করে উপরের সমাধান সম্পর্কে আপনার মতামত সরবরাহ করে আমাকে সহায়তা করুন কাজ করবে?
কানগাভেলু সুগুমার

@ জুহা সিরাজলির উপরের সমাধানটি কি ঠিক আছে?
কানগাভেলু সুগুমার

0
CREATE TABLE Tags (
    tag VARHAR(...) NOT NULL,
    bid INT ... NOT NULL,
    PRIMARY KEY(tag, bid),
    INDEX(bid, tag)
)

মন্তব্য:

  • এটি টক্সির চেয়ে আরও ভাল যে এটি অতিরিক্ত অনেকের মধ্য দিয়ে যায় না: অনেক টেবিল যা অপ্টিমাইজেশনকে কঠিন করে তোলে।
  • নিশ্চয়ই, অপ্রয়োজনীয় ট্যাগগুলির কারণে আমার পদ্ধতির পরিমাণ কিছুটা বেশি (টক্সির চেয়ে) বেশি হতে পারে, তবে এটি পুরো ডাটাবেসের একটি ছোট শতাংশ , এবং পারফরম্যান্সের উন্নতিগুলি উল্লেখযোগ্য হতে পারে।
  • এটি অত্যন্ত স্কেলেবল।
  • এটিতে কোনও সার্গেট AUTO_INCREMENTপিকে নেই (কারণ এটির প্রয়োজন নেই) । সুতরাং, এটি স্কটলের চেয়ে ভাল।
  • (MySQLicious sucks কারণ এটি একটি সূচক ব্যবহার করতে পারবেন না LIKEসঙ্গে নেতৃস্থানীয় ; সাবস্ট্রিং মিথ্যা হিট বন্য কার্ড)
  • মাইএসকিউএলের জন্য, 'ক্লাস্টারিং' প্রভাবগুলি পেতে ENGINE = InnoDB ব্যবহার করা নিশ্চিত করুন।

সম্পর্কিত আলোচনা (মাইএসকিউএল এর জন্য):
অনেকগুলি: অনেকগুলি ম্যাপিং টেবিল অপ্টিমাইজেশান
তালিকার আদেশ দেয়

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.