পোস্টগ্র্যাসএসকিউএল বহু-কলামের স্বতন্ত্র সীমাবদ্ধতা এবং নাল মান


93

আমার নীচের মত একটি টেবিল আছে:

create table my_table (
    id   int8 not null,
    id_A int8 not null,
    id_B int8 not null,
    id_C int8 null,
    constraint pk_my_table primary key (id),
    constraint u_constrainte unique (id_A, id_B, id_C)
);

এবং আমি যে (id_A, id_B, id_C)কোনও পরিস্থিতিতে স্বতন্ত্র হতে চাই । সুতরাং নিম্নলিখিত দুটি প্রবেশের ফলে অবশ্যই একটি ত্রুটি ঘটতে পারে:

INSERT INTO my_table VALUES (1, 1, 2, NULL);
INSERT INTO my_table VALUES (2, 1, 2, NULL);

তবে এটি আশানুরূপ আচরণ করে না কারণ ডকুমেন্টেশন অনুসারে দুটি NULLমান একে অপরের সাথে তুলনা করা হয় না, তাই উভয় সন্নিবেশ ত্রুটি ছাড়াই পাস করে।

আমি আমার অনন্য বাধ্যতা কীভাবে নিশ্চিত করতে পারে না এমনকি যদি id_Cহতে পারে NULLএই ক্ষেত্রে? আসলে, আসল প্রশ্নটি: আমি কি এই ধরণের স্বতন্ত্রতার জন্য "খাঁটি এসকিএল" এর গ্যারান্টি দিতে পারি বা এটি কি উচ্চতর স্তরে প্রয়োগ করতে হবে (আমার ক্ষেত্রে জাভা)?


সুতরাং, আপনি মান বলতে (1,2,1)এবং (1,2,2)(A,B,C)কলাম। একটি (1,2,NULL)যোগ করার অনুমতি দেওয়া উচিত বা না?
ypercubeᵀᴹ

A এবং B নাল হতে পারে না তবে সি নাল বা কোনও ধনাত্মক পূর্ণসংখ্যার মান হতে পারে। সুতরাং (1,2,3) এবং (2,4, নাল) বৈধ তবে (নাল, 2,3) বা (1, নাল, 4) অবৈধ। এবং [(1,2, নাল), (1,2,3)] অনন্য বাধা ভঙ্গ করে না তবে [(1,2, নাল), (1,2, নাল)] এটি অবশ্যই ভেঙে ফেলবে।
ম্যানুয়েল লেডুক

2
এমন কোনও মান আছে যা এই কলামগুলিতে কখনই উপস্থিত হবে না (যেমন নেতিবাচক মান?)
এ_ ঘোড়া_বিহীন_নাম_নামা

আপনাকে পিজিতে আপনার সীমাবদ্ধতা লেবেল করতে হবে না। এটি স্বয়ংক্রিয়ভাবে একটি নাম তৈরি করবে। শুধু এফওয়াইআই।
ইভান ক্যারল

উত্তর:


93

আপনি খাঁটি এসকিউএল এ এটি করতে পারেন । আপনার কাছে থাকা ছাড়াও আংশিক অনন্য সূচক তৈরি করুন :

CREATE UNIQUE INDEX ab_c_null_idx ON my_table (id_A, id_B) WHERE id_C IS NULL;

এইভাবে আপনি (a, b, c)আপনার টেবিলের জন্য প্রবেশ করতে পারেন :

(1, 2, 1)
(1, 2, 2)
(1, 2, NULL)

তবে এর কোনওটিই দ্বিতীয়বার নয়।

অথবা দুটি আংশিক UNIQUEসূচক এবং সম্পূর্ণ সূচি (বা সীমাবদ্ধতা) ব্যবহার করবেন না। সেরা সমাধান আপনার প্রয়োজনীয়তার বিবরণের উপর নির্ভর করে। তুলনা করা:

যদিও UNIQUEসূচকের একক নালামযোগ্য কলামের জন্য এটি মার্জিত একটি দক্ষ , তবে এটি আরও বেশি সময়ের জন্য হাতছাড়া হয়ে যায়। এটি নিয়ে আলোচনা হচ্ছে - এবং আংশিক সূচকগুলির সাথে কীভাবে ইউপিএসআরটি ব্যবহার করবেন:

Asides

PostgreSQL এ ডাবল উদ্ধৃতি ব্যতীত মিশ্র কেস শনাক্তকারীদের জন্য ব্যবহার করবেন না।

আপনি পারে একটি বিবেচনা serialকলাম প্রাথমিক কী হিসাবে অথবা একটি IDENTITYকলাম Postgres মধ্যে 10 টি বা তার পরে। সম্পর্কিত:

তাই:

CREATE TABLE my_table (
   my_table_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY  -- for pg 10+
-- my_table_id bigserial PRIMARY KEY  -- for pg 9.6 or older
 , id_a int8 NOT NULL
 , id_b int8 NOT NULL
 , id_c int8
 , CONSTRAINT u_constraint UNIQUE (id_a, id_b, id_c)
);

যদি আপনি আপনার টেবিলের জীবদ্দশায় (২4৪7483838364 27) ২ বিলিয়নেরও বেশি সজ্জিত না হন (বর্জ্য এবং মুছে ফেলা সারিগুলি সহ), integer(8 বাইট) এর পরিবর্তে (4 বাইট) বিবেচনা করুন bigint


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

12

