एक दोस्ती डेटाबेस संरचना डिजाइन करना: क्या मुझे एक बहुस्तरीय कॉलम का उपयोग करना चाहिए?


9

कहो कि मेरे पास एक तालिका है User_FriendList, जिसमें निम्नलिखित विशेषताएं हैं:

CREATE TABLE User_FriendList (
    ID ...,
    User_ID...,
    FriendList_IDs...,
    CONSTRAINT User_Friendlist_PK PRIMARY KEY (ID)
);

और मान लें कि उक्त तालिका में निम्नलिखित आंकड़े हैं:

 + ---- + --------- + --------------------------- +
 | आईडी | उपयोगकर्ता_आईडी | फ्रेंडलिस्ट_आईडी             |
 + ---- + --------- + --------------------------- +
 | 1 | 102 | 2: 15: 66: 35: 26: 17: |
 + ---- + --------- + --------------------------- +
 | 2 | 114 | 1: 12: 63: 33: 24: 16: 102 |
 + ---- + --------- + --------------------------- +
 | 3 | 117 | 6: 24: 52: 61: 23: 90: 97: 118 |
 + ---- + --------- + --------------------------- +

नोट: ":" (कोलन) PHP में विस्फोट करते समय सीमांकक है array

प्रशन

इसलिए:

  • क्या यह "स्टोर" करने IDsका एक सुविधाजनक तरीका है FriendList?

  • या, इसके बजाय, क्या मुझे FriendIdउनमें से प्रत्येक में केवल एक ही मूल्य वाली व्यक्तिगत पंक्तियाँ होनी चाहिए और, जब मुझे दी गई सूची की सभी पंक्तियों को पुनः प्राप्त करने की आवश्यकता है , तो बस एक क्वेरी करें SELECT * FROM UserFriendList WHERE UserId = 1?


3
मैं आपको इसे पढ़ने की सलाह देता हूं: stackoverflow.com/questions/3653462/…
tombom

यह आईडी को स्टोर करने का एक सुविधाजनक तरीका है, जब तक आप उनके साथ कुछ भी करने की योजना नहीं बना रहे हैं और विशेष रूप से डेटा की गुणवत्ता के बारे में परवाह नहीं करते हैं।
15-29

मुझे लगता है कि codedodle.com/2014/12/social-network-friends-database.html सबसे अच्छा समाधान में से एक हो सकता है।
गुप्त

जवाबों:


19

सूचना के एक व्यक्तिगत टुकड़े का प्रबंधन

यह मानते हुए कि, आपके व्यावसायिक डोमेन में,

  • एक उपयोगकर्ता के पास शून्य-एक-या-कई मित्र हो सकते हैं ;
  • एक मित्र को पहले उपयोगकर्ता के रूप में पंजीकृत होना चाहिए ; तथा
  • आप मित्र सूची के एकल मानों और / या जोड़ेंगे, और / या निकालें, और / या संशोधित करेंगे ;

तब बहुस्तरीय कॉलम में एकत्रित प्रत्येक विशिष्ट डेटा एक अलग जानकारी काFriendlist_IDs प्रतिनिधित्व करता है जो बहुत सटीक अर्थ वहन करती है। इसलिए, कहा स्तंभ

  • स्पष्ट बाधाओं के एक उचित समूह को जोड़ता है, और
  • इसके मूल्यों में कई संबंधपरक संचालन (या इसके संयोजन) के माध्यम से व्यक्तिगत रूप से हेरफेर करने की क्षमता है।

संक्षिप्त जवाब

नतीजतन, आपको Friendlist_IDs(ए) मानों में से प्रत्येक को बनाए रखना चाहिए जो एक कॉलम में विशेष रूप से प्रति पंक्ति में एकमात्र एकमात्र मान स्वीकार करता है (तालिका) जो वैचारिक स्तर के एसोसिएशन प्रकार का प्रतिनिधित्व करता है जो उपयोगकर्ताओं के बीच जगह ले सकता है , अर्थात, एक मैत्री -एसएएस मैं निम्नलिखित खंडों में उदाहरण प्रस्तुत करूंगा-

इस तरह, आप एक गणितीय संबंध के रूप में (i) तालिका को संभाल पाएंगे और (ii) स्तंभ को गणितीय संबंध विशेषता के रूप में कह सकते हैं — जैसे कि MySQL और इसकी SQL बोली परमिट के रूप में, निश्चित रूप से।

क्यों?

क्योंकि डॉ। ई। एफ। कोडेड द्वारा बनाया गया डेटा का संबंधपरक मॉडल , उन स्तंभों से बना है जो उन स्तंभों से बने होते हैं जो लागू डोमेन का ठीक एक मूल्य रखते हैं या प्रति पंक्ति टाइप करते हैं ; इसलिए, एक स्तंभ के साथ एक तालिका की घोषणा करना जिसमें डोमेन का एक से अधिक मूल्य हो सकता है या प्रश्न में टाइप कर सकता है (1) एक गणितीय संबंध का प्रतिनिधित्व नहीं करता है और (2) उपरोक्त सैद्धांतिक ढांचे में प्रस्तावित लाभों को प्राप्त करने की अनुमति नहीं देगा।

यूजर्स के बीच मॉडलिंग दोस्ती : पहले कारोबारी माहौल के नियमों को परिभाषित करना

मैं अत्यधिक सलाह देता हूं कि डेटाबेस को आकार देने की शुरुआत करें - इसके अलावा और कुछ भी - संबंधित व्यवसाय नियमों की परिभाषा के आधार पर संबंधित वैचारिक स्कीमा , जो अन्य कारकों के साथ, ब्याज के अलग-अलग पहलुओं के बीच मौजूद अंतर-संबंध के प्रकारों का वर्णन करना चाहिए, अर्थात लागू इकाई प्रकार और उनके गुण ; उदाहरण के लिए:

  • एक उपयोगकर्ता को मुख्य रूप से उसके उपयोगकर्ता आईडी द्वारा पहचाना जाता है
  • एक उपयोगकर्ता को उसके फर्स्टनाम , लास्टनाम , जेंडर और बर्थडे के संयोजन द्वारा वैकल्पिक रूप से पहचाना जाता है
  • एक उपयोगकर्ता को उसके उपयोगकर्ता नाम से बारी-बारी से पहचाना जाता है
  • एक उपयोगकर्ता शून्य-एक-या-कई मित्रता का अनुरोधकर्ता है
  • एक उपयोगकर्ता है addressee शून्य से एक या कई की दोस्ती
  • एक मैत्री को मुख्य रूप से उसके RequesterId और उसके AddresseeId के संयोजन से पहचाना जाता है

एक्सपोजिटरी IDEF1X आरेख

इस तरीके से, मैं चित्र 1 में दिखाए गए IDEF1X 1 आरेख को प्राप्त करने में सक्षम था , जो पहले बनाए गए अधिकांश नियमों को एकीकृत करता है:

चित्रा 1. उपयोगकर्ता मित्रता IDEF1X आरेख

जैसा कि दर्शाया गया है, रिक्वेस्टर और एड्रेसी एक डिपोशन हैं जो उन विशिष्ट उपयोगकर्ताओं द्वारा किए गए रोल्स को व्यक्त करते हैं जो किसी दिए गए मैत्री में भाग लेते हैं ।

ऐसा होने के नाते, मैत्री इकाई प्रकार कई-से-कई (एम: एन) कार्डिनैलिटी अनुपात के एक संघ प्रकार को चित्रित करता है जिसमें एक ही इकाई प्रकार के अलग-अलग ऑरेग्राफ शामिल हो सकते हैं , अर्थात, उपयोगकर्ता । जैसे, यह "निर्माण सामग्री" या "पार्ट्स विस्फोट" नामक क्लासिक निर्माण का एक उदाहरण है।


1 सूचना मॉडलिंग ( आईडीईएफ 1 एक्स ) के लिए एकीकरण परिभाषा एक उच्च अनुशंसा योग्य तकनीक है जिसेदिसंबर 1993 में यूएस नेशनल इंस्टीट्यूट ऑफ स्टैंडर्ड एंड टेक्नोलॉजी (एनआईएसटी)द्वारा मानक के रूप में स्थापित किया गया था। यह ठोस रूप से (ए)संबंधपरक मॉडलके एकमात्र प्रवर्तक द्वारा लिखित प्रारंभिक सैद्धांतिक सामग्री पर आधारित है, अर्थात, डॉ ईएफ कोड ; डॉ। पीपी चेन द्वारा विकसित(बी)डेटाकी इकाई-संबंध दृश्य; और (ग) रॉबर्ट जी ब्राउन द्वारा निर्मित लॉजिकल डाटाबेस डिजाइन तकनीक पर भी।


चित्रण एसक्यूएल-डीडीएल तार्किक डिजाइन

फिर, ऊपर प्रस्तुत IDEF1X आरेख से, डीडीएल व्यवस्था की घोषणा करते हुए, जो इस प्रकार है कि "अधिक प्राकृतिक" है:

-- You should determine which are the most fitting 
-- data types and sizes for all the table columns 
-- depending on your business context characteristics.

-- At the physical level, you should make accurate tests 
-- to define the mostconvenient INDEX strategies based on 
-- the pertinent query tendencies.

-- As one would expect, you are free to make use of 
-- your preferred (or required) naming conventions. 

CREATE TABLE UserProfile ( -- Represents an independent entity type.
    UserId          INT      NOT NULL,
    FirstName       CHAR(30) NOT NULL,
    LastName        CHAR(30) NOT NULL,
    BirthDate       DATE     NOT NULL,
    GenderCode      CHAR(3)  NOT NULL,
    Username        CHAR(20) NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    --
    CONSTRAINT UserProfile_PK  PRIMARY KEY (UserId),
    CONSTRAINT UserProfile_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
        FirstName,
        LastName,
        GenderCode,
        BirthDate
    ),
    CONSTRAINT UserProfile_AK2 UNIQUE (Username) -- Single-column ALTERNATE KEY.
);

CREATE TABLE Friendship ( -- Stands for an associative entity type.
    RequesterId     INT      NOT NULL,
    AddresseeId     INT      NOT NULL, -- Fixed with a well-delimited data type.
    CreatedDateTime DATETIME NOT NULL,
    --
    CONSTRAINT Friendship_PK            PRIMARY KEY (RequesterId, AddresseeId), -- Composite PRIMARY KEY.
    CONSTRAINT FriendshipToRequester_FK FOREIGN KEY (RequesterId)
        REFERENCES UserProfile (UserId),
    CONSTRAINT FriendshipToAddressee_FK FOREIGN KEY (AddresseeId)
        REFERENCES UserProfile (UserId)
);

इस फैशन में:

  • प्रत्येक आधार तालिका एक व्यक्तिगत इकाई प्रकार का प्रतिनिधित्व करती है;
  • प्रत्येक कॉलम संबंधित इकाई प्रकार की एकमात्र संपत्ति के लिए है ;
  • एक विशिष्ट डेटा टाइप एक प्रत्येक के लिए तय हो गई है स्तंभ गारंटी करने के लिए है कि सभी मूल्यों यह एक विशेष और अच्छी तरह से परिभाषित से संबंधित होता है सेट , यह हो INT DATETIME,, CHAR, आदि .; तथा
  • कई बाधाओं क्रम में (एलान के तौर पर) कॉन्फ़िगर किया गया है यह सुनिश्चित करें कि के रूप में दावे पंक्तियों सभी में बनाए रखा टेबल वैचारिक स्कीमा पर निर्धारित व्यापार के नियम को पूरा।

एकल-मूल्यवान स्तंभ के लाभ

