2009-07-24 5 views
6

हाय आई इस के साथ थोड़ा संघर्ष कर रहा है और कुछ विचारों का उपयोग कर सकता है ...किसी भी तालिका से जुड़े रिकॉर्ड्स?

कहें कि मेरे डेटाबेस में निम्न तालिकाएं हैं; ग्राहकों supplers SalesInvoices PurchaseInvoices मुद्राओं

आदि आदि

मैं रिकॉर्ड

किसी भी प्रकार की एक "नोट्स" रिकॉर्ड जोड़ने में सक्षम होना चाहते हैं नोट्स तालिका इस

चाहते हैं
NoteID  Int (PK) 
NoteFK  Int 
NoteFKType Varchar(3) 
NoteText  varchar(100) 
NoteDate  Datetime 

जहां नोटएफके ग्राहक या आपूर्तिकर्ता आदि का पीके है और नोटएफके टाइप टाइप करता है कि किस प्रकार का रेको rd नोट

अब मुझे एहसास है कि मैं एक एफके नहीं जोड़ सकता जो नोटफैक के बिना सभी तालिकाओं में मौजूद होने के बिना एकाधिक तालिकाओं का संदर्भ देता है।

तो आप उपर्युक्त कैसे डिजाइन करेंगे? टिप्पणी FK ऊपर टेबल

चीयर्स में से किसी में हो सकता है, डैनियल

+0

डेटाबेस स्तर रेफरेंसियल अखंडता आवश्यक है, या आप एप्लिकेशन प्रबंधित रेफरेंसियल अखंडता के साथ रह सकते हैं? – tschaible

उत्तर

-2

क्यों आप इसे दूसरी तरह के आसपास करते हैं और अन्य तालिकाओं (ग्राहक, प्रदायक आदि आदि) में एक विदेशी कुंजी है न की जरूरत के लिए NotesID। इस तरह आपके पास एक से एक मैपिंग है।

+1

क्या होगा यदि वह एक-से-कई संबंध रखना चाहता है? एक इकाई के लिए कई नोट्स।वह कई अतिरिक्त तालिकाओं के साथ खत्म होगा जो आवश्यक नहीं हैं। – maciejkow

+1

यह गारंटी नहीं देगा कि एक ही नोटआईडी को एक से अधिक बार संदर्भित नहीं किया गया है। लेकिन यह व्यापार की आवश्यकता पर निर्भर करता है। –

+0

यदि किसी के लिए कई की आवश्यकता है, तो हमारे पास लिंक करने के लिए अलग-अलग तालिकाओं के बजाय एक अल्पविराम से अलग नोट्स को संग्रहीत किया जा सकता है (यह केवल एक वर्कअराउंड है)। –

0

आप ग्राहकों, आपूर्तिकर्ता इत्यादि के लिए एक GUID फ़ील्ड जोड़ सकते हैं। फिर नोट्स तालिका में, उस GUID को संदर्भित करने के लिए विदेशी कुंजी बदलें।

यह डेटा अखंडता के लिए मदद नहीं करता है। लेकिन यह एम-टू-एन संबंधों को किसी भी संख्या में आसानी से संभव बनाता है और यह आपको नोट्स तालिका में नोटफैटाइप कॉलम को परिभाषित करने से बचाता है।

2

मुझे लगता है कि आपका डिज़ाइन ठीक है, अगर आप इस तथ्य को स्वीकार कर सकते हैं, तो डीबी सिस्टम यह जांच नहीं करेगा कि कोई नोट अन्य तालिका में किसी मौजूदा इकाई का संदर्भ दे रहा है या नहीं। यह एकमात्र ऐसा डिज़ाइन है जिसे मैं सोच सकता हूं कि डुप्लिकेशन की आवश्यकता नहीं है और अधिक तालिकाओं के लिए स्केलेबल है।

जिस तरह से आपने इसे डिज़ाइन किया है, जब आप कोई अन्य इकाई प्रकार जोड़ते हैं जिसके लिए आप नोट्स रखना चाहते हैं, तो आपको अपना मॉडल बदलना नहीं होगा। साथ ही, आपको अपने मौजूदा मॉडल, या अतिरिक्त तालिकाओं में कोई अतिरिक्त कॉलम शामिल करने की आवश्यकता नहीं है।

डेटा अखंडता सुनिश्चित करने के लिए, आप ट्रिगर या कुछ सॉफ़्टवेयर समाधान सेट कर सकते हैं जो थोड़ी देर में नोट्स तालिका को साफ़ कर देगा।

3

आपको इस सीमा को स्वीकार करना होगा कि आप इस विदेशी कुंजी बाधा के बारे में डेटाबेस नहीं पढ़ सकते हैं। तो आपको अखंडता जांच (और कैस्केडिंग डिलीट) के बिना करना होगा।

आपका डिज़ाइन ठीक है। यह अतिरिक्त तालिकाओं के लिए आसानी से एक्स्टेंसिबल है, आपके पास प्रति इकाई एकाधिक नोट्स हो सकते हैं, और लक्ष्य तालिकाओं को नोट्स सुविधा के बारे में भी जागरूक होने की आवश्यकता नहीं है।

एक लाभ यह है कि यह डिज़ाइन प्रति इकाई तालिका में एक अलग नोट तालिका का उपयोग कर खत्म हो गया है, यह है कि आप आसानी से सभी नोट्स में क्वेरी चला सकते हैं, उदाहरण के लिए "सबसे हालिया नोट्स" या "किसी दिए गए उपयोगकर्ता द्वारा बनाए गए सभी नोट्स"।

