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

एक से एक से अधिक कैसे बनाएं

आप विरासत का उपयोग कर रहे हैं (जिसे इकाई-संबंध मॉडलिंग में "उपवर्ग" या "श्रेणी" के रूप में भी जाना जाता है)। सामान्य तौर पर, डेटाबेस में इसका प्रतिनिधित्व करने के 3 तरीके हैं:

  1. "सभी कक्षाएं एक टेबल में": माता-पिता और सभी बाल वर्गों (यानी सभी माता-पिता और बच्चे के कॉलम के साथ) को "कवर" करने के लिए केवल एक टेबल है, यह सुनिश्चित करने के लिए चेक बाधा के साथ फ़ील्ड का सही सबसेट गैर-नल है (यानी दो अलग-अलग बच्चे "मिश्रण" नहीं करते हैं)।
  2. "प्रति तालिका कंक्रीट वर्ग": प्रत्येक बच्चे के लिए एक अलग टेबल है, लेकिन कोई पैरेंट टेबल नहीं है। इसके लिए माता-पिता के रिश्ते (आपके मामले में इन्वेंटरी <- स्टोरेज) को सभी बच्चों में दोहराया जाना आवश्यक है।
  3. "प्रति तालिका कक्षा": प्रत्येक बच्चे के लिए एक पैरेंट टेबल और एक अलग टेबल होना, जो आप करने की कोशिश कर रहे हैं। यह सबसे साफ है, लेकिन कुछ प्रदर्शन खर्च कर सकते हैं (ज्यादातर डेटा को संशोधित करते समय, पूछताछ करते समय इतना अधिक नहीं क्योंकि आप सीधे बच्चे से जुड़ सकते हैं और माता-पिता को छोड़ सकते हैं)।

मैं आमतौर पर तीसरा दृष्टिकोण पसंद करता हूं, लेकिन उपस्थिति . दोनों को लागू करता हूं और विशिष्टता आवेदन स्तर पर एक बच्चे की। डेटाबेस स्तर पर दोनों को लागू करना थोड़ा बोझिल है, लेकिन यह किया जा सकता है यदि DBMS आस्थगित बाधाओं का समर्थन करता है। उदाहरण के लिए:

CHECK (
    (
        (VAN_ID IS NOT NULL AND VAN_ID = STORAGE_ID)
        AND WAREHOUSE_ID IS NULL
    )
    OR (
        VAN_ID IS NULL
        AND (WAREHOUSE_ID IS NOT NULL AND WAREHOUSE_ID = STORAGE_ID)
    )
)

यह दोनों विशिष्टता को लागू करेगा (CHECK . के कारण ) और उपस्थिति (CHECK . के संयोजन के कारण) और FK1 /FK2 ) बच्चे की।

दुर्भाग्य से, MS SQL सर्वर आस्थगित बाधाओं का समर्थन नहीं करता है, लेकिन आप संग्रहीत प्रक्रियाओं के पीछे पूरे ऑपरेशन को "छिपाने" में सक्षम हो सकते हैं और क्लाइंट को सीधे तालिकाओं को संशोधित करने से मना कर सकते हैं।

आस्थगित बाधाओं के बिना केवल विशिष्टता को लागू किया जा सकता है:

STORAGE_TYPE एक प्रकार का विभेदक है, आमतौर पर स्थान बचाने के लिए एक पूर्णांक (उपरोक्त उदाहरण में, 0 और 1 आपके आवेदन के लिए "ज्ञात" हैं और तदनुसार व्याख्या की गई है)।

VAN.STORAGE_TYPE और WAREHOUSE.STORAGE_TYPE भंडारण को बचाने और CHECK की आवश्यकता से बचने के लिए गणना की जा सकती है (उर्फ "गणना") कॉलम स.

--- संपादित करें ---

कंप्यूटेड कॉलम SQL सर्वर के तहत इस तरह काम करेंगे:

CREATE TABLE STORAGE (
    STORAGE_ID int PRIMARY KEY,
    STORAGE_TYPE tinyint NOT NULL,
    UNIQUE (STORAGE_ID, STORAGE_TYPE)
);

CREATE TABLE VAN (
    STORAGE_ID int PRIMARY KEY,
    STORAGE_TYPE AS CAST(0 as tinyint) PERSISTED,
    FOREIGN KEY (STORAGE_ID, STORAGE_TYPE) REFERENCES STORAGE(STORAGE_ID, STORAGE_TYPE)
);

CREATE TABLE WAREHOUSE (
    STORAGE_ID int PRIMARY KEY,
    STORAGE_TYPE AS CAST(1 as tinyint) PERSISTED,
    FOREIGN KEY (STORAGE_ID, STORAGE_TYPE) REFERENCES STORAGE(STORAGE_ID, STORAGE_TYPE)
);

-- We can make a new van.
INSERT INTO STORAGE VALUES (100, 0);
INSERT INTO VAN VALUES (100);

-- But we cannot make it a warehouse too.
INSERT INTO WAREHOUSE VALUES (100);
-- Msg 547, Level 16, State 0, Line 24
-- The INSERT statement conflicted with the FOREIGN KEY constraint "FK__WAREHOUSE__695C9DA1". The conflict occurred in database "master", table "dbo.STORAGE".

दुर्भाग्य से, SQL सर्वर को एक परिकलित कॉलम की आवश्यकता होती है जो एक विदेशी में उपयोग किया जाता है जारी रखने की कुंजी। अन्य डेटाबेस में यह सीमा नहीं हो सकती है (जैसे Oracle के वर्चुअल कॉलम), जो कुछ संग्रहण स्थान बचा सकते हैं।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर में "पंक्ति संस्करण" क्या है?

  2. स्कीमा को नहीं छोड़ा जा सकता, क्योंकि यह मौजूद नहीं है या आपके पास अनुमति नहीं है। - SQL सर्वर / TSQL ट्यूटोरियल भाग 29

  3. अद्यतन विवरण से प्रभावित पंक्तियों की वापसी संख्या

  4. पता करें कि क्या कोई ऑब्जेक्ट SQL सर्वर में OBJECTPROPERTY () के साथ एक विदेशी कुंजी है

  5. डेटाबेस और स्कीमा के बीच अंतर