আপনার মোটেই ট্রিগার বা পিএল / পিজিএসকিউএল দরকার নেই।
এমনকি আপনার বাধাও দরকার 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()
হিসাবে নীচে লিঙ্ক উত্তরে বিস্তারিতভাবে ব্যাখ্যা ।
আপনি যদি কলামটির সাথে সংযুক্ত ক্রমের নামটি না জানেন তবে আপনি প্রতিস্থাপন করতে পারেন:serial
email.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()
: