3 तालिकाओं के बीच चक्रीय निर्भरता (परिपत्र संदर्भ) से कैसे बचें?


10

मेरे पास 3 टेबल हैं:

  • लोग
  • पद
  • को यह पसंद है

जब मैं ईआर मॉडल तैयार करता हूं तो उसमें चक्रीय निर्भरता होती है:

         1: एन
लोग -------- <पोस्ट

         1: एन
पोस्ट ---------- <लाइक

         1: एन
लोग -------- <पसंद

तर्क है:

  • 1 लोगों के कई पद हो सकते हैं।

  • 1 पोस्ट को कई लाइक मिले।

  • 1 लोग कई पोस्ट पसंद कर सकते हैं (बनाया गया व्यक्ति अपनी पोस्ट पसंद नहीं कर सकता)।

मैं इस तरह के चक्रीय डिजाइन को कैसे हटा सकता हूं? या मेरी डीबी डिजाइन गलत है?

जवाबों:


10

व्यापार नियम

आइए हम आपके द्वारा प्रस्तुत किए गए व्यावसायिक नियमों के बारे में कुछ विवरण दें:

  • A शून्य-एक-या-कईPerson बनाता है Posts
  • A शून्य-एक-या-कईPost प्राप्त करता है Likes
  • एक शून्य-एक-या-कईPerson प्रकट होता है Likes , प्रत्येक विच एक विशिष्ट से संबंधित होता है Post

तार्किक मॉडल

फिर, इस तरह के दावे से, मैंने दो तार्किक स्तर IDEF1X [1] डेटा मॉडल निकाले हैं जो चित्र 1 में दिखाए गए हैं ।

चित्र 1 - लोग और डाक डेटा मॉडल

विकल्प ए

आप विकल्प ए मॉडल में देख सकते हैं, PersonId migrates [2] से Personकरने के लिए Postएक विदेशी कुँजी (FK) के रूप में है, लेकिन यह प्राप्त करता भूमिका का नाम [3] के AuthorIdसाथ साथ, और इस विशेषता का निर्माण करता है, PostNumber, प्राथमिक कुंजी (पी) की Postइकाई प्रकार।

मुझे लगता है कि एक Likeकेवल एक विशेष के सिलसिले में मौजूद कर सकते हैं Post, तो मैं एक की स्थापना की है Likeपीके कि तीन अलग-अलग गुण शामिल हैं: PostAuthorId, PostNumberऔर LikerId। के संयोजन PostAuthorIdऔर PostNumberएक FK कि उचित संदर्भ बनाता है Postपी। LikerIdबदले में, एक एफके जो उपयुक्त संगति स्थापित करता है Person.PersonId

इस संरचना की सहायता से, आप यह सुनिश्चित करते हैं कि एक निर्धारित व्यक्ति एक ही Likeघटना के लिए एक ही घटना को प्रकट कर सकता है Post

किसी पोस्ट ऑथर को अपनी पोस्ट को पसंद करने से रोकने के तरीके

चूंकि आप इस संभावना को अनुमति नहीं देना चाहते हैं कि कोई व्यक्ति अपने लेखक पदों को पसंद कर सकता है, तो कार्यान्वयन चरण में एक बार, आपको एक विधि स्थापित करनी चाहिए जो प्रत्येक INSERT प्रयास में Like.PostAuthorIdमूल्य के मूल्य की तुलना करती है Like.LikerId। यदि कहा जाता है कि मान मेल खाते हैं, (ए) आप प्रविष्टि को अस्वीकार करते हैं, यदि वे मेल नहीं खाते हैं (बी) तो आप इस प्रक्रिया को जारी रखने देंगे।

अपने डेटाबेस में इस कार्य को पूरा करने के लिए, आप इसका उपयोग कर सकते हैं:

  1. एक संक्षिप्त , लेकिन निश्चित रूप से, यह विधि MySQL को बाहर करती है, क्योंकि यह अब तक इस प्लेटफ़ॉर्म में लागू नहीं किया गया है, जैसा कि आप यहाँ और यहाँ देख सकते हैं ।

  2. एक ACID लेनदेन के अंदर कोड लाइनें

  3. TRIGGER के भीतर कोड लाइनें , जो नियम उल्लंघन के प्रयास को इंगित करते हुए एक कस्टम संदेश लौटा सकती हैं।

विकल्प बी

यदि लेखक एक विशेषता नहीं है जो आपके व्यवसाय डोमेन में प्राथमिक तरीके से पोस्ट की पहचान करता है, तो आप विकल्प बी में दर्शाए गए एक के समान संरचना के साथ जा सकते हैं।

यह दृष्टिकोण यह भी सुनिश्चित करता है कि एक पोस्ट को केवल एक ही व्यक्ति द्वारा एक बार पसंद किया जा सकता है।


टिप्पणियाँ

1. सूचना मॉडलिंग के लिए एकीकरण परिभाषा ( आईडीईएफ 1 एक्स ) एक अत्यधिक सिफारिशी डेटा मॉडलिंग तकनीक है जिसे संयुक्त राज्य अमेरिका के राष्ट्रीय मानक और प्रौद्योगिकी संस्थान ( एनआईएसटी ) द्वारा 1993 में एक मानक के रूप में परिभाषित किया गया था ।

2. आईडीईएफ 1 एक्स प्रमुख प्रवासन को "एक बच्चे के रूप में अपने बच्चे या श्रेणी इकाई में एक मूल या जेनेरिक इकाई की प्राथमिक कुंजी रखने की मॉडलिंग प्रक्रिया" एक विदेशी कुंजी के रूप में परिभाषित करता है ।

3. एक भूमिका नाम एक विदेशी कुंजी विशेषता को निर्दिष्ट करने के लिए दिया गया एक शब्द है जो इस प्रकार की विशेषता को उसके संबंधित निकाय प्रकार के संदर्भ में व्यक्त करता है। डॉ। ईएफ कोडड द्वारा 1970 के बाद से उनके नाममात्र के पेपर में "बड़े साझा बैंकों के लिए डेटा का एक संबंधपरक मॉडल" शीर्षक से रोल नामकरण की सिफारिश की गई है । अपने हिस्से के लिए, IDEF1X-keeping निष्ठा संबंधपरक प्रथाओं का संबंध है - इस प्रक्रिया की भी वकालत करता है।


6

मुझे यहाँ कुछ भी चक्रीय नहीं दिख रहा है। कर रहे हैं लोगों को और पदों और इन संस्थाओं के बीच दो स्वतंत्र रिश्ते। मैं इनमें से किसी एक रिश्ते के कार्यान्वयन के रूप में पसंद देखूंगा ।

  • एक व्यक्ति कई पोस्ट लिख सकता है, एक पोस्ट एक व्यक्ति द्वारा लिखी जाती है: 1:n
  • एक व्यक्ति कई पदों को पसंद कर सकता है, एक पोस्ट को कई लोगों द्वारा पसंद किया जा सकता है: n:m
    n: m संबंध किसी अन्य संबंध के साथ लागू किया जा सकता है likes:।

मूल कार्यान्वयन

मूल कार्यान्वयन PostgreSQL में इस तरह दिख सकता है :

CREATE TABLE person (
  person_id serial PRIMARY KEY
, person    text NOT NULL
);

CREATE TABLE post (
  post_id   serial PRIMARY KEY
, author_id int NOT NULL  -- cannot be anonymous
     REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE  -- 1:n relationship
, post      text NOT NULL
);

CREATE TABLE likes (  -- n:m relationship
  person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE
, post_id   int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE
, PRIMARY KEY (post_id, person_id)
);

विशेष रूप से ध्यान दें कि एक पोस्ट में एक लेखक ( ) होना चाहिएNOT NULL , जबकि पसंद का अस्तित्व वैकल्पिक है। मौजूदा पसंद के लिए, हालाँकि, postऔर दोनों को संदर्भित किया person जाना चाहिए (इसके द्वारा लागू किया गया PRIMARY KEYहै) दोनों कॉलम NOT NULLस्वचालित रूप से बनाता है (आप इन बाधाओं को स्पष्ट रूप से जोड़ सकते हैं, अनावश्यक रूप से) इसलिए अनाम पसंद भी असंभव है।

