অনন্য সীমাবদ্ধতা বনাম সূচক পোস্টগ্রিজ করে


157

আমি যেমন ডকুমেন্টেশন বুঝতে পারি নীচের সংজ্ঞাগুলি সমতুল্য:

create table foo (
    id serial primary key,
    code integer,
    label text,
    constraint foo_uq unique (code, label));

create table foo (
    id serial primary key,
    code integer,
    label text);
create unique index foo_idx on foo using btree (code, label);    

তবে পোস্টগ্রিস ৯.৪-এর ম্যানুয়ালটিতে একটি নোট বলেছে:

সারণীতে অনন্য বাধা যুক্ত করার পছন্দের উপায় হ'ল ALTER TABLE ... ADD CONSTRAINT। অনন্য প্রতিবন্ধকতাগুলি প্রয়োগ করতে সূচকগুলির ব্যবহার এমন একটি বাস্তবায়ন বিশদ হিসাবে বিবেচনা করা যেতে পারে যা সরাসরি অ্যাক্সেস করা উচিত নয়।

(সম্পাদনা করুন: পোস্টগ্রিস 9.5 সহ ম্যানুয়াল থেকে এই নোটটি সরানো হয়েছিল))

এটি কি কেবল ভাল স্টাইলের বিষয়? এই রূপগুলির মধ্যে একটির পছন্দসই ব্যবহারিক পরিণতিগুলি কী (উদাহরণস্বরূপ কার্য সম্পাদন)?


23
(কেবলমাত্র) পার্থক্যগত পার্থক্য হ'ল আপনি কোনও অনন্য বাধার জন্য একটি বিদেশী কী তৈরি করতে পারেন তবে কোনও অনন্য সূচকে নয়।
a_horse_with_no_name

29
অন্য উপায়ের চারপাশের একটি সুবিধা ( যেমনটি সম্প্রতি অন্য একটি প্রশ্নে উঠে এসেছে ) তা হ'ল আপনার একটি আংশিক অনন্য সূচক থাকতে পারে, যেমন "অনন্য (ফুও) যেখানে বার ইজ নুল"। আফাইক, বাধা দিয়ে তা করার কোনও উপায় নেই।
আইএমএসওপি

3
@ এ_হর্স_বিহীন_নাম_নাম কখন ঘটেছে তা আমি নিশ্চিত নই, তবে এটি আর সত্য বলে মনে হয় না। এই এসকিউএল ফ্রিডল একটি অনন্য সূচকে বিদেশী কী উল্লেখগুলি মঞ্জুরি দেয়: sqlfiddle.com/#!17/20ee9 ; সম্পাদনা: অনন্য সূচকে 'ফিল্টার' যুক্ত করা এটি কাজ করা বন্ধ করে দেয় (প্রত্যাশা অনুযায়ী)
ব্যবহারকারী 19353561

1
পোস্টগ্র্যাস ডকুমেন্টেশন থেকে: পোস্টগ্র্রেএসকিউএল স্বয়ংক্রিয়ভাবে একটি অনন্য সূচক তৈরি করে যখন কোনও সারণির জন্য কোনও অনন্য বাধা বা প্রাথমিক কী সংজ্ঞায়িত করা হয়। postgresql.org/docs/9.4/static/indexes-unique.html
ম্যাগগু

আমি @ user1935361 এর সাথে সম্মতি জানাই, যদি কোনও অনন্য সূচকে বিদেশী কী তৈরি করা সম্ভব না হত (কমপক্ষে পিজি 10 দিয়ে) আমি এই সমস্যাটি অনেক আগেই চালিত করতাম।
অ্যান্ডি

উত্তর:


132

এই বেসিক কিন্তু গুরুত্বপূর্ণ সমস্যাটি সম্পর্কে আমার কিছু সন্দেহ ছিল, তাই আমি উদাহরণ দিয়ে শিখার সিদ্ধান্ত নিয়েছি।

