আপনি যা বর্ণনা করছেন তাকে পলিমর্ফিক অ্যাসোসিয়েশন বলা হয়। এটি হ'ল "বিদেশী কী" কলামে একটি আইডি মান রয়েছে যা লক্ষ্য সারণির সেটগুলির মধ্যে একটিতে উপস্থিত থাকতে হবে। সাধারণত লক্ষ্য টেবিলগুলি কোনও উপায়ে সম্পর্কিত হয় যেমন ডেটাগুলির কিছু সাধারণ সুপারক্লাসের উদাহরণ। বিদেশী কী কলামের পাশাপাশি আপনার আরও একটি কলামের প্রয়োজন হবে, যাতে প্রতিটি সারিতে আপনি কোন লক্ষ্য সারণিকে রেফারেন্স করা যায় তা নির্ধারণ করতে পারেন।
CREATE TABLE popular_places (
user_id INT NOT NULL,
place_id INT NOT NULL,
place_type VARCHAR(10) -- either 'states' or 'countries'
-- foreign key is not possible
);
এসকিউএল সীমাবদ্ধতাগুলি ব্যবহার করে পলিমারফিক অ্যাসোসিয়েশনগুলির মডেল করার কোনও উপায় নেই। একটি বিদেশী কী বাধা সর্বদা একটি লক্ষ্য সারণী উল্লেখ করে ।
পলিমারফিক অ্যাসোসিয়েশনগুলি রেলস এবং হাইবারনেটের মতো ফ্রেমওয়ার্ক দ্বারা সমর্থিত। তবে তারা স্পষ্টতই বলেছে যে এই বৈশিষ্ট্যটি ব্যবহার করার জন্য আপনাকে অবশ্যই এসকিউএল সীমাবদ্ধতাগুলি অক্ষম করতে হবে। পরিবর্তে, অ্যাপ্লিকেশন বা ফ্রেমওয়ার্কটি অবশ্যই রেফারেন্সটি সন্তুষ্ট কিনা তা নিশ্চিত করার জন্য সমতুল্য কাজ করতে হবে। এটি হ'ল বিদেশী কীতে মান সম্ভাব্য টার্গেট সারণীর একটিতে উপস্থিত রয়েছে।
পলিমারফিক অ্যাসোসিয়েশনগুলি ডাটাবেসের ধারাবাহিকতা প্রয়োগের ক্ষেত্রে দুর্বল। ডেটা অখণ্ডতা সমস্ত ক্লায়েন্টদের উপর নির্ভর করে একই রেফারেন্সিয়াল অখণ্ডতা যুক্তিযুক্ত প্রয়োগ করে ডেটাবেস অ্যাক্সেস করে এবং প্রয়োগকারীটি অবশ্যই বাগ-মুক্ত থাকতে হবে।
এখানে কিছু বিকল্প সমাধান রয়েছে যা ডাটাবেস-প্রয়োগকারী রেফারেনশিয়াল অখণ্ডতার সুযোগ নেয়:
লক্ষ্য প্রতি একটি অতিরিক্ত টেবিল তৈরি করুন। উদাহরণস্বরূপ popular_states
এবং popular_countries
, যথাক্রমে কোন রেফারেন্স states
এবং countries
। এই "জনপ্রিয়" টেবিলগুলির প্রত্যেকটি ব্যবহারকারীর প্রোফাইলকেও উল্লেখ করে।
CREATE TABLE popular_states (
state_id INT NOT NULL,
user_id INT NOT NULL,
PRIMARY KEY(state_id, user_id),
FOREIGN KEY (state_id) REFERENCES states(state_id),
FOREIGN KEY (user_id) REFERENCES users(user_id),
);
CREATE TABLE popular_countries (
country_id INT NOT NULL,
user_id INT NOT NULL,
PRIMARY KEY(country_id, user_id),
FOREIGN KEY (country_id) REFERENCES countries(country_id),
FOREIGN KEY (user_id) REFERENCES users(user_id),
);
এর অর্থ এই নয় যে কোনও ব্যবহারকারীর জনপ্রিয় পছন্দের জায়গাগুলির জন্য আপনাকে এই দুটি সারণী উভয়েরই জিজ্ঞাসা করতে হবে। তবে এর অর্থ আপনি ধারাবাহিকতা প্রয়োগের জন্য ডাটাবেসের উপর নির্ভর করতে পারেন।
places
সুপার্টেবল হিসাবে একটি টেবিল তৈরি করুন । Abie উল্লেখ হিসাবে, একটি দ্বিতীয় বিকল্প আপনার জনপ্রিয় জায়গা মত একটা টেবিল রেফারেন্স places
, যা উভয় একটি অভিভাবক হয় states
এবং countries
। অর্থাৎ উভয় রাজ্যের ও দেশ এছাড়াও একটি বিদেশী কী আছে places
(আপনি এমনকি করতে পারেন এই বিদেশী কী এছাড়াও প্রাথমিক কী হতে states
এবং countries
)।
CREATE TABLE popular_areas (
user_id INT NOT NULL,
place_id INT NOT NULL,
PRIMARY KEY (user_id, place_id),
FOREIGN KEY (place_id) REFERENCES places(place_id)
);
CREATE TABLE states (
state_id INT NOT NULL PRIMARY KEY,
FOREIGN KEY (state_id) REFERENCES places(place_id)
);
CREATE TABLE countries (
country_id INT NOT NULL PRIMARY KEY,
FOREIGN KEY (country_id) REFERENCES places(place_id)
);
দুটি কলাম ব্যবহার করুন। দুটি লক্ষ্য সারণীর যে কোনও একটিতে উল্লেখ করতে পারে এমন কলামের পরিবর্তে দুটি কলাম ব্যবহার করুন। এই দুটি কলাম হতে পারে NULL
; আসলে এর মধ্যে শুধুমাত্র একটি অ হওয়া উচিত NULL
।
CREATE TABLE popular_areas (
place_id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
state_id INT,
country_id INT,
CONSTRAINT UNIQUE (user_id, state_id, country_id), -- UNIQUE permits NULLs
CONSTRAINT CHECK (state_id IS NOT NULL OR country_id IS NOT NULL),
FOREIGN KEY (state_id) REFERENCES places(place_id),
FOREIGN KEY (country_id) REFERENCES places(place_id)
);
রিলেশনাল তত্ত্বের ক্ষেত্রে, পলিমর্ফিক অ্যাসোসিয়েশনগুলি প্রথম সাধারণ ফর্মটি লঙ্ঘন করে , কারণ এটি popular_place_id
কার্যকরভাবে একটি কলাম দুটি অর্থ সহ: এটি হয় একটি রাষ্ট্র বা একটি দেশ। আপনি কোনও ব্যক্তির age
এবং phone_number
সেগুলি একটি একক কলামে সংরক্ষণ করবেন না এবং একই কারণে আপনার উভয় state_id
এবং country_id
একক কলামে সংরক্ষণ করা উচিত নয় । এই দুটি বৈশিষ্ট্যের সাথে সামঞ্জস্যপূর্ণ ডেটা টাইপ রয়েছে তা কাকতালীয়; তারা এখনও বিভিন্ন যৌক্তিক সত্তা বোঝায়।
পলিমারফিক অ্যাসোসিয়েশনগুলি তৃতীয় সাধারণ ফর্ম লঙ্ঘন করে , কারণ কলামটির অর্থ অতিরিক্ত কলামের উপর নির্ভর করে যা বিদেশী কী উল্লেখ করে সেই টেবিলের নাম দেয়। তৃতীয় নরমাল ফর্মে, একটি সারণীর কোনও বৈশিষ্ট্য অবশ্যই সেই টেবিলের প্রাথমিক কীতে নির্ভর করবে।
@ সাভাসভেদোভা থেকে মন্তব্য করুন:
আমি নিশ্চিত নন যে আমি টেবিলের সংজ্ঞা বা উদাহরণ কোয়েরি না করেই আপনার বিবরণটি অনুসরণ করেছি, তবে মনে হচ্ছে আপনার কেবল একাধিক Filters
টেবিল রয়েছে, প্রতিটিতে একটি বিদেশী কী রয়েছে যা একটি কেন্দ্রীয় Products
টেবিলের উল্লেখ করে ।
CREATE TABLE Products (
product_id INT PRIMARY KEY
);
CREATE TABLE FiltersType1 (
filter_id INT PRIMARY KEY,
product_id INT NOT NULL,
FOREIGN KEY (product_id) REFERENCES Products(product_id)
);
CREATE TABLE FiltersType2 (
filter_id INT PRIMARY KEY,
product_id INT NOT NULL,
FOREIGN KEY (product_id) REFERENCES Products(product_id)
);
...and other filter tables...
নির্দিষ্ট ধরণের ফিল্টারগুলিতে পণ্যগুলিতে যোগদান করা সহজ আপনি যদি জানেন যে আপনি কোন ধরণের সাথে যুক্ত হতে চান:
SELECT * FROM Products
INNER JOIN FiltersType2 USING (product_id)
আপনি যদি ফিল্টার প্রকারটি গতিশীল হতে চান তবে এসকিউএল কোয়েরিটি তৈরি করতে আপনাকে অবশ্যই অ্যাপ্লিকেশন কোডটি লিখতে হবে। এসকিউএলকে আপনার কোয়েরিটি লেখার সময় সারণি নির্দিষ্ট এবং নির্দিষ্ট করা দরকার। আপনি যোগদানের টেবিলটিকে স্বতন্ত্র সারিগুলির মধ্যে পাওয়া মানগুলির ভিত্তিতে গতিশীলভাবে চয়ন করতে পারবেন না Products
।
বাইরের যোগদানগুলি ব্যবহার করে সমস্ত ফিল্টার টেবিলগুলিতে যোগদানের একমাত্র অন্য বিকল্প । যাঁদের সাথে মেলে প্রোডাক্ট_আইডি নেই তাদের কেবল একটি নালার একক সারি হিসাবে ফেরত দেওয়া হবে। তবে আপনাকে এখনও যোগ হওয়া সমস্ত টেবিলগুলিকে হার্ডকোড করতে হবে এবং আপনি যদি নতুন ফিল্টার টেবিল যোগ করেন তবে আপনাকে আপনার কোড আপডেট করতে হবে।
SELECT * FROM Products
LEFT OUTER JOIN FiltersType1 USING (product_id)
LEFT OUTER JOIN FiltersType2 USING (product_id)
LEFT OUTER JOIN FiltersType3 USING (product_id)
...
সমস্ত ফিল্টার টেবিলগুলিতে যোগদানের আরেকটি উপায় হ'ল এটি ক্রমিকভাবে করা:
SELECT * FROM Product
INNER JOIN FiltersType1 USING (product_id)
UNION ALL
SELECT * FROM Products
INNER JOIN FiltersType2 USING (product_id)
UNION ALL
SELECT * FROM Products
INNER JOIN FiltersType3 USING (product_id)
...
তবে এই ফর্ম্যাটটির জন্য আপনাকে সমস্ত সারণীতে রেফারেন্স লিখতে হবে। এর আশেপাশে কোনও লাভ নেই।
join
সেইসাথে লক্ষ্যটিও পরিবর্তিত হবে ...... আমি কি খুব বেশি জটিলতা করছি বা কি? সাহায্য করুন!