एन के लिए विवरण: एम कार्यान्वयन:

आत्मचिंतन को रोकें

आपने भी लिखा:

(बनाया गया व्यक्ति अपने पद को पसंद नहीं कर सकता है)।

यह उपरोक्त कार्यान्वयन में लागू नहीं है, फिर भी। आप एक ट्रिगर का उपयोग कर सकते हैं ।
या इनमें से एक तेज / अधिक विश्वसनीय समाधान:

लागत के लिए रॉक-सॉलिड

यह होने की जरूरत है, तो रॉक-ठोस , आप से FK का विस्तार कर सकता likesकरने के लिए postशामिल करने के लिए author_idप्रचुरता से। फिर आप एक साधारण CHECKबाधा के साथ अनाचार को नियंत्रित कर सकते हैं ।

CREATE TABLE likes (
  person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE
, post_id   int 
, author_id int NOT NULL
, CONSTRAINT likes_pkey PRIMARY KEY (post_id, person_id)
, CONSTRAINT likes_post_fkey FOREIGN KEY (author_id, post_id)
     REFERENCES post(author_id, post_id) ON UPDATE CASCADE ON DELETE CASCADE
, CONSTRAINT no_self_like CHECK (person_id <> author_id)
);

इसके लिए एक अन्यथा अतिरेक UNIQUEअवरोध की भी आवश्यकता होती है post:

ALTER TABLE post ADD CONSTRAINT post_for_fk_uni UNIQUE (author_id, post_id);

मैंने author_idसबसे पहले एक उपयोगी इंडेक्स की आपूर्ति की, जबकि उस पर रहा।

अधिक के साथ संबंधित जवाब:

एक CHECKबाधा के साथ सस्ता

ऊपर "मूल कार्यान्वयन" पर निर्माण।

CHECKबाधाओं को अपरिवर्तनीय माना जाता है। एक जांच के लिए अन्य तालिकाओं को संदर्भित करना कभी भी अपरिवर्तनीय नहीं है, हम यहां अवधारणा का थोड़ा दुरुपयोग कर रहे हैं। मैं NOT VALIDठीक से प्रतिबिंबित करने के लिए बाधा घोषित करने का सुझाव देता हूं । विवरण:

CHECKइस विशेष मामले में एक बाधा उचित लगती है, क्योंकि एक पोस्ट के लेखक एक विशेषता की तरह लगता है जो कभी नहीं बदलता है। सुनिश्चित करने के लिए उस फ़ील्ड के अपडेट को अस्वीकृत करें।

हम एक समारोह नकलीIMMUTABLE :

CREATE OR REPLACE FUNCTION f_author_id_of_post(_post_id int)
  RETURNS int AS
'SELECT p.author_id FROM public.post p WHERE p.post_id = $1'
LANGUAGE sql IMMUTABLE;

अपनी तालिकाओं के वास्तविक स्कीमा से 'जनता' को बदलें।
एक CHECKबाधा में इस समारोह का उपयोग करें :

ALTER TABLE likes ADD CONSTRAINT no_self_like_chk
   CHECK (f_author_id_of_post(post_id) <> person_id) NOT VALID;

4

मुझे लगता है कि आपको इस बात का पता लगाने में कठिनाई हो रही है कि आप अपने व्यावसायिक नियमों को कैसे बताते हैं।

लोग और पोस्ट "ऑब्जेक्ट" हैं। जैसे एक क्रिया है।

आपके पास वास्तव में सिर्फ 2 कार्य हैं:

  1. एक व्यक्ति एक या अधिक पोस्ट बना सकता है
  2. कई व्यक्ति कई पोस्ट पसंद कर सकते हैं। (आपके अंतिम 2 कथनों का संकलन)

लोग पोस्ट आरेख पसंद करते हैं

"पसंद" तालिका में एक प्राथमिक कुंजी के रूप में person_id और post_id होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.