টেস্ট টেবিল তৈরি করা যাক মাস্টার দুটি কলাম সঙ্গে, con_id অনন্য বাধ্যতা সঙ্গে এবং ind_id অনন্য সূচক দ্বারা সূচীবদ্ধ।

create table master (
    con_id integer unique,
    ind_id integer
);
create unique index master_unique_idx on master (ind_id);

    Table "public.master"
 Column |  Type   | Modifiers
--------+---------+-----------
 con_id | integer |
 ind_id | integer |
Indexes:
    "master_con_id_key" UNIQUE CONSTRAINT, btree (con_id)
    "master_unique_idx" UNIQUE, btree (ind_id)

সারণির বিবরণে (ps d পিএসকিএল) আপনি অনন্য সূচক থেকে অনন্য বাধা বলতে পারেন।

অনন্যতা

আসুন স্বতন্ত্রতা পরীক্ষা করা যাক, সেক্ষেত্রে।

test=# insert into master values (0, 0);
INSERT 0 1
test=# insert into master values (0, 1);
ERROR:  duplicate key value violates unique constraint "master_con_id_key"
DETAIL:  Key (con_id)=(0) already exists.
test=# insert into master values (1, 0);
ERROR:  duplicate key value violates unique constraint "master_unique_idx"
DETAIL:  Key (ind_id)=(0) already exists.
test=#

এটি প্রত্যাশার মতো কাজ করে!

বিদেশী চাবি

এখন আমরা দুটি বিদেশী কী দিয়ে বিশদ টেবিলটি সংজ্ঞায়িত করব মাস্টারে আমাদের দুটি কলামে উল্লেখ করে ।

create table detail (
    con_id integer,
    ind_id integer,
    constraint detail_fk1 foreign key (con_id) references master(con_id),
    constraint detail_fk2 foreign key (ind_id) references master(ind_id)
);

    Table "public.detail"
 Column |  Type   | Modifiers
--------+---------+-----------
 con_id | integer |
 ind_id | integer |
Foreign-key constraints:
    "detail_fk1" FOREIGN KEY (con_id) REFERENCES master(con_id)
    "detail_fk2" FOREIGN KEY (ind_id) REFERENCES master(ind_id)

ভাল, কোন ত্রুটি। আসুন নিশ্চিত হয়ে নিন এটি কার্যকরভাবে কাজ করে।

test=# insert into detail values (0, 0);
INSERT 0 1
test=# insert into detail values (1, 0);
ERROR:  insert or update on table "detail" violates foreign key constraint "detail_fk1"
DETAIL:  Key (con_id)=(1) is not present in table "master".
test=# insert into detail values (0, 1);
ERROR:  insert or update on table "detail" violates foreign key constraint "detail_fk2"
DETAIL:  Key (ind_id)=(1) is not present in table "master".
test=#

উভয় কলাম বিদেশী কীতে উল্লেখ করা যেতে পারে।

সূচক ব্যবহার করে বাধা

বিদ্যমান অনন্য সূচকটি ব্যবহার করে আপনি সারণির সীমাবদ্ধতা যুক্ত করতে পারেন।

alter table master add constraint master_ind_id_key unique using index master_unique_idx;

    Table "public.master"
 Column |  Type   | Modifiers
--------+---------+-----------
 con_id | integer |
 ind_id | integer |
Indexes:
    "master_con_id_key" UNIQUE CONSTRAINT, btree (con_id)
    "master_ind_id_key" UNIQUE CONSTRAINT, btree (ind_id)
Referenced by:
    TABLE "detail" CONSTRAINT "detail_fk1" FOREIGN KEY (con_id) REFERENCES master(con_id)
    TABLE "detail" CONSTRAINT "detail_fk2" FOREIGN KEY (ind_id) REFERENCES master(ind_id)

এখন কলামের সীমাবদ্ধতার বর্ণনার মধ্যে কোনও পার্থক্য নেই।

আংশিক সূচি

সারণি সীমাবদ্ধতার ঘোষণায় আপনি আংশিক সূচক তৈরি করতে পারবেন না। এটা তোলে থেকে সরাসরি আসে সংজ্ঞা এর create table ...। অনন্য সূচক ঘোষণায় আপনি WHERE clauseআংশিক সূচক তৈরি করতে সেট করতে পারেন। আপনি এক্সপ্রেশনতে সূচকও তৈরি করতে পারেন (কেবল কলামে নয়) এবং কিছু অন্যান্য প্যারামিটার সংজ্ঞায়িত করতে পারেন (কোলিশেশন, সাজানোর ক্রম, NULLs স্থান নির্ধারণ)।

আপনি আংশিক সূচক ব্যবহার করে সারণির সীমাবদ্ধতা যুক্ত করতে পারবেন না

alter table master add column part_id integer;
create unique index master_partial_idx on master (part_id) where part_id is not null;

alter table master add constraint master_part_id_key unique using index master_partial_idx;
ERROR:  "master_partial_idx" is a partial index
LINE 1: alter table master add constraint master_part_id_key unique ...
                               ^
DETAIL:  Cannot create a primary key or unique constraint using such an index.

এটা কি আসল তথ্য? বিশেষত আংশিক সূচকগুলি সম্পর্কে
আনাতল

1
@ আনাটল - হ্যাঁ, এটি।
ক্লিন

30

UNIQUE INDEXবনাম ব্যবহারের আরও একটি সুবিধা UNIQUE CONSTRAINTহ'ল আপনি সহজেই DROP/ CREATEসূচকটি করতে পারেন CONCURRENTLY, তবে সীমাবদ্ধতার সাথে আপনি পারবেন না।


4
এএফআইএকি একসাথে একটি অনন্য সূচক বাদ দেওয়া সম্ভব নয়। postgresql.org/docs/9.3/static/sql-DPindex.html "এই বিকল্পটি ব্যবহার করার সময় সচেতন হওয়ার জন্য বেশ কয়েকটি সতর্কতা রয়েছে Only কেবলমাত্র একটি সূচকের নাম উল্লেখ করা যেতে পারে, এবং CASCADE বিকল্পটি সমর্থিত নয় Thus (সুতরাং, একটি সূচি এটি একটি অনন্য বা প্রাথমিক কী বাধা সমর্থন করে এইভাবে বাদ দেওয়া যাবে না)) "
রাফা সিইলাক

15

স্বতন্ত্রতা একটি বাধা। এটি একটি অনন্য সূচক তৈরির মাধ্যমে কার্যকর করা হয় যেহেতু একটি সূচক প্রদত্ত মান ইতিমধ্যে বিদ্যমান কিনা তা নির্ধারণের জন্য দ্রুত সমস্ত বিদ্যমান মান সন্ধান করতে সক্ষম হয়।

ধারণাগতভাবে সূচকটি একটি বাস্তবায়ন বিশদ এবং স্বতন্ত্রতা কেবলমাত্র সীমাবদ্ধতার সাথে যুক্ত হওয়া উচিত।

সম্পূর্ণ পাঠ্য

সুতরাং গতির পারফরম্যান্স একই হওয়া উচিত


4

আর একটি জিনিস যা আমি মুখোমুখি হলাম তা হ'ল আপনি অনন্য সূচকগুলিতে স্কয়ার এক্সপ্রেশন ব্যবহার করতে পারেন তবে সীমাবদ্ধতায় নয়।

সুতরাং, এটি কাজ করে না:

CREATE TABLE users (
    name text,
    UNIQUE (lower(name))
);

কিন্তু নিম্নলিখিত কাজ।

CREATE TABLE users (
    name text
);
CREATE UNIQUE INDEX uq_name on users (lower(name));

আমি citextএক্সটেনশনটি ব্যবহার করব ।
সিভ করা

@ এটি পাওয়া ব্যবহারের ক্ষেত্রে নির্ভর করে। কখনও কখনও আপনি কেস-সংবেদনশীল স্বতন্ত্রতা নিশ্চিত করার সময় কেসিং সংরক্ষণ করতে চান
সাম্পসন ক্রোলি

2

যেহেতু বিভিন্ন ব্যক্তি অনন্য সীমাবদ্ধতার তুলনায় অনন্য সূচির সুবিধা সরবরাহ করেছে, তাই এখানে একটি অসুবিধা রয়েছে: একটি অনন্য বাধা পিছিয়ে দেওয়া যায় (কেবলমাত্র লেনদেনের শেষে পরীক্ষা করা হয়), কোনও অনন্য সূচক হতে পারে না।


সমস্ত অনন্য সীমাবদ্ধতার একটি অনন্য সূচক দেওয়া থাকলে এটি কীভাবে হতে পারে?
ক্রিস

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

0

আমি এটি ডকটিতে পড়েছি:

টেবিল_সামগ্রী যুক্ত করুন [ভাল নয়]

এই ফর্মটি একই সিনট্যাক্স ব্যবহার করে একটি টেবিলের সাথে একটি নতুন বাধা যুক্ত করে CREATE TABLE, বিকল্পটি NOT VALID, যা বর্তমানে কেবল বিদেশী কী বাধাগুলির জন্য অনুমোদিত। বাধ্যতা হিসাবে চিহ্নিত করা হয়, তাহলে NOT VALID, সম্ভাব্য-লম্বা প্রাথমিক চেক যাচাই করার জন্য টেবিলে সব সারি সন্তুষ্ট যে বাধ্যতা হয় এড়ানো হয়েছেপরবর্তী সন্নিবেশ বা আপডেটের বিরুদ্ধে এখনও এই বাধা প্রয়োগ করা হবে (এটি রেফারেন্স সারণীতে কোনও মিলের সারি না থাকলে তারা ব্যর্থ হবে)। কিন্তু ডাটাবেসের করা হবে না অনুমান বাধ্যতা টেবিলে সব সারি জন্য ঝুলিতে পর্যন্ত এটি যাচাই বাধ্যতা বিকল্প ব্যবহার করে যাচাই করা হয়।

সুতরাং আমি মনে করি এটিই আপনি বাধা যুক্ত করে "আংশিক স্বাতন্ত্র্য" বলে।

এবং, কীভাবে স্বতন্ত্রতা নিশ্চিত করা যায় সে সম্পর্কে:

একটি অনন্য বাধা যুক্ত করা সীমাবদ্ধতায় তালিকাবদ্ধ কলামের কলাম বা গোষ্ঠীতে স্বয়ংক্রিয়ভাবে একটি অনন্য বি-ট্রি সূচক তৈরি করবে। কেবলমাত্র কয়েকটি সারি জুড়ে একটি স্বতন্ত্রতা সীমাবদ্ধতা অনন্য সীমাবদ্ধতা হিসাবে লেখা যায় না, তবে অনন্য আংশিক সূচক তৈরি করে এ জাতীয় বিধিনিষেধ প্রয়োগ করা সম্ভব।

দ্রষ্টব্য: কোনও টেবিলে অনন্য বাধা যুক্ত করার পছন্দের উপায়টি হ'ল ALTER TABLE… সংযুক্তি যুক্ত করুন। অনন্য প্রতিবন্ধকতাগুলি প্রয়োগ করতে সূচকগুলির ব্যবহার এমন একটি বাস্তবায়ন বিশদ হিসাবে বিবেচনা করা যেতে পারে যা সরাসরি অ্যাক্সেস করা উচিত নয়। তবে একটি সচেতন হওয়া উচিত যে অনন্য কলামগুলিতে ম্যানুয়ালি সূচী তৈরি করার দরকার নেই; এটি করার ফলে কেবল স্বয়ংক্রিয়ভাবে তৈরি সূচকটি নকল হবে।