प्रदर्शन के अनुसार, आप कर सकते हैं, उदाहरण के लिए:

  • स्तंभ के लिए डेटाबेस मैनेजमेंट सिस्टम (डीबीएमएस फॉर ब्रीविटी) द्वारा लागू की गई संदर्भात्मक अखंडता का लाभ उठाएं Friendship.AddresseeId, क्योंकि यह फॉरवर्ड डिजाइन (संक्षिप्तता के लिए एफके) के रूप में विवश करता है, जो कॉलम के संदर्भ में बनाता है UserProfile.UserIdकि प्रत्येक मौजूदा पंक्ति को इंगित करता है ।

  • स्तंभों के संयोजन से बना एक समग्र प्राथमिक कुंजी (पीके) बनाएं (Friendship.RequesterId, Friendship.AddresseeId), जो सभी सम्मिलित पंक्तियों को अलग-अलग पहचानने में मदद करता है और स्वाभाविक रूप से, उनकी विशिष्टता की रक्षा करता है

    बेशक, इसका मतलब है कि सिस्टम-असाइन किए गए सरोगेट मानों के लिए एक अतिरिक्त कॉलम का अनुलग्नक (उदाहरण के लिए, Microsoft SQL सर्वर में IDENTITY गुण या MySQL में AUTO_INCREMENT विशेषता के साथ सेट किया गया ) और सहायक INDEX पूरी तरह से अति-विशिष्ट है

  • Friendship.AddresseeIdसटीक मानों को एक सटीक डेटा प्रकार c (जो कि UserProfile.UserIdइस मामले में INT के लिए स्थापित है, उदाहरण के लिए, मेल खाना चाहिए) को प्रतिबंधित करें , जिससे DBMS को स्वचालित स्वत: मान्यता का ख्याल रखा जा सके ।

    यह कारक संबंधित बिल्ट-इन प्रकार के कार्यों के उपयोग (ए) के लिए भी मदद कर सकता है और (बी) डिस्क स्थान उपयोग को अनुकूलित कर सकता है ।

  • कॉलम के लिए छोटे और तेज अधीनस्थ INDEX को कॉन्फ़िगर करके भौतिक स्तर पर डेटा पुनर्प्राप्ति का अनुकूलन करें, क्योंकि ये भौतिक तत्व उन प्रश्नों को गति देने में काफी मदद कर सकते हैं जिनमें कहा गया कॉलम शामिल है।Friendship.AddresseeId

    निश्चित रूप से, आप कर सकते हैं, उदाहरण के लिए, एक एकल-कॉलम INDEX को Friendship.AddresseeIdअकेले के लिए, एक बहु-स्तंभ एक को शामिल करें जो इसमें शामिल है Friendship.RequesterIdऔर Friendship.AddresseeId, या दोनों।

  • "एक समान कॉलम (बहुत संभावित रूप से डुप्लिकेट, गलत टाइप किए गए, आदि) के अंदर एक साथ एकत्र किए गए अलग-अलग मानों के लिए खोज की गई अनावश्यक जटिलता से बचें , कार्रवाई का एक कोर्स जो अंततः आपके सिस्टम के कामकाज को धीमा कर देगा, क्योंकि आप करेंगे कहा कार्य को पूरा करने के लिए संसाधन और समय लेने वाली गैर-संबंधपरक विधियों का सहारा लेना होगा।

तो, वहाँ कई कारण है कि आदेश बाहर चिह्नित करने के लिए ध्यान से प्रासंगिक कारोबारी माहौल का विश्लेषण करने के लिए कॉल कर रहे हैं प्रकार सटीकता के साथ तालिका का प्रत्येक स्तंभ की।

जैसा कि सामने आया, डेटाबेस डिज़ाइनर द्वारा निभाई गई भूमिका रिलेशनल मॉडल और पसंद के DBMS द्वारा प्रदान किए गए भौतिक तंत्रों (2) द्वारा प्रदान किए गए तार्किक-स्तरीय लाभों का सर्वोत्तम उपयोग करने के लिए सर्वोपरि है ।


, बी , सी , डी , जाहिर है, जब एसक्यूएल प्लेटफार्मों (जैसे, फायरबर्ड और पोस्टग्रैसीक्यू ) केसाथ काम करते हैंजो DOMAIN निर्माण (एक विशिष्ट संबंधपरक विशेषता) कासमर्थन करते हैं, तो आप उन स्तंभों की घोषणा कर सकते हैं जो केवल उन मूल्यों को स्वीकार करते हैं जो उनके संबंधित हैं (कभी-कभी विवश और कभी-कभी। साझा) DOMAINs।