আমারও একই সমস্যা ছিল এবং আমি টেবিলের মধ্যে অনন্য ন্যূনল থাকার অন্য একটি উপায় খুঁজে পেয়েছি।

CREATE UNIQUE INDEX index_name ON table_name( COALESCE( foreign_key_field, -1) )

আমার ক্ষেত্রে ক্ষেত্রটি foreign_key_fieldইতিবাচক পূর্ণসংখ্যার এবং কখনই -1 হবে না।

সুতরাং, ম্যানুয়াল লেডুকে উত্তর দেওয়ার জন্য, আরও একটি সমাধান হতে পারে

CREATE UNIQUE INDEX  u_constrainte (COALESCE(id_a, -1), COALESCE(id_b,-1),COALESCE(id_c, -1) )

আমি ধরে নিলাম আইডিগুলি -1 হবে না।

আংশিক সূচক তৈরির সুবিধা কী?
যদি আপনার কাছে নুল শুল্ক নেই id_a, id_bএবং id_cকেবল একবারে একসাথে নুল হতে পারে।
আংশিক সূচকের সাথে, 3 টি ক্ষেত্র একাধিকবার নাল হতে পারে।


3
> আংশিক সূচক তৈরির সুবিধা কী? আপনি এটিটি যেভাবে দিয়ে করেছেন তা COALESCEসদৃশগুলিকে সীমাবদ্ধ রাখতে কার্যকর হতে পারে, তবে সূচকটি তার এক্সপ্রেশন সূচক হিসাবে অনুসন্ধানে খুব কার্যকর হবে না যা সম্ভবত ক্যোয়ারী এক্সপ্রেশনগুলির সাথে মেলে না। এটি হ'ল যদি না আপনি SELECT COALESCE(col, -1) ...সূচককে আঘাত করবেন না।
বো জিনেস

@ BoJeanes সূচকটি পারফরম্যান্স সমস্যার জন্য তৈরি করা হয়নি। এটি ব্যবসায়ের প্রয়োজনীয়তা পূরণ করার জন্য তৈরি করা হয়েছে।
লুক এম

8

একটি নুল অর্থ এই মুহূর্তে সেই সারিটির জন্য জানা যায় না তবে ভবিষ্যতে ( FinishDateদৌড়ের উদাহরণ হিসাবে Project) বা এই সারিটির জন্য কোনও মান প্রয়োগ করা যায় না (উদাহরণস্বরূপ EscapeVelocityএকটি কৃষ্ণগহ্বরের জন্য Star) এটি যুক্ত করা যেতে পারে ।

আমার মতে, সমস্ত নালগুলি সরিয়ে টেবিলগুলিকে সাধারণকরণ করা ভাল better

আপনার ক্ষেত্রে, আপনি NULLsআপনার কলামে অনুমতি দিতে চান , তবুও আপনি চান কেবল একটির NULLঅনুমতি দেওয়া হোক। কেন? দুটি টেবিলের মধ্যে এটি কী ধরনের সম্পর্ক?

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


2
আমার ক্ষেত্রে NULL সত্যিই NULL (আইডি_সি উদাহরণস্বরূপ টেবিল_সি এর একটি বিদেশী কী, যাতে এটি -1 মান থাকতে পারে না), এর অর্থ তাদের "my_table" এবং "table_c" এর মধ্যে কোনও সম্পর্ক নেই। সুতরাং এটির একটি কার্যকরী স্বাক্ষর রয়েছে। যাইহোক, [(1, 1,1, নাল), (2, 1,2, নাল), (3,2,4, নাল)] sertedোকানো ডেটার একটি বৈধ তালিকা।
ম্যানুয়েল লেডুক

1
এটি এসকিউএল হিসাবে ব্যবহৃত আসলেই নাল নয় কারণ আপনি সমস্ত সারিটিতে কেবল একটি চান want আপনি আপনার ডাটাবেস স্কিমাটি পরিবর্তন করতে পারেন -1-কে টেবিল_সি যুক্ত করে অথবা অন্য সারণী যুক্ত করে (যা সাব-টাইপ টেবিল_সিতে সুপার টাইপ হবে)।
ypercubeᵀᴹ

3
আমি কেবল @ ম্যানুয়েলের দিকে ইঙ্গিত করতে চাই যে এই উত্তরের নাল সম্পর্কে মতামত সর্বজনীনভাবে অনুষ্ঠিত হয় না এবং এটি অনেক বিতর্কিত। আমার মতো অনেকেই মনে করেন যে নাল আপনার পছন্দসই কোনও উদ্দেশ্যে ব্যবহার করা যেতে পারে (তবে প্রতিটি ক্ষেত্রের জন্য কেবল একটি জিনিস বোঝানো উচিত এবং সম্ভবত ক্ষেত্রের নাম বা একটি কলামের মন্তব্যে ডকুমেন্ট করা উচিত)
জ্যাক ডগলাস

1
যখন আপনার কলামটি একটি বিদেশী কী হবে তখন আপনি একটি ডামি মান ব্যবহার করতে পারবেন না।
লুক এম

1
+1 আমি আপনার সাথে রয়েছি: আমরা যদি কলামগুলির কিছু সংমিশ্রণটি অনন্য হতে চাই তবে আপনার একটি সত্তা বিবেচনা করা উচিত যেখানে কলামগুলির এই সমন্বয়টি পিকে। ওপি'র ডাটাবেস স্কিমা সম্ভবত পিতামাতার টেবিল এবং একটি সন্তানের পরিবর্তিত হওয়া উচিত।
একে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.