সুতরাং স্বতন্ত্রতা নিশ্চিত করার জন্য আমাদের বাধা যুক্ত করা উচিত, যা একটি সূচক তৈরি করে।

আমি এই সমস্যাটি কীভাবে দেখছি?

একটি "সীমাবদ্ধতা" গ্রামীণভাবে এই কলামটি অনন্য হওয়া উচিত তা নিশ্চিত করে লক্ষ্য করা যায় , এটি একটি আইন, একটি নিয়ম প্রতিষ্ঠা করে; যদিও "সূচক" শব্দার্থানুক্রমিক , "কীভাবে প্রয়োগ করা যায়, স্বতন্ত্রতা কীভাবে অর্জন করতে হয়, বাস্তবায়নের ক্ষেত্রে কী অনন্য অর্থ বোঝায়" সম্পর্কে। সুতরাং, পোস্টগ্র্যাস্কেল যেভাবে এটি প্রয়োগ করে, তা অত্যন্ত যুক্তিসঙ্গত: প্রথমত, আপনি ঘোষণা করেন যে একটি কলামটি অনন্য হওয়া উচিত, তারপরে পোস্টগ্র্যাস্কেল আপনার জন্য একটি অনন্য সূচক যুক্ত করার বাস্তবায়ন যুক্ত করে


1
"সুতরাং আমি মনে করি এটিই আপনি বাধা যুক্ত করে" আংশিক স্বতন্ত্রতা "বলেছেন" " সূচকগুলি whereধারাটির মাধ্যমে রেকর্ডগুলির কেবলমাত্র একটি সু-সংজ্ঞায়িত উপসেটের জন্য প্রয়োগ করতে পারে , তাই আপনি সংজ্ঞা দিতে পারেন যে রেকর্ডগুলি অনন্য আইএফএফ তারা কিছু মানদণ্ডকে সন্তুষ্ট করে। এটি কেবল অনির্ধারিত রেকর্ডগুলির সেটগুলির সীমাবদ্ধতাগুলি অক্ষম করে যা সীমাবদ্ধতা তৈরি হওয়ার পূর্বাভাস দেয়। এটি সম্পূর্ণ আলাদা, এবং উত্তরটি উল্লেখযোগ্যভাবে কম কার্যকর, যদিও আমার ধারণা প্রগতিশীল স্থানান্তরের জন্য এটি সুবিধাজনক।
মাস্কলিন

0

লক করার মধ্যে পার্থক্য রয়েছে।
একটি সূচি যোগ করা সারণিতে পাঠ্য অ্যাক্সেসকে আটকাবে না।
বাধা যুক্ত করা একটি টেবিল লক রাখে (তাই সমস্ত নির্বাচনগুলি অবরুদ্ধ করা হয়) যেহেতু এটি ALL TABLE এর মাধ্যমে যুক্ত করা হয় ।


0

একটি সূক্ষ্ম কাজ যা কেবল সূচি দিয়ে নয় বাধা দিয়েই করা যেতে পারে ক্লজটি ব্যবহার করছে ON CONFLICT ON CONSTRAINT( এই প্রশ্নটি দেখুন )।

এটি কাজ করে না:

CREATE TABLE T (a INT PRIMARY KEY, b INT, c INT);
CREATE UNIQUE INDEX u ON t(b);

INSERT INTO T (a, b, c)
VALUES (1, 2, 3)
ON CONFLICT ON CONSTRAINT u
DO UPDATE SET c = 4
RETURNING *;

এটি উৎপন্ন করে:

[42704]: ERROR: constraint "u" for table "t" does not exist

সূচকে বাধা হিসাবে রূপান্তর করুন:

DROP INDEX u;
ALTER TABLE t ADD CONSTRAINT u UNIQUE (b);

এবং INSERTবিবৃতি এখন কাজ করে।

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