2012-04-09 8 views
13

मेरे पास दो टेबल पुस्तकें और ऑडियोबुक्स हैं, जिनमें से दोनों में आईएसबीएन की प्राथमिक कुंजी है। मेरे पास एक सारणी लिखी गई है जिसमें एक आईएसबीएन विशेषता है जिसमें पुस्तकों और ऑडियोबुक्स आईएसबीएन के लिए एक विदेशी कुंजी बाधा है। जब मैं लिखित में सम्मिलित करता हूं तो यह मुद्दा यह है कि postgresql चाहता है कि आईएसबीएन मैं लिखित रूप में लिखित रूप में पुस्तकें और ऑडीबुक्स दोनों में शामिल करूं। मुझे यह समझ में आता है कि लिखित एक टेबल है जो लेखकों और पुस्तकों/ऑडीबुक्स को लिखे गए हैं, हालांकि यह पोस्टग्रेस्क्ल में एक तालिका में अनुवाद नहीं करता है। वैकल्पिक समाधान जिसे मैं कार्यान्वित करने के बारे में सोच रहा हूं, में दो नए संबंध थे audiobook_writtenby और books_writtenby लेकिन मुझे यकीन नहीं है कि यह एक अच्छा विकल्प है। क्या आप मुझे एक विचार दे सकते हैं कि मैं दो अलग-अलग तालिकाओं का संदर्भ देने वाली लिखित एक तालिका रखने के बारे में अपने मूल विचार को कैसे कार्यान्वित करूं या मैं अपने डेटाबेस को बेहतर तरीके से कैसे डिजाइन कर सकता हूं। कृपया मुझे बताएं कि क्या आपको और अधिक जानकारी चाहिये?POSTGRESQL विदेशी कुंजी संदर्भ दो अलग-अलग टेबल्स की प्राथमिक कुंजी

उत्तर

4

आरडीबीएमएस पॉलिमॉर्फिक विदेशी कुंजी बाधाओं का समर्थन नहीं करते हैं। आप जो करना चाहते हैं वह उचित है, लेकिन संबंध मॉडल द्वारा अच्छी तरह से समायोजित कुछ नहीं है और ओआरएम सिस्टम बनाते समय ऑब्जेक्ट रिलेशनल प्रतिबाधा विसंगति की वास्तविक समस्याओं में से एक है। Nice discussion on this on Ward's WIki

आपकी समस्या का एक दृष्टिकोण एक अलग टेबल, ज्ञात_आईएसबीएनएस, और पुस्तकों और ऑडियोबुक पर बाधाओं और/या ट्रिगर्स सेट करना हो सकता है ताकि तालिका में दोनों प्रकार की विशिष्ट पुस्तक तालिकाओं के सभी मान्य आईएसबीएन शामिल हों। फिर लिखित रूप में आपकी एफके बाधा ज्ञात_आईएसबीएनएस के खिलाफ जांच करेगी।

+3

संबंधपरक मॉडल और एसक्यूएल डेटाबेस वास्तव में इस तरह की चीज़ को अच्छी तरह से संभालते हैं। समस्या संबंधपरक या एसक्यूएल नहीं है; समस्या यह है कि स्पष्ट बाधाओं में से एक गलत तरीके से लागू किया गया है। (बाधा यह है कि पुस्तकों और ऑडियोबुक्स के लिए आईएसबीएन एक ही डोमेन से खींचे जाते हैं।) –

3

आप दोनों दुनिया के सर्वश्रेष्ठ प्राप्त करने के लिए टेबल विरासत का उपयोग कर सकते हैं। लिखितby तालिका का संदर्भ देने वाले INHERITS खंड के साथ audiobook_writtenby और books_writtenby बनाएं। जैसा कि आप वर्णन करते हैं, विदेशी कुंजी को बाल स्तर पर परिभाषित किया जा सकता है, लेकिन आप अभी भी उच्च स्तर पर डेटा का संदर्भ दे सकते हैं। (तुम भी एक दृश्य के साथ ऐसा कर सकता है, लेकिन यह लग रहा है विरासत की तरह इस मामले में क्लीनर हो सकता है।)

डॉक्स देखें:

http://www.postgresql.org/docs/current/interactive/sql-createtable.html

http://www.postgresql.org/docs/current/interactive/tutorial-inheritance.html

http://www.postgresql.org/docs/current/interactive/ddl-inherit.html

ध्यान दें कि यदि आप ऐसा करते हैं तो संभवत: लिखित तालिका पर एक बेहतर इन्टर ट्रिगर जोड़ना चाहते हैं।

26

PostgreSQL में ऐसा करने के एक से अधिक तरीके हैं। निजी तौर पर, मैं इस तरह से पसंद करता हूं।

-- This table should contain all the columns common to both 
-- audio books and printed books. 
create table books (
    isbn char(13) primary key, 
    title varchar(100) not null, 
    book_type char(1) not null default 'p' 
    check(book_type in ('a', 'p')), 
    -- This unique constraint lets the tables books_printed and books_audio 
    -- target the isbn *and* the type in a foreign key constraint. 
    -- This prevents you from having an audio book in this table 
    -- linked to a printed book in another table. 
    unique (isbn, book_type) 
); 

-- Columns unique to printed books. 
create table books_printed (
    isbn char(13) primary key references books (isbn), 
    -- Allows only one value. This plus the FK constraint below guarantee 
    -- that this row will relate to a printed book row, not an audio book 
    -- row, in the table books. The table "books_audio" is similar. 
    book_type char(1) default 'p' 
    check (book_type = 'p'), 
    foreign key (isbn, book_type) references books (isbn, book_type), 
    other_columns_for_printed_books char(1) default '?' 
); 

-- Columns unique to audio books. 
create table books_audio (
    isbn char(13) primary key references books (isbn), 
    book_type char(1) default 'a' 
    check (book_type = 'a'), 
    foreign key (isbn, book_type) references books (isbn, book_type), 
    other_columns_for_audio_books char(1) default '?' 
); 

-- Authors are common to both audio and printed books, so the isbn here 
-- references the table of books. 
create table book_authors (
    isbn char(13) not null references books (isbn), 
    author_id integer not null references authors (author_id), -- not shown 
    primary key (isbn, author_id) 
); 
-1

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

+2

भले ही आपका उत्तर तकनीकी रूप से सही है, मुझे नहीं लगता कि इसका पालन किया जाना चाहिए। PostgreSQL यह साफ तरह से मॉडलिंग का समर्थन करता है। एक ही टेबल में एकाधिक ऑब्जेक्ट्स को एक साथ फोल्ड करना आमतौर पर एक बड़ी गड़बड़ी में समाप्त होता है। – Theuni

संबंधित मुद्दे