কীভাবে "ক্যাসকেড মুছে ফেলুন" সীমাবদ্ধতা যুক্ত করবেন?


163

পোস্টগ্র্যাসকিউএল 8-তে ON DELETE CASCADESকি পরেরটি বাদ না দিয়ে নিম্নলিখিত টেবিলের উভয় বিদেশী কী যুক্ত করা সম্ভব ?

# \d scores
        Table "public.scores"
 Column  |         Type          | Modifiers
---------+-----------------------+-----------
 id      | character varying(32) |
 gid     | integer               |
 money   | integer               | not null
 quit    | boolean               |
 last_ip | inet                  |
Foreign-key constraints:
   "scores_gid_fkey" FOREIGN KEY (gid) REFERENCES games(gid)
   "scores_id_fkey" FOREIGN KEY (id) REFERENCES users(id)

উভয় রেফারেন্স সারণী নীচে - এখানে:

# \d games
                                     Table "public.games"
  Column  |            Type             |                        Modifiers
----------+-----------------------------+----------------------------------------------------------
 gid      | integer                     | not null default nextval('games_gid_seq'::regclass)
 rounds   | integer                     | not null
 finished | timestamp without time zone | default now()
Indexes:
    "games_pkey" PRIMARY KEY, btree (gid)
Referenced by:
    TABLE "scores" CONSTRAINT "scores_gid_fkey" FOREIGN KEY (gid) REFERENCES games(gid)

এবং এখানে:

# \d users
                Table "public.users"
   Column   |            Type             |   Modifiers
------------+-----------------------------+---------------
 id         | character varying(32)       | not null
 first_name | character varying(64)       |
 last_name  | character varying(64)       |
 female     | boolean                     |
 avatar     | character varying(128)      |
 city       | character varying(64)       |
 login      | timestamp without time zone | default now()
 last_ip    | inet                        |
 logout     | timestamp without time zone |
 vip        | timestamp without time zone |
 mail       | character varying(254)      |
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "cards" CONSTRAINT "cards_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "catch" CONSTRAINT "catch_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "chat" CONSTRAINT "chat_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "game" CONSTRAINT "game_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "hand" CONSTRAINT "hand_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "luck" CONSTRAINT "luck_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "match" CONSTRAINT "match_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "misere" CONSTRAINT "misere_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "money" CONSTRAINT "money_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "pass" CONSTRAINT "pass_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "payment" CONSTRAINT "payment_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "rep" CONSTRAINT "rep_author_fkey" FOREIGN KEY (author) REFERENCES users(id)
    TABLE "rep" CONSTRAINT "rep_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "scores" CONSTRAINT "scores_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
    TABLE "status" CONSTRAINT "status_id_fkey" FOREIGN KEY (id) REFERENCES users(id)

এবং আমিও আশ্চর্য হয়েছি যে যদি পূর্বের টেবিলে 2 সূচি 'যুক্ত করা বুদ্ধিমান হয়?

আপডেট: আপনাকে ধন্যবাদ, এবং আমি মেলিং তালিকায় পরামর্শও পেয়েছি, আমি এটি 1 টি বিবৃতিতে এবং এভাবে স্পষ্টভাবে কোনও লেনদেন শুরু না করে পরিচালনা করতে পারি:

ALTER TABLE public.scores
DROP CONSTRAINT scores_gid_fkey,
ADD CONSTRAINT scores_gid_fkey
   FOREIGN KEY (gid)
   REFERENCES games(gid)
   ON DELETE CASCADE;

1
একটু ওটি, তবে আমি লক্ষ্য করেছি যে আপনি রেফারিং কলামগুলিতে সূচী তৈরি করেন নি (উদাহরণস্বরূপ, pref_scores.gid)। আপনি যদি এই টেবিলগুলিতে অনেকগুলি সারি পেয়ে থাকেন তবে রেফারেন্সযুক্ত টেবিলের মোছা ছাড়াই দীর্ঘ সময় নিতে হবে। কিছু ডাটাবেস স্বয়ংক্রিয়ভাবে রেফারেন্সিং কলামে একটি সূচক তৈরি করে; পোস্টগ্র্রেএসকিউএল এটি আপনার উপর ছেড়ে দেয়, যেহেতু কিছু ক্ষেত্রে এটি সার্থক নয়।
কেজিগ্রিটন

1
ধন্যবাদ! আমি প্রকৃতপক্ষে লক্ষ্য করেছি যে মুছে ফেলতে দীর্ঘ সময় লাগবে, তবে কারণটি তা জানতে পারিনি
আলেকজান্ডার ফারবার

1
বিদেশী কীগুলিতে সূচকগুলি সার্থক না হলে কোন ক্ষেত্রে তা ঘটবে?
আলেকজান্ডার ফারবার

2
আমি আপনার উত্তর আমার উত্তর অন্তর্ভুক্ত। (এই একক বিবৃতিটিও একটি একক লেনদেন।)
মাইক শেরিল 'ক্যাট রিকল'

2
@ আলেকজান্ডারফারবার: আপনি কখন এফকে এর রেফারেন্সিং কলাম (গুলি) এ কোনও সূচি বাদ দিতে চান? যখন অন্য কোনও সূচীর সাথে হুবহু মিল নেই যা যথেষ্ট পরিমাণে ভাল কাজ করবে (যেমন, আপনার ঘন ঘন সাদৃশ্য অনুসন্ধানগুলির জন্য একটি ট্রিগার সূচক থাকতে পারে যা এফকে মুছার জন্যও ঠিক আছে)। মুছে ফেলা খুব কম হয় এবং বন্ধ সময় নির্ধারিত করা যেতে পারে। যখন কোনও সারণীতে রেফারেন্সিং মানটির ঘন ঘন আপডেট থাকে। যখন রেফারেন্সিং টেবিলটি খুব ছোট তবে প্রায়শই আপডেট হয়। ব্যতিক্রমগুলি প্রায়শই পর্যাপ্ত হয়ে থাকে যে পোস্টগ্রেএসকিউএল সম্প্রদায় এটিকে স্বয়ংক্রিয় করার পরিবর্তে এর উপর নিয়ন্ত্রণ রাখতে পছন্দ করে।
কেজিগ্রিটন

উত্তর:


218

আমি নিশ্চিত যে আপনি কেবল on delete cascadeবিদ্যমান বৈদেশিক কী সীমাবদ্ধতায় যুক্ত করতে পারবেন না pretty আপনাকে প্রথমে সীমাবদ্ধতা ফেলে দিতে হবে, তারপরে সঠিক সংস্করণ যুক্ত করতে হবে। স্ট্যান্ডার্ড এসকিউএল-তে, আমি বিশ্বাস করি এটি করার সবচেয়ে সহজ উপায় হ'ল

  • একটি লেনদেন শুরু করুন,
  • বিদেশী চাবি ফেলে দিন,
  • এর সাথে একটি বিদেশী কী যুক্ত করুন on delete cascadeএবং শেষ পর্যন্ত
  • লেনদেন প্রতিশ্রুতিবদ্ধ

আপনি যে বিদেশী কী পরিবর্তন করতে চান তার পুনরাবৃত্তি করুন।

তবে পোস্টগ্র্যাসকিউএল-এর একটি মানহীন এক্সটেনশন রয়েছে যা আপনাকে একক এসকিউএল স্টেটমেন্টে একাধিক বাধা ক্লজ ব্যবহার করতে দেয়। উদাহরণ স্বরূপ

alter table public.scores
drop constraint scores_gid_fkey,
add constraint scores_gid_fkey
   foreign key (gid)
   references games(gid)
   on delete cascade;

আপনি যে বিদেশী কী বাধাটি বাদ দিতে চান তার নামটি যদি না জানেন তবে আপনি এটি pgAdminIII এ সন্ধান করতে পারেন (কেবল সারণির নামটি ক্লিক করুন এবং ডিডিএলটি দেখুন, বা "সীমাবদ্ধতাগুলি" না দেখা পর্যন্ত স্তরক্রমটি প্রসারিত করুন), অথবা আপনি তথ্য স্কিমা জিজ্ঞাসা করতে পারেন ।

select *
from information_schema.key_column_usage
where position_in_unique_constraint is not null

ধন্যবাদ, আমিও এটাই ভেবেছিলাম - তবে বিদেশী কীগুলি কী করব? এগুলি কি কেবল সীমাবদ্ধতাগুলি (নট নুলের সমান) যা সহজেই ফেলে দেওয়া যায় এবং আবার সংযোজন করা যায়?
আলেকজান্ডার ফারবার

2
@ আলেকজান্ডার ফারবার: হ্যাঁ, এগুলি নামকরণ করা হয়েছে যেগুলি আপনি সহজেই ড্রপ এবং যোগ করতে পারেন। তবে আপনি সম্ভবত কোনও লেনদেনের মধ্যে এটি করতে চান। আরও উত্তর সহ আমার উত্তর আপডেট।
মাইক শেরিল 'ক্যাট রিকল'

PgAdminIII- এ সন্ধান করার জন্য +1। এমনকি এটি আপনাকে ড্রপ কনসেন্ট্রেট এবং অ্যাডস কনট্রাস্ট কমান্ড দেয়, সুতরাং আপনি কেবল একটি ক্যোয়ারী উইন্ডোতে অনুলিপি করে আটকান এবং যা চান তা আদেশটি সম্পাদনা করতে পারেন।
ডেভ পাইল

: QUERY আপ লেখার পর, আমি আমার Postgres গুই (Navicat) আসুন আমাকে জাভাস্ক্রিপ্টে গার্বেজ গুই মধ্যে থেকে এই পরিবর্তন কি খেয়াল dl.dropboxusercontent.com/spa/quq37nq1583x0lf/wwqne-lw.png
danneu

বড় টেবিলগুলির জন্য, NOT VALIDএকটি পৃথক লেনদেনের মাধ্যমে এটি কী বৈধতা দেওয়া সম্ভব ? আমি এই সম্পর্কে একটি উত্তরহীন প্রশ্ন আছে ।
দ্য ক্লাউডলেসস্কি

11

@ মাইক শেরিল ক্যাট রিকলের উত্তরের ভিত্তিতে, এটি আমার জন্য কাজ করেছে:

ALTER TABLE "Children"
DROP CONSTRAINT "Children_parentId_fkey",
ADD CONSTRAINT "Children_parentId_fkey"
  FOREIGN KEY ("parentId")
  REFERENCES "Parent"(id)
  ON DELETE CASCADE;

5

ব্যবহার:

select replace_foreign_key('user_rates_posts', 'post_id', 'ON DELETE CASCADE');

ফাংশন:

CREATE OR REPLACE FUNCTION 
    replace_foreign_key(f_table VARCHAR, f_column VARCHAR, new_options VARCHAR) 
RETURNS VARCHAR
AS $$
DECLARE constraint_name varchar;
DECLARE reftable varchar;
DECLARE refcolumn varchar;
BEGIN

SELECT tc.constraint_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name 
FROM 
    information_schema.table_constraints AS tc 
    JOIN information_schema.key_column_usage AS kcu
      ON tc.constraint_name = kcu.constraint_name
    JOIN information_schema.constraint_column_usage AS ccu
      ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY' 
   AND tc.table_name= f_table AND kcu.column_name= f_column
INTO constraint_name, reftable, refcolumn;

EXECUTE 'alter table ' || f_table || ' drop constraint ' || constraint_name || 
', ADD CONSTRAINT ' || constraint_name || ' FOREIGN KEY (' || f_column || ') ' ||
' REFERENCES ' || reftable || '(' || refcolumn || ') ' || new_options || ';';

RETURN 'Constraint replaced: ' || constraint_name || ' (' || f_table || '.' || f_column ||
 ' -> ' || reftable || '.' || refcolumn || '); New options: ' || new_options;

END;
$$ LANGUAGE plpgsql;

সচেতন থাকুন: এই ফাংশনটি প্রাথমিক বিদেশী কীগুলির বৈশিষ্ট্যগুলি অনুলিপি করবে না । এটি কেবল বিদেশী টেবিলের নাম / কলামের নাম নেয়, বর্তমান কী ড্রপ করে এবং নতুন সাথে প্রতিস্থাপন করে।

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