আপনার মোটেই ট্রিগার বা পিএল / পিজিএসকিউএল দরকার নেই।
এমনকি আপনার বাধাও দরকার DEFERRABLE নেই।
এবং আপনার কোনও তথ্য অপ্রয়োজনীয়ভাবে সংরক্ষণ করার দরকার নেই।
usersসারণিতে সক্রিয় ইমেলের আইডি অন্তর্ভুক্ত করুন , যার ফলে পারস্পরিক রেফারেন্স আসে। কেউ ভাবতে পারেন যে DEFERRABLEএকজন ব্যবহারকারী এবং তার সক্রিয় ইমেল ofোকানোর মুরগি এবং ডিমের সমস্যা সমাধানের জন্য আমাদের বাধা প্রয়োজন , তবে ডেটা-মডিফাইং সিটিই ব্যবহার করে আমাদের এটির প্রয়োজনও নেই।
এটি সর্বদা ব্যবহারকারী প্রতি ঠিক একটি সক্রিয় ইমেল প্রয়োগ করে :
CREATE TABLE users (
user_id serial PRIMARY KEY
, username text NOT NULL
, email_id int NOT NULL -- FK to active email, constraint added below
);
CREATE TABLE email (
email_id serial PRIMARY KEY
, user_id int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE
, email text NOT NULL
, CONSTRAINT email_fk_uni UNIQUE(user_id, email_id) -- for FK constraint below
);
ALTER TABLE users ADD CONSTRAINT active_email_fkey
FOREIGN KEY (user_id, email_id) REFERENCES email(user_id, email_id);
"সর্বাধিক একটি সক্রিয় ইমেল" তৈরি করতে এই NOT NULLসীমাবদ্ধতাটি সরিয়ে দিন users.email_id। (আপনি এখনও প্রতি ব্যবহারকারী একাধিক ইমেল সঞ্চয় করতে পারেন, তবে এর মধ্যে কোনওটিই "সক্রিয়" নয়))
আপনি করতে পারেন করতে active_email_fkey DEFERRABLEআরো অতি সামান্য বিচ্যুতি (পৃথক কমান্ড ব্যবহারকারী এবং ইমেল সন্নিবেশ করার অনুমতি একই লেনদেনের), কিন্তু যে প্রয়োজন হয় না ।
আমি সূচক কভারেজটি অনুকূল user_idকরতে UNIQUEসীমাবদ্ধতায় প্রথমে রেখেছি email_fk_uni। বিবরণ:
Viewচ্ছিক দর্শন:
CREATE VIEW user_with_active_email AS
SELECT * FROM users JOIN email USING (user_id, email_id);
আপনি কীভাবে সক্রিয় ইমেল দিয়ে নতুন ব্যবহারকারীদের প্রবেশ করান তা এখানে (প্রয়োজনীয় হিসাবে):
WITH new_data(username, email) AS (
VALUES
('usr1', 'abc@d.com') -- new users with *1* active email
, ('usr2', 'def3@d.com')
, ('usr3', 'ghi1@d.com')
)
, u AS (
INSERT INTO users(username, email_id)
SELECT n.username, nextval('email_email_id_seq'::regclass)
FROM new_data n
RETURNING *
)
INSERT INTO email(email_id, user_id, email)
SELECT u.email_id, u.user_id, n.email
FROM u
JOIN new_data n USING (username);
সুনির্দিষ্ট অসুবিধাটি হ'ল আমাদের আর user_idনা email_idশুরু করার দরকার to উভয়ই স্ব স্ব সম্পর্কিত ক্রমিক সংখ্যা SEQUENCE। এটি একটি একক RETURNINGধারা (অন্য মুরগী এবং ডিমের সমস্যা) দিয়ে সমাধান করা যায় না। সমাধান nextval()হিসাবে নীচে লিঙ্ক উত্তরে বিস্তারিতভাবে ব্যাখ্যা ।
আপনি যদি কলামটির সাথে সংযুক্ত ক্রমের নামটি না জানেন তবে আপনি প্রতিস্থাপন করতে পারেন:serialemail.email_id
nextval('email_email_id_seq'::regclass)
সঙ্গে
nextval(pg_get_serial_sequence('email', 'email_id'))
আপনি কীভাবে একটি নতুন "সক্রিয়" ইমেল যুক্ত করবেন তা এখানে:
WITH e AS (
INSERT INTO email (user_id, email)
VALUES (3, 'new_active@d.com')
RETURNING *
)
UPDATE users u
SET email_id = e.email_id
FROM e
WHERE u.user_id = e.user_id;
এসকিউএল ফিডল।
কিছু সাধারণ-মনের ওআরএম যদি এটিকে মোকাবেলার জন্য যথেষ্ট স্মার্ট না হয় তবে আপনি সার্ভার-সাইড ফাংশনে এসকিউএল কমান্ডগুলি সজ্জিত করতে পারেন।
নিবিড়ভাবে সম্পর্কিত, যথেষ্ট ব্যাখ্যা সহ:
সম্পর্কিত:
DEFERRABLEবাধা সম্পর্কে :
সম্পর্কে nextval()এবং pg_get_serial_sequence():