এসকিউএল করা সহজ নয় তবে এটি অসম্ভব নয়। আপনি যদি কেবল ডিডিএলের মাধ্যমে এটি প্রয়োগ করতে চান তবে ডিবিএমএসের DEFERRABLE
সীমাবদ্ধতাগুলি প্রয়োগ করতে হবে। এটি করা যেতে পারে (এবং পোস্টগ্রিসে কাজ করার জন্য এটি পরীক্ষা করা যেতে পারে, এটি তাদের প্রয়োগ করেছে):
-- lets create first the 2 tables, A and B:
CREATE TABLE a
( aid INT NOT NULL,
bid INT NOT NULL,
CONSTRAINT a_pk PRIMARY KEY (aid)
);
CREATE TABLE b
( bid INT NOT NULL,
aid INT NOT NULL,
CONSTRAINT b_pk PRIMARY KEY (bid)
);
-- then table R:
CREATE TABLE r
( aid INT NOT NULL,
bid INT NOT NULL,
CONSTRAINT r_pk PRIMARY KEY (aid, bid),
CONSTRAINT a_r_fk FOREIGN KEY (aid) REFERENCES a,
CONSTRAINT b_r_fk FOREIGN KEY (bid) REFERENCES b
);
এখানে "সাধারণ" নকশা রয়েছে, যেখানে প্রতিটি A
শূন্যের সাথে সম্পর্কিত হতে পারে, এক বা অনেকগুলি B
এবং প্রত্যেকটি B
শূন্য, এক বা বহু সম্পর্কিত হতে পারে A
।
"সম্পূর্ণ অংশগ্রহণ" বিধিনিষেধের বিপরীত ক্রমে বাধা প্রয়োজন ( যথাক্রমে A
এবং B
যথাক্রমে, রেফারেন্সিং R
)। রয়ে FOREIGN KEY
(এক্স থেকে ওয়াই প্রয়োজন এবং এক্স ওয়াই থেকে) একটি বৃত্ত (একটি "চিকেন এবং ডিম" সমস্যা) গঠন করছে এবং যে কেন আমরা তাদের মধ্যে একজন অন্তত হতে হবে বিপরীত দিকে সীমাবদ্ধতার DEFERRABLE
। এক্ষেত্রে আমাদের দুটি চেনাশোনা রয়েছে ( A -> R -> A
এবং B -> R -> B
তাই আমাদের দুটি পিছনে ছাড়ার দরকার হয়:
-- then we add the 2 constraints that enforce the "total participation":
ALTER TABLE a
ADD CONSTRAINT r_a_fk FOREIGN KEY (aid, bid) REFERENCES r
DEFERRABLE INITIALLY DEFERRED ;
ALTER TABLE b
ADD CONSTRAINT r_b_fk FOREIGN KEY (aid, bid) REFERENCES r
DEFERRABLE INITIALLY DEFERRED ;
তারপরে আমরা পরীক্ষা করতে পারি যে আমরা ডেটা .োকাতে পারি। নোট করুন যে INITIALLY DEFERRED
প্রয়োজন হয় না। আমরা সীমাবদ্ধতাগুলি হিসাবে সংজ্ঞায়িত করতে পারতাম DEFERRABLE INITIALLY IMMEDIATE
তবে তারপরে SET CONSTRAINTS
লেনদেনের সময় আমাদের বিবৃতিটি তাদের পিছিয়ে দিতে ব্যবহার করতে হত । যদিও প্রতিটি ক্ষেত্রেই আমাদের একক লেনদেনে টেবিলগুলিতে toোকানো দরকার:
-- insert data
BEGIN TRANSACTION ;
INSERT INTO a (aid, bid)
VALUES
(1, 1), (2, 5),
(3, 7), (4, 1) ;
INSERT INTO b (aid, bid)
VALUES
(1, 1), (1, 2),
(2, 3), (2, 4),
(2, 5), (3, 6),
(3, 7) ;
INSERT INTO r (aid, bid)
VALUES
(1, 1), (1, 2),
(2, 3), (2, 4),
(2, 5), (3, 6),
(3, 7), (4, 1),
(4, 2), (4, 7) ;
END ;
এসকিউএলফিডেলে পরীক্ষিত ।
ডিবিএমএসের যদি DEFERRABLE
সীমাবদ্ধতা না থাকে তবে একটি কার্যবিধির মধ্যে A (bid)
এবং B (aid)
কলামগুলি সংজ্ঞায়িত করা উচিত NULL
। INSERT
পদ্ধতি / বিবৃতি তারপর প্রথম সন্নিবেশ করতে হবে A
এবং B
(ইন NULLs নির্বাণ bid
এবং aid
যথাক্রমে), তারপর মধ্যে সন্নিবেশ R
এবং তারপর থেকে সম্পর্কিত নাল না মান উপরে নাল মান আপডেট R
।
এই পদ্ধতির সঙ্গে, DBMS জোরদার নেই DDL দ্বারা প্রয়োজনীয়তা একা কিন্তু প্রত্যেক INSERT
(এবং UPDATE
এবং DELETE
এবং MERGE
) পদ্ধতি বিবেচনা করা এবং সেই অনুযায়ী স্থায়ী এবং ব্যবহারকারীদের ব্যবহার করতে এগুলিকে কেবল এবং টেবিল থেকে সরাসরি লেখার এক্সেস আছে সীমাবদ্ধ করা থাকতে হবে না।
FOREIGN KEY
সীমাবদ্ধতাগুলির মধ্যে চেনাশোনাগুলি থাকা অনেকগুলি সর্বোত্তম অনুশীলন এবং ভাল কারণে, জটিলতাগুলির মধ্যে অন্যতম বলে বিবেচিত হয় না। উদাহরণস্বরূপ (অণুযুক্ত কলাম সহ) দ্বিতীয় পদ্ধতির সাথে, সারিগুলি আপডেট করা এবং মুছে ফেলার কাজটি ডিবিএমএসের উপর নির্ভর করে অতিরিক্ত কোড সহ এখনও করতে হবে। উদাহরণস্বরূপ এসকিউএল সার্ভারে আপনি কেবল রাখতে পারবেন না ON DELETE CASCADE
কারণ যখন এফকে চেনাশোনা থাকে তখন ক্যাসকেডিং আপডেট এবং মোছার অনুমতি দেওয়া হয় না।
দয়া করে এই সম্পর্কিত প্রশ্নের উত্তরগুলিও পড়ুন:
কোনও সুবিধাবঞ্চিত সন্তানের সাথে কীভাবে একের সাথে একাধিক সম্পর্ক থাকবে?
আরেকটি, তৃতীয় পদ্ধতির (উপরে বর্ণিত প্রশ্নে আমার উত্তর দেখুন) পুরোপুরি বিজ্ঞপ্তি এফকে অপসারণ করা। তাই, কোড প্রথম অংশ পালন (টেবিল সঙ্গে A
, B
, R
এবং বিদেশী কী শুধুমাত্র আর থেকে A এবং B পর্যন্ত) প্রায় অক্ষত (আসলে সরল), আমরা আরেকটি সারণী জুড়ুন A
থেকে "থাকা আবশ্যক একটি" সংশ্লিষ্ট আইটেম সঞ্চয় করতে B
। সুতরাং, A (bid)
কলাম A_one (bid)
একই সরানো বি থেকে A এর বিপরীত সম্পর্কের জন্য করা হয়েছে:
CREATE TABLE a
( aid INT NOT NULL,
CONSTRAINT a_pk PRIMARY KEY (aid)
);
CREATE TABLE b
( bid INT NOT NULL,
CONSTRAINT b_pk PRIMARY KEY (bid)
);
-- then table R:
CREATE TABLE r
( aid INT NOT NULL,
bid INT NOT NULL,
CONSTRAINT r_pk PRIMARY KEY (aid, bid),
CONSTRAINT a_r_fk FOREIGN KEY (aid) REFERENCES a,
CONSTRAINT b_r_fk FOREIGN KEY (bid) REFERENCES b
);
CREATE TABLE a_one
( aid INT NOT NULL,
bid INT NOT NULL,
CONSTRAINT a_one_pk PRIMARY KEY (aid),
CONSTRAINT r_a_fk FOREIGN KEY (aid, bid) REFERENCES r
);
CREATE TABLE b_one
( bid INT NOT NULL,
aid INT NOT NULL,
CONSTRAINT b_one_pk PRIMARY KEY (bid),
CONSTRAINT r_b_fk FOREIGN KEY (aid, bid) REFERENCES r
);
1 ম এবং 2 য় পদ্ধতির মধ্যে পার্থক্য হ'ল কোনও বিজ্ঞপ্তি এফকে নেই, সুতরাং ক্যাসকেডিং আপডেট এবং ডিলিটগুলি ঠিক কাজ করবে। "সম্পূর্ণ অংশগ্রহণ" প্রয়োগকরণ কেবলমাত্র ডিডিএল দ্বারা নয়, যেমন 2 য় পদ্ধতির মতো এবং যথাযথ পদ্ধতি ( INSERT/UPDATE/DELETE/MERGE
) দ্বারা করতে হবে । ২ য় পদ্ধতির সাথে একটি সামান্য পার্থক্য হ'ল সমস্ত কলামগুলি স্থায়ী নয় এমন সংজ্ঞা দেওয়া যেতে পারে।
আর একটি, চতুর্থ পন্থা ( উপরে উল্লিখিত প্রশ্নের মধ্যে @ অ্যারন বার্ট্র্যান্ডের উত্তর দেখুন) ফিল্টারড / আংশিক অনন্য সূচকগুলি ব্যবহার করা হয় , যদি সেগুলি আপনার ডিবিএমএসে পাওয়া যায় ( R
এই ক্ষেত্রে আপনার দুটি টেবিলে দরকার হবে )। এটি 3 য় পদ্ধতির সাথে খুব সমান, আপনার অতিরিক্ত 2 টি সারণী লাগবে না। "সামগ্রিক অংশগ্রহণ" সীমাবদ্ধতা এখনও কোড দ্বারা প্রয়োগ করতে হবে।