एक या अधिक एप्लिकेशन प्रोग्राम डेटाबेस को विचार के तहत साझा करते हैं

जब आपको arraysडेटाबेस पर आरोप लगाने वाले एप्लिकेशन प्रोग्राम (कोड) के कोड में काम करना होता है, तो आपको संबंधित डेटा सेट को पूर्ण रूप से प्राप्त करना होगा और फिर संबंधित कोड संरचना में इसे (उन्हें) "बाइंड" करना होगा या निष्पादित करना होगा। संबद्ध एप्लिकेशन (प्रक्रियाएं) जो होनी चाहिए।

एकल-मूल्यवान स्तंभों के आगे के लाभ: डेटाबेस संरचना विस्तार बहुत आसान है

AddresseeIdअपने आरक्षित और ठीक प्रकार के कॉलम में डेटा बिंदु को रखने का एक और फायदा यह है कि यह डेटाबेस संरचना को विस्तारित करने की सुविधा प्रदान करता है, क्योंकि मैं नीचे अनुकरण करूंगा।

परिदृश्य प्रगति: मैत्री स्थिति अवधारणा को शामिल करना

चूँकि दोस्ती समय के साथ विकसित हो सकती है, इसलिए आपको इस तरह की घटना पर नज़र रखनी पड़ सकती है, इस प्रकार आपको वैचारिक स्कीमा का विस्तार करना होगा और (ii) तार्किक लेआउट में कुछ और तालिकाओं की घोषणा करनी होगी। तो, आइए हम नए व्यापारों को शामिल करने के लिए अगले व्यापार नियमों की व्यवस्था करें:

  • एक फ्रेंडशिप में एक से कई फ्रेंडशिपस्टैटस होते हैं
  • एक FriendshipStatus को मुख्य रूप से इसके RequesterId , इसके AddresseeId और इसके SpecifiedDateTime के संयोजन द्वारा पहचाना जाता है
  • एक उपयोगकर्ता शून्य-एक-या कई फ्रेंडशिपस्टैटस निर्दिष्ट करता है
  • एक स्थिति जीरो-वन-या-कई फ्रेंडशिपस्टैट्स को वर्गीकृत करती है
  • एक स्थिति मुख्य रूप से उसके StatusCode द्वारा पहचानी जाती है
  • वैकल्पिक रूप से इसके नाम से एक स्थिति की पहचान की जाती है

विस्तारित IDEF1X आरेख

क्रमिक रूप से, पिछली IDEF1X आरेख को ऊपर वर्णित नई इकाई प्रकारों और अंतर्संबंध प्रकारों को शामिल करने के लिए बढ़ाया जा सकता है। नए लोगों से जुड़े पिछले तत्वों को दर्शाने वाला आरेख चित्र 2 में प्रस्तुत किया गया है :

चित्रा 2. मैत्री स्थिति IDEF1X आरेख

तार्किक संरचना जोड़

बाद में, हम निम्नलिखित घोषणाओं के साथ DDL लेआउट को लंबा कर सकते हैं:

--
CREATE TABLE MyStatus ( -- Denotes an independent entity type.
    StatusCode CHAR(1)  NOT NULL,
    Name       CHAR(30) NOT NULL,
    --
    CONSTRAINT MyStatus_PK PRIMARY KEY (StatusCode),
    CONSTRAINT MyStatus_AK UNIQUE      (Name) -- ALTERNATE KEY.
); 

