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


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বা অনুরূপ)। এটি একটি ভাল নামকরণ কনভেনশন । অন্যথায়, আপনি যখন কোনও ক্যোয়ারিতে কয়েকটি টেবিলের সাথে যুক্ত হন - যা আপনি একটি রিলেশনাল ডাটাবেসে অনেক কিছু করেন - আপনি "নাম" নামে একাধিক কলাম দিয়ে শেষ করেন এবং গণ্ডগোল বাছাইয়ের জন্য কলামের নাম ব্যবহার করতে হবে। এটি সহায়ক নয়। আর একটি বিস্তৃত এন্টি-প্যাটার্নটি কলামের নাম হিসাবে কেবল "আইডি" হবে।
    কোনটির নাম কী হবে তা আমি নিশ্চিত নই billbill_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.