उस तालिका के तर्क के लिए बहुत बड़ा बढ़ रहा है, इसे पांच टेबल कहने के लिए विभाजित करना तालिका के आकार के लगभग पांचवें हिस्से को कम कर देगा, लेकिन इससे इंडेक्स-आधारित पहुंच के लिए कोई फर्क नहीं पड़ता। डेटाबेस बड़े टेबल को संभालने के लिए बनाए जाते हैं (जब तक वे ठीक से अनुक्रमित होते हैं)।

0

आप ट्रिगर्स के साथ आसानी से "बहु" --foreign कुंजी को कार्यान्वित कर सकते हैं। ट्रिगर आपको बहुत लचीला तंत्र देंगे और आप अपनी इच्छानुसार किसी भी ईमानदारी जांच कर सकते हैं।

1

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

+0

+1 मैं सहमत हूं और इसके लिए झुका सकता हूं। लंबे समय तक आप केवल अपने समाधान को जटिल बना रहे हैं और तकनीकी ऋण जोड़ रहे हैं जिसे अंततः निपटाया जाना चाहिए। –

+0

दूसरी तरफ, वह अपने वर्तमान समाधान के साथ सभी नोटों में चलने वाले प्रश्नों के साथ कर सकता है, जो कई नोट टेबल के साथ मुश्किल होगा। – Thilo

+1

@ थिलो - माइकल की सलाह के साथ, एक एसक्यूएल व्यू सभी नोट्स टेबल को एक क्वेरी स्रोत में एकत्र करने का एक और उचित तरीका है। –

1

मैं माइकल मैकलोस्की से एक डिग्री के लिए सहमत हूं।

मेरे दिमाग में सवाल यह है कि: एकाधिक नोट्स टेबल रखने की तकनीकी लागत क्या है?

मेरे दिमाग में, एक ही कार्यक्षमता को एक ही तालिका में समेकित करना बेहतर है। यह रिपोर्टिंग और अन्य आगे के विकास को आसान बनाता है। प्रबंधित करने के लिए छोटे और आसान टेबल की सूची रखने का उल्लेख नहीं है।

यह एक संतुलित कार्य है, आपको दोनों लाभों को पूर्व निर्धारित करने और इस तरह कुछ करने की लागत को पूर्व निर्धारित करने की आवश्यकता है। मेरा व्यक्तिगत प्राथमिकता डाटाबेस रेफरेंसियल अखंडता है। अखंडता के आवेदन प्रबंधन को मेरी राय में, व्यावसायिक तर्क को सीमित किया जाना चाहिए। डेटाबेस सुनिश्चित करना चाहिए डेटा हमेशा सुसंगत और वैध है ...


वास्तव में अपने प्रश्न का उत्तर देने ...

विकल्प मैं का प्रयोग करेंगे एक उपयोगकर्ता का उपयोग कर एक चेक बाधा परिभाषित किया गया है मूल्यों की जांच करने के लिए समारोह। यह एम $ एसक्यूएल सर्वर में काम करता है ...

CREATE TABLE Test_Table_1 (id INT IDENTITY(1,1), val INT) 
GO 
CREATE TABLE Test_Table_2 (id INT IDENTITY(1,1), val INT) 
GO 
CREATE TABLE Test_Table_3 (fk_id INT, table_name VARCHAR(64)) 
GO 

CREATE FUNCTION id_exists (@id INT, @table_name VARCHAR(64)) 
RETURNS INT 
AS 
BEGIN 
    IF (@table_name = 'Test_Table_1') 
     IF EXISTS(SELECT * FROM Test_Table_1 WHERE id = @id) 
      RETURN 1 
    ELSE 
    IF (@table_name = 'Test_Table_2') 
     IF EXISTS(SELECT * FROM Test_Table_2 WHERE id = @id) 
      RETURN 1 

    RETURN 0 
END 
GO 

ALTER TABLE Test_Table_3 WITH CHECK ADD CONSTRAINT 
    CK_Test_Table_3 CHECK ((dbo.id_exists(fk_id,table_name)=(1))) 
GO 
ALTER TABLE [dbo].[Test_Table_3] CHECK CONSTRAINT [CK_Test_Table_3] 
GO 

INSERT INTO Test_Table_1 SELECT 1 
GO 
INSERT INTO Test_Table_1 SELECT 2 
GO 
INSERT INTO Test_Table_1 SELECT 3 
GO 
INSERT INTO Test_Table_2 SELECT 1 
GO 
INSERT INTO Test_Table_2 SELECT 2 
GO 
INSERT INTO Test_Table_3 SELECT 3, 'Test_Table_1' 
GO 
INSERT INTO Test_Table_3 SELECT 3, 'Test_Table_2' 
GO 

उस उदाहरण में, अंतिम सम्मिलन कथन विफल हो जाएगा।

1

आप एक दूसरे के लिए नोट टेबल में एक कॉलम रखने की लागत पर एफके रेफरेंसियल अखंडता प्राप्त कर सकते हैं।

create table Notes (
    id int PRIMARY KEY, 
    note varchar (whatever), 
    customer_id int NULL REFERENCES Customer (id), 
    product_id int NULL REFERENCES Product (id) 
) 

फिर आपको यह सुनिश्चित करने के लिए एक बाधा की आवश्यकता होगी कि आपके पास केवल कॉलम सेट में से एक है।

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

यदि आप एक और संदर्भ तालिका जोड़ना चाहते हैं तो इस डिज़ाइन को नोट्स में एक नया कॉलम जोड़ने की आवश्यकता होगी।

+0

शायद यह अब तक का सबसे सुरुचिपूर्ण समाधान है। – Thilo