PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL में कई-से-अनेक संबंध कैसे कार्यान्वित करें?

SQL DDL (डेटा परिभाषा भाषा) कथन इस तरह दिख सकते हैं:

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:m संबंध आमतौर पर एक अलग तालिका द्वारा कार्यान्वित किया जाता है - bill_product इस मामले में।

  • मैंने serial added जोड़ा प्राथमिक कुंजियों को सरोगेट करें . के रूप में कॉलम . Postgres 10 या बाद के संस्करण में IDENTITY . पर विचार करें इसके बजाय कॉलम। देखें:

    • क्रमिक प्राथमिक कुंजी कॉलम का उपयोग करके तालिकाओं का सुरक्षित रूप से नाम बदलें
    • ऑटो इंक्रीमेंट टेबल कॉलम
    • https://www.2ndquadrant.com/hi/blog/postgresql-10-identity-columns/

    मैं इसकी अत्यधिक अनुशंसा करता हूं, क्योंकि किसी उत्पाद का नाम शायद ही अद्वितीय हो (एक अच्छी "प्राकृतिक कुंजी" नहीं)। साथ ही, विशिष्टता को लागू करना और कॉलम को विदेशी कुंजियों में संदर्भित करना आमतौर पर 4-बाइट integer के साथ सस्ता होता है। (या यहां तक ​​कि एक 8-बाइट bigint ) text . के रूप में संग्रहीत स्ट्रिंग के बजाय या varchar

  • बुनियादी डेटा प्रकारों जैसे date . के नामों का उपयोग न करें पहचानकर्ता . के रूप में . हालांकि यह संभव है, यह खराब शैली है और भ्रमित करने वाली त्रुटियों और त्रुटि संदेशों की ओर ले जाती है। कानूनी, लोअर केस, गैर-उद्धृत पहचानकर्ताओं का प्रयोग करें। कभी भी आरक्षित शब्दों का प्रयोग न करें और यदि संभव हो तो दोहरे-उद्धृत मिश्रित केस पहचानकर्ताओं से बचें।

  • "नाम" एक अच्छा नाम नहीं है। मैंने तालिका के कॉलम का नाम बदल दिया product product होने के लिए (या product_name या इसी के समान)। यह एक बेहतर नामकरण परंपरा है . अन्यथा, जब आप किसी क्वेरी में कुछ तालिकाओं को जोड़ते हैं - जो आप बहुत कुछ करते हैं एक संबंधपरक डेटाबेस में - आप "नाम" नामक कई कॉलम के साथ समाप्त होते हैं और गड़बड़ी को हल करने के लिए कॉलम उपनाम का उपयोग करना पड़ता है। यह मददगार नहीं है। कॉलम नाम के रूप में एक और व्यापक विरोधी पैटर्न सिर्फ "id" होगा।
    मुझे यकीन नहीं है कि bill का नाम क्या है होगा। bill_id शायद इस मामले में पर्याप्त होगा।

  • price डेटा प्रकार . का है numeric भिन्नात्मक संख्याओं को संगृहीत करने के लिए ठीक वैसे ही जैसे दर्ज किया गया है (फ़्लोटिंग पॉइंट प्रकार के बजाय मनमाना सटीक प्रकार)। यदि आप विशेष रूप से पूर्ण संख्याओं से निपटते हैं, तो वह integer बनाएं . उदाहरण के लिए, आप कीमतों को सेंट के रूप में बचा सकते हैं ।

  • 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 allow की अनुमति दे सकते हैं मान, फ़ंक्शन और जॉइन NULL introduce को पेश कर सकते हैं प्रश्नों आदि में मूल्य।

  • CREATE TABLE पर अध्याय पढ़ें मैनुअल में।

  • प्राथमिक कुंजियाँ एक अद्वितीय अनुक्रमणिका . के साथ क्रियान्वित की जाती हैं कुंजी कॉलम पर, जो पीके कॉलम पर शर्तों के साथ तेजी से पूछताछ करता है। हालाँकि, बहु-स्तंभ कुंजियों में कुंजी स्तंभों का क्रम प्रासंगिक है। चूंकि PK bill_product . पर है (bill_id, product_id) पर है मेरे उदाहरण में, आप केवल product_id . पर एक और अनुक्रमणिका जोड़ना चाह सकते हैं या (product_id, bill_id) यदि आपके पास दिए गए product_id . की तलाश में कोई प्रश्न हैं और नहीं bill_id . देखें:

    • PostgreSQL समग्र प्राथमिक कुंजी
    • क्या पहले फ़ील्ड पर प्रश्नों के लिए एक समग्र अनुक्रमणिका भी अच्छी है?
    • PostgreSQL में अनुक्रमणिका का कार्य करना
  • मैनुअल में इंडेक्स पर अध्याय पढ़ें।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PhpPgAdmin से sql इंसर्ट क्वेरी सिंटैक्स त्रुटि पोस्टग्रेज करता है

  2. PSQLException:त्रुटि:संबंध TABLE_NAME मौजूद नहीं है

  3. इंडेक्स स्कैन ज्यादा बेहतर विकल्प होने पर इंडेक्स का उपयोग नहीं करना पोस्टग्रेस

  4. रेल 3.2 पोस्टग्रेज त्रुटि सहेजें ActiveRecord ::StatementInvalid:PG ::त्रुटि:त्रुटि:स्थिति 5 पर 'T' के पास सिंटैक्स त्रुटि

  5. Django के सिंकडब को चलाते समय OSX 10.7.3 पर पोस्टग्रेस्क्ल सॉकेट त्रुटि