CREATE TABLE FriendshipStatus ( -- Represents an associative entity type.
    RequesterId       INT      NOT NULL,
    AddresseeId       INT      NOT NULL,
    SpecifiedDateTime DATETIME NOT NULL,
    StatusCode        CHAR(1)  NOT NULL,
    SpecifierId       INT      NOT NULL,
    --
    CONSTRAINT FriendshipStatus_PK             PRIMARY KEY (RequesterId, AddresseeId, SpecifiedDateTime), -- Composite PRIMARY KEY.
    CONSTRAINT FriendshipStatusToFriendship_FK FOREIGN KEY (RequesterId, AddresseeId)
        REFERENCES Friendship  (RequesterId, AddresseeId), -- Composite FOREIGN KEY.
    CONSTRAINT FriendshipStatusToMyStatus_FK   FOREIGN KEY (StatusCode)
        REFERENCES MyStatus    (StatusCode),
    CONSTRAINT FriendshipStatusToSpecifier_FK  FOREIGN KEY (SpecifierId)
        REFERENCES UserProfile (UserId)      
);

नतीजतन, हर बार जब किसी दिए गए मैत्री की स्थिति को अप-टू-डेट रखने की आवश्यकता होती है, तो उपयोगकर्ताओं को केवल एक नई पंक्ति को सम्मिलित करना होगा , जिसमें:FriendshipStatus

  • उपयुक्त RequesterIdऔर AddresseeIdमूल्यों - संबंधित Friendshipपंक्ति से बाहर -;

  • नया और सार्थक StatusCodeमूल्य MyStatus.StatusCode- से वापस ले लिया ;

  • सटीक INSERTION तत्काल, अर्थात् - SpecifiedDateTimeनिश्चित रूप से एक सर्वर फ़ंक्शन का उपयोग करना ताकि आप इसे विश्वसनीय तरीके से पुनर्प्राप्त और बनाए रख सकें; तथा

  • वह SpecifierIdमान जो उस संकेत को इंगित करेगा जो आपके ऐप की सुविधाओं के साथ-साथ सिस्टम में UserIdनए-नए तरीके से दर्ज किया गया FriendshipStatusहै-।

उस सीमा तक, मान लें कि MyStatusतालिका निम्न डेटा को संलग्न करती है - PK मान जो (a) एंड यूज़र-, ऐप प्रोग्रामर- और DBA-friendly और (b) भौतिक कार्यान्वयन स्तर पर बाइट्स के संदर्भ में छोटे और तेज़ हैं -:

 + ------------ + ----------- +
 | स्टेटसकोड | नाम       |
 + ------------ + ----------- +
 | आर | अनुरोध किया |
 + ------------ + ----------- +
 | ए | स्वीकार किया |
 + ------------ + ----------- +
 | D | अस्वीकृत |
 + ------------ + ----------- +
 | B | फूला हुआ |
 + ------------ + ----------- +

इसलिए, FriendshipStatusतालिका नीचे दिखाए गए डेटा की तरह पकड़ सकती है:

 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | RequesterId | पताडी | SpecifiedDateTime        | स्टेटसकोड | स्पेसिफायर |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-01 16: 58: 12.000 | आर | 1750 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-02 09: 12: 05.000 | ए | 1748 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-04 10: 57: 01.000 | B | 1750 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-07 07: 33: 08.000 | आर | 1748 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-08 12: 12: 09.000 | ए | 1750 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +

जैसा कि आप देख सकते हैं, यह कहा जा सकता है कि FriendshipStatusतालिका समय श्रृंखला को शामिल करने के उद्देश्य से कार्य करती है ।


प्रासंगिक पद

आप में रुचि हो सकती है:

  • यह उत्तर जिसमें मैं दो भिन्न इकाई के बीच एक सामान्य कई-से-कई संबंधों से निपटने के लिए एक मूल विधि का सुझाव देता हूं।
  • आईडीईएफ 1 एक्स चित्र 1 में दिखाया गया है जो इस अन्य उत्तर को दिखाता है । विवाह और संतान नामक इकाई प्रकारों पर विशेष ध्यान दें , क्योंकि वे "पार्ट्स धमाका समस्या" को संभालने के दो और उदाहरण हैं।
  • यह पोस्ट जो एक कॉलम के भीतर सूचना के विभिन्न टुकड़ों को रखने के बारे में एक संक्षिप्त विचार प्रस्तुत करती है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.