পোস্টগ্রেএসকিউএল-তে একাধিক থেকে অনেকের সম্পর্ক কীভাবে কার্যকর করা যায়?


102

আমি বিশ্বাস করি শিরোনামটি স্ব-ব্যাখ্যামূলক। একাধিক থেকে অনেকের সম্পর্ক তৈরি করতে আপনি কীভাবে পোস্টগ্রাইএসকিউএলে টেবিলের কাঠামো তৈরি করেন।

আমার উদাহরণ:

Product(name, price);
Bill(name, date, Products);

4
বিল টেবিল থেকে পণ্যগুলি সরান, দুটি ক্ষেত্র সহ "বিল_প্রডাক্ট" নামে একটি নতুন সারণী তৈরি করুন: একটি পণ্যকে দেখানো, একটি বিলকে নির্দেশ করে। এই দুটি ক্ষেত্রটিকে এই নতুন টেবিলের প্রাথমিক কী তৈরি করুন।
— মার্ক বি

সুতরাং বিল_প্রডাক্টস (বিল, পণ্য); ? আর দুজনেই পিকে?
— রাদু ঘিওরঘিউউ 20'12

4
হ্যাঁ তারা স্বতন্ত্রভাবে তাদের নিজ নিজ টেবিলের দিকে নির্দেশ করে এফকে হতে চাইবে এবং তারা একসাথে নতুন টেবিলের জন্য পিকে হবেন।
— মার্ক বি

সুতরাং, বিল_প্রোডাক্ট (পণ্যের রেফারেন্স product.name, বিল রেফারেন্স বিল.নেম, (পণ্য, বিল) প্রাথমিক কী)?
— রাদু ঘিওরঘিউউ

তারা পণ্য এবং বিল টেবিলগুলির পিকে ক্ষেত্রগুলিকে তলিয়ে যাওয়ার নির্দেশ করবে।
— মার্ক বি

উত্তর:


307

এসকিউএল ডিডিএল (ডেটা সংজ্ঞা ভাষা) বিবৃতিগুলি দেখতে এরকম হতে পারে:

CREATE TABLE product (
  product_id serial PRIMARY KEY  -- implicit primary key constraint
, product    text NOT NULL
, price      numeric NOT NULL DEFAULT 0
);

CREATE TABLE bill (
  bill_id  serial PRIMARY KEY
, bill     text NOT NULL
, billdate date NOT NULL DEFAULT CURRENT_DATE
);

CREATE TABLE bill_product (
  bill_id    int REFERENCES bill (bill_id) ON UPDATE CASCADE ON DELETE CASCADE
, product_id int REFERENCES product (product_id) ON UPDATE CASCADE
, amount     numeric NOT NULL DEFAULT 1
, CONSTRAINT bill_product_pkey PRIMARY KEY (bill_id, product_id)  -- explicit pk
);

আমি কয়েকটি সামঞ্জস্য করেছি:

  • এই ক্ষেত্রে : n সম্পর্ক সাধারণত একটি পৃথক টেবিল দ্বারা প্রয়োগ করা হয় bill_product।

  • আমি সারোগেট প্রাথমিক কীserial হিসাবে কলামগুলি যুক্ত করেছি । পোস্টগ্রিসে 10 বা তার পরিবর্তে একটি কলাম বিবেচনা করুন। দেখা:IDENTITY

    আমি অত্যন্ত পরামর্শ দিচ্ছি, কারণ কোনও পণ্যের নামই খুব কমই অনন্য (কোনও ভাল "প্রাকৃতিক কী" নয়)। এছাড়াও, স্বতন্ত্রতা প্রয়োগ এবং বিদেশী কী কলাম উল্লেখ সাধারণত একটি 4 বাইট সঙ্গে সস্তা integer(অথবা এমনকি একটি 8-বাইট bigintএকটি স্ট্রিং হিসাবে সংরক্ষিত সঙ্গে তুলনায়) textঅথবা varchar।

  • প্রাথমিক তথ্য ধরণের নাম শনাক্তকারীdate হিসাবে ব্যবহার করবেন না । যদিও এটি সম্ভব, এটি খারাপ শৈলী এবং বিভ্রান্তিকর ত্রুটি এবং ত্রুটি বার্তাগুলির দিকে নিয়ে যায়। ব্যবহার করুন আইনগত, নিম্ন মামলা, unquoted শনাক্তকারী । সংরক্ষিত শব্দগুলি কখনই ব্যবহার করবেন না এবং যদি পারেন তবে ডাবল-কোটড মিশ্র কেস শনাক্তকারীদের এড়িয়ে চলুন।

  • "নাম" একটি ভাল নাম নয়। আমি টেবিলের কলাম নতুন নামকরণ productকরা product(অথবা product_nameবা অনুরূপ)। এটি একটি ভাল নামকরণ কনভেনশন । অন্যথায়, আপনি যখন কোনও ক্যোয়ারিতে কয়েকটি টেবিলের সাথে যুক্ত হন - যা আপনি একটি রিলেশনাল ডাটাবেসে অনেক কিছু করেন - আপনি "নাম" নামে একাধিক কলাম দিয়ে শেষ করেন এবং গণ্ডগোল বাছাইয়ের জন্য কলামের নাম ব্যবহার করতে হবে। এটি সহায়ক নয়। আর একটি বিস্তৃত এন্টি-প্যাটার্নটি কলামের নাম হিসাবে কেবল "আইডি" হবে।
    কোনটির নাম কী হবে তা আমি নিশ্চিত নই bill। bill_idসম্ভবত এই ক্ষেত্রে যথেষ্ট হবে।

  • priceভগ্নাংশের সংখ্যা নির্দিষ্টভাবে সন্নিবেশ করানোর জন্য ডেটা টাইপ (ভাসমান পয়েন্ট ধরণের পরিবর্তে স্বেচ্ছাচারিত নির্ভুলতা প্রকার)। আপনি যদি পুরো সংখ্যাটি একচেটিয়াভাবে মোকাবেলা করেন তবে তা তৈরি করুন । উদাহরণস্বরূপ, আপনি সেন্ট হিসাবে দামগুলি সঞ্চয় করতে পারেন ।numericinteger

  • এটি amount( "Products"আপনার প্রশ্নে) লিঙ্কিং টেবিলের মধ্যে যায় এবং টাইপও bill_productহয় numeric। আবার integerআপনি যদি পুরো সংখ্যাটি একচেটিয়াভাবে পরিচালনা করেন।

  • আপনি দেখতে বিদেশী কী মধ্যে bill_product? আমি উভয় ক্যাসকেড পরিবর্তনের তৈরি করা হয়েছে: ON UPDATE CASCADE। যদি একটি product_idবা bill_idপরিবর্তিত হয়, পরিবর্তনটি সমস্ত নির্ভরশীল এন্ট্রিগুলিতে ক্যাসকেড হয় bill_productএবং কিছুই ভাঙে না। এগুলি কেবল তাদের নিজস্ব গুরুত্ব ছাড়াই উল্লেখযোগ্য রেফারেন্স।
    আমি ব্যবহার ON DELETE CASCADEজন্য bill_id: একটি বিল মোছা, তাহলে এটির বিশদ বিবরণ এটি দিয়ে মারা যায়।
    পণ্যগুলির জন্য তাই নয়: আপনি কোনও বিলে ব্যবহৃত পণ্য মুছতে চান না। পোস্টগ্রিজ যদি আপনি এটি চেষ্টা করেন তবে একটি ত্রুটি ফেলবে। productপরিবর্তে অপ্রচলিত সারিগুলি চিহ্নিত করার জন্য আপনি অন্য কলাম যুক্ত করবেন ("সফট-মুছুন")।

  • এই বেসিক উদাহরণে সমস্ত কলাম শেষ পর্যন্ত শেষ হয় NOT NULL, সুতরাং NULLমানগুলি অনুমোদিত হয় না। (হ্যাঁ, সমস্ত কলাম - প্রাথমিক কী কলামগুলি UNIQUE NOT NULLস্বয়ংক্রিয়ভাবে সংজ্ঞায়িত হয়)) এটি কারণ NULLকারণগুলির কোনও কলামে মানগুলি বোঝায় না। এটি একটি শিক্ষানবিশ জীবন সহজ করে তোলে। তবে আপনি এত সহজেই NULLপালাতে পারবেন না , আপনাকে যেভাবেই হ্যান্ডলিং করা দরকার । অতিরিক্ত কলামগুলি NULLমানগুলিকে মঞ্জুরি দেয় , ফাংশন এবং যোগদানগুলিতে NULLপ্রশ্নগুলি ইত্যাদিতে মানগুলি প্রবর্তন করতে পারে might

  • CREATE TABLEম্যানুয়ালটিতে অধ্যায়টি পড়ুন ।

  • প্রাথমিক কীগুলি মূল কলামগুলিতে একটি অনন্য সূচী দিয়ে প্রয়োগ করা হয় , যা পিকে কলাম (গুলি) এর শর্তগুলির সাথে দ্রুত অনুসন্ধান করে। যাইহোক, কী কলামগুলির ক্রমটি বহুবিধ কীগুলিতে প্রাসঙ্গিক। যেহেতু উপর পি কে bill_productহয় (bill_id, product_id)আমার উদাহরণে, আপনি শুধু আরেকটি সূচক যোগ করতে পারেন product_idবা (product_id, bill_id)আপনি প্রশ্নের একটি প্রদত্ত খুঁজছেন আছে product_idএবং কোন bill_id। দেখা:

  • ম্যানুয়ালটিতে সূচীগুলির উপর অধ্যায়টি পড়ুন ।


আমি কীভাবে ম্যাপিং টেবিলের জন্য একটি সূচক তৈরি করতে পারি bill_product? সাধারণত দেখে মনে হচ্ছে করা উচিত: CREATE INDEX idx_bill_product_id ON booked_rates(bill_id, product_id)। এটা কী ঠিক?
— কোডিলাইন

4
@ কোডিলাইন: এই সূচকটি পিকে দ্বারা স্বয়ংক্রিয়ভাবে তৈরি করা হয়েছে।
— এরউইন ব্র্যান্ডসটেটার

4
@ এরউইন ব্র্যান্ডসটেটার: প্রোডাক্ট_আইডি কলামের জন্য বিলি_প্রডাক্টে কোনও সূচক তৈরি করা উচিত নয়?
— খ্রিস্টান

4
@ ক্রিশ্চিয়ানবি.আলমিদা: হ্যাঁ, এটি অনেক ক্ষেত্রেই কার্যকর। আমি ইনডেক্সিং সম্পর্কে কিছুটা যুক্ত করেছি।
— এরউইন ব্র্যান্ডসটেটার

4
@ জাকভ: টেবিলের প্রতিটি বিলের জন্য মাত্র 1 সারি রয়েছে bill। আমাদের প্রতি যোগ আইটেম পরিমাণ প্রয়োজন bill_product।
— এরউইন ব্র্যান্ডসটেটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.