পোস্টগ্রিজে ডিফেরেবল অনন্য সূচক


14

পরিবর্তনের টেবিলের জন্য পোস্টগ্রিজ ডকুমেন্টেশনের দিকে তাকালে মনে হয় নিয়মিত প্রতিবন্ধকতাগুলি চিহ্নিত করা যেতে পারে DEFERRABLE(আরও দৃ concrete়ভাবে INITIALLY DEFERRED, যা আমি আগ্রহী)।

সূচিগুলিও সীমাবদ্ধতার সাথে যুক্ত হতে পারে, যতক্ষণ না:

সূচীতে এক্সপ্রেশন কলাম থাকতে পারে না আংশিক সূচক হতে পারে

যা আমাকে বিশ্বাস করতে পরিচালিত করে বর্তমানে শর্তগুলির সাথে একটি অনন্য সূচক থাকার কোনও উপায় নেই, যেমন:

CREATE UNIQUE INDEX unique_booking
  ON public.booking
  USING btree
  (check_in, check_out)
  WHERE booking_status = 1;

হতে INITIALLY DEFERRED, যার অর্থ, যে স্বতন্ত্রতা 'বাধ্যতা' শুধুমাত্র লেনদেনের প্রান্তে যাচাই করা হবে (যদি SET CONSTRAINTS ALL DEFERRED;ব্যবহার করা হয়)।

আমার ধারণাটি কি সঠিক, এবং যদি তাই হয় তবে, অভ্যাসগত আচরণ অর্জনের কোনও উপায় আছে কি?

ধন্যবাদ

উত্তর:


15

একটি সূচক স্থগিত করা যায় না - এটি UNIQUEআঞ্চলিক বা না, তা কেবল UNIQUEবাধা নয় তা গুরুত্বপূর্ণ নয় । সীমাবদ্ধতার অন্য প্রকার ( FOREIGN KEY, PRIMARY KEY, EXCLUDEকিন্তু না -) এছাড়াও deferrable হয় CHECKসীমাবদ্ধতার।

সুতরাং অনন্য আংশিক সূচক (এবং এটি প্রয়োগ করে নিখুঁত প্রতিবন্ধকতা) লেনদেনের শেষে নয়, প্রতিটি বিবৃতিতে (এবং প্রকৃতপক্ষে বর্তমানের প্রয়োগের প্রতিটি সারি সন্নিবেশ / আপডেটের পরে) পরীক্ষা করা হবে।


আপনি কি করতে পারেন, যদি আপনি এই সীমাবদ্ধতা স্থগিত হিসাবে প্রয়োগ করতে চান, তা হ'ল ডিজাইনে আরও একটি সারণী যুক্ত করা। এটার মতো কিছু:

CREATE TABLE public.booking_status
  ( booking_id int NOT NULL,               -- same types
    check_in timestamp NOT NULL,           -- as in  
    check_out timestamp NOT NULL,          -- booking
    CONSTRAINT unique_booking
        UNIQUE (check_in, check_out)
        DEFERRABLE INITIALLY DEFERRED,
    CONSTRAINT unique_booking_fk
        FOREIGN KEY (booking_id, check_in, check_out)
        REFERENCES public.booking (booking_id, check_in, check_out)
        DEFERRABLE INITIALLY DEFERRED
  ) ;

এই নকশাটি এবং ধরে নিলে যে booking_statusকেবল দুটি সম্ভাব্য বিকল্প রয়েছে (0 এবং 1), আপনি এটিকে পুরোপুরি সরিয়ে ফেলতে bookingপারেন (যদি কোনও সারি থাকে তবে booking_statusএটি 1, যদি 0 না হয়)।


আরেকটি উপায় হ'ল (আব) EXCLUDEসীমাবদ্ধতা ব্যবহার করা :

ALTER TABLE booking
    ADD CONSTRAINT unique_booking
        EXCLUDE 
          ( check_in  WITH =, 
            check_out WITH =, 
            (CASE WHEN booking_status = 1 THEN TRUE END) WITH =
          ) 
        DEFERRABLE INITIALLY DEFERRED ;

ডিবিফিডেলে পরীক্ষা করা হয়েছে

উপরেরটি কী করে:

  • CASEঅভিব্যক্তি হয়ে NULLযখন booking_statusফাঁকা বা তুলনায় 1. বিভিন্ন আমরা লিখতে পারে (CASE WHEN booking_status = 1 THEN TRUE END)যেমন (booking_status = 1 OR NULL)যে যদি এটা তোলে কোনো আরো স্পষ্ট।

  • অনন্য এবং বাদ দেওয়া সীমাবদ্ধতাগুলি সারিগুলি গ্রহণ করে যেখানে এক বা একাধিক অভিব্যক্তি নুল হয়। সুতরাং এটি ফিল্টার সূচক হিসাবে কাজ করে WHERE booking_status = 1

  • সমস্ত WITHঅপারেটর =তাই এটি একটি UNIQUEসীমাবদ্ধতা হিসাবে কাজ করে।

  • এই দুটি মিলিত একটি ফিল্টার অনন্য সূচক হিসাবে সীমাবদ্ধতা কাজ করে।

  • তবে এটি একটি সীমাবদ্ধতা এবং EXCLUDEসীমাবদ্ধতাগুলি স্থগিত করা যেতে পারে।


2
এক্সক্লুড সংস্করণটির জন্য +1, যা আমার প্রয়োজন ছিল। এক্সক্লুডের ক্ষমতাগুলি দেখানোর জন্য এখানে আরও একটি উদাহরণ রয়েছে: সাইবারটেক-
বেনিয়ামিন পিটার

(CASE WHEN booking_status = 1 THEN TRUE END) WITH =)এর সাথে প্রতিস্থাপন করা উচিত ) WHERE (booking_status = 1)কারণ "বর্ধনের সীমাবদ্ধতাগুলি একটি সূচক ব্যবহার করে প্রয়োগ করা হয়", এবং এই আংশিক সূচকটি আরও WHEREছোট এবং দ্রুত হবে - postgresql.org/docs/current/sql-createtable.html এবং postgresql.org/docs/current/sql- createindex.html
ডেনিস

1

যদিও এই প্রশ্নের বছর পেরিয়ে গেছে, আমি স্প্যানিশ স্পিকারদের জন্য স্পষ্ট করে বলতে চাই, টেস্টগুলি পোস্টগ্রিসে করা হয়েছে:

নিম্নলিখিত সীমাবদ্ধতাটি 1337 রেকর্ডের একটি সারণীতে যুক্ত করা হয়েছে, যেখানে কিটটি প্রাথমিক কী:

**Bloque 1**
ALTER TABLE ele_kitscompletos
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit) 

এটি টেবিলের জন্য অগ্রাহ্য নয় এমন একটি ডিফল্ট প্রাথমিক কী তৈরি করে যাতে পরবর্তী আপডেটের চেষ্টা করার সময় আমরা ত্রুটি পাই:

update ele_kitscompletos
set div_nkit = div_nkit + 1; 

ত্রুটি: সদৃশ কীটি স্বতন্ত্রতা সীমাবদ্ধতা লঙ্ঘন করে «অনন্য_ডিভ_নিকিট»

পোস্টগ্রিসে, প্রতিটি ROW- র জন্য একটি আপডেটের নির্ধারণ করা পুনরুদ্ধার বা চুক্তি পূরণ করেছে তা যাচাই করে।


চুক্তি অবিলম্বে তৈরি করা হয়েছে এবং প্রতিটি বিবৃতি পৃথকভাবে কার্যকর করা হয়:

ALTER TABLE ele_kitscompletos
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
DEFERRABLE INITIALLY IMMEDIATE

**Bloque 2**
BEGIN;   
UPDATE ele_kitscompletos set div_nkit = div_nkit + 1;
INSERT INTO public.ele_kitscompletos(div_nkit, otro_campo)
VALUES 
  (1338, '888150502');
COMMIT;

অনুসন্ধানের ঠিক আছে, 0 টি সারি প্রভাবিত হয়েছে (মৃত্যুর সময়: 0 এমএস; মোট সময়: 0 এমএস) অনুসন্ধানের ঠিক আছে, 1328 টি সারি প্রভাবিত হয়েছে (মৃত্যুদণ্ডের সময়: 858 এমএস; মোট সময়: 858 এমএস) ত্রুটি: লেভেল ডুপ্লিক্ট ভায়োলা সীমাবদ্ধ করা হয়েছে «অনন্য_ডিভ_নিকিট ET বিবরণ : ইয়া এক্সিস্টে লা ল্লেভে (Div_nkit) = (1338)।

এখানে এসআই প্রাথমিক কী পরিবর্তন করার অনুমতি দেয় কারণ এটি সম্পূর্ণ প্রথম সম্পূর্ণ বাক্য (1328 সারি) চালায়; তবে এটি লেনদেনের ক্ষেত্রে (বিগইন), চুক্তি কমিট না করে প্রতিটি বাক্য শেষ করার সাথে সাথে অবিলম্বে বৈধতা দেওয়া হয়, সুতরাং INSERT কার্যকর করার সময় ত্রুটি তৈরি করে। অবশেষে আমরা নিম্নলিখিতটি বাতিল চুক্তি তৈরি করেছি:

**Bloque 3**
ALTER TABLE public.ele_edivipol
DROP CONSTRAINT unique_div_nkit RESTRICT;   

ALTER TABLE ele_edivipol
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
DEFERRABLE INITIALLY DEFERRED

যদি আমরা ** ব্লক 2 ** এর প্রতিটি বিবৃতি পৃথকভাবে প্রতিটি বাক্য কার্যকর করি তবে INSERT এ কোনও ত্রুটি উত্পন্ন হয় না কারণ এটি বৈধতা দেয় না তবে চূড়ান্ত COMMIT কার্যকর করা হয় যেখানে এটি কোনও অসঙ্গতি খুঁজে পায়।


ইংরাজীতে সম্পূর্ণ তথ্যের জন্য আমি আপনাকে লিঙ্কগুলি পরীক্ষা করতে পরামর্শ দিচ্ছি:

গভীরতায় ডেফেরেবল এসকিউএল সীমাবদ্ধতা

অবিচ্ছিন্নভাবে তাত্ক্ষণিকভাবে ডিফেরাবল নয়

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