2008-09-22 13 views
6

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

उदाहरण के रूप में निम्न त्वरित 'एन' गंदे स्कीमा का उपयोग करना, क्या MySQL को यह सुनिश्चित करने का कोई तरीका है कि product_cd और product_dvd दोनों पंक्तियां समान product_id साझा नहीं कर सकती हैं? डेटाबेस को इस संबंध को लागू करने की अनुमति देने के लिए स्कीमा को डिज़ाइन करने का कोई बेहतर तरीका है, या क्या यह संभव नहीं है?

CREATE TABLE IF NOT EXISTS `product` (
    `product_id` int(10) unsigned NOT NULL auto_increment, 
    `product_name` varchar(50) NOT NULL, 
    `description` text NOT NULL, 
    PRIMARY KEY (`product_id`) 
) ENGINE = InnoDB; 

CREATE TABLE `product_cd` (
    `product_cd_id` INT UNSIGNED NOT NULL AUTO_INCREMENT , 
    `product_id` INT UNSIGNED NOT NULL , 
    `artist_name` VARCHAR(50) NOT NULL , 
    PRIMARY KEY (`product_cd_id`) , 
    INDEX (`product_id`) 
) ENGINE = InnoDB; 

ALTER TABLE `product_cd` ADD FOREIGN KEY (`product_id`) 
    REFERENCES `product` (`product_id`) 
    ON DELETE RESTRICT ON UPDATE RESTRICT ; 

CREATE TABLE `product_dvd` (
    `product_dvd_id` INT UNSIGNED NOT NULL AUTO_INCREMENT , 
    `product_id` INT UNSIGNED NOT NULL , 
    `director` VARCHAR(50) NOT NULL , 
    PRIMARY KEY (`product_dvd_id`) , 
    INDEX (`product_id`) 
) ENGINE = InnoDB; 

ALTER TABLE `product_dvd` ADD FOREIGN KEY (`product_id`) 
    REFERENCES `product` (`product_id`) 
    ON DELETE RESTRICT ON UPDATE RESTRICT ; 

@Skliwz, आप कैसे चलाता स्कीमा के साथ इस बाधा प्रदान की लागू करने के लिए इस्तेमाल किया जा सकता के बारे में अधिक विवरण प्रदान करें कर सकते हैं?

@boes, यह बहुत अच्छा लगता है। यह उन परिस्थितियों में कैसे काम करता है जहां आपके बच्चे के बच्चे हैं? उदाहरण के लिए, अगर हमने product_movie जोड़ा और product_movie के बच्चे को product_dvd बनाया? क्या यह उत्पादकता के लिए चेक बाधा बनाने के लिए एक रखरखाव दुःस्वप्न होगा, सभी बच्चों के प्रकारों में भी कारक होना चाहिए?

+5

अपने प्रश्न को संपादित करने के बजाय उत्तरों पर टिप्पणियों का उपयोग करें। – epochwolf

उत्तर

3

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

CREATE TABLE IF NOT EXISTS `product` (
`product_id` int(10) unsigned NOT NULL auto_increment, 
'product_type' int not null, 
`product_name` varchar(50) NOT NULL, 
`description` text NOT NULL, 
PRIMARY KEY (`product_id`, 'product_type') 
) ENGINE = InnoDB; 

CREATE TABLE `product_cd` (
`product_id` INT UNSIGNED NOT NULL , 
'product_type' int not null default(1) check ('product_type' = 1) 
`artist_name` VARCHAR(50) NOT NULL , 
PRIMARY KEY (`product_id`, 'product_type') , 
) ENGINE = InnoDB; 

ALTER TABLE `product_cd` ADD FOREIGN KEY (`product_id`, 'product_type') 
REFERENCES `product` (`product_id`, 'product_type') 
ON DELETE RESTRICT ON UPDATE RESTRICT ; 
+2

-1। MySQL चेक बाधाओं को अनदेखा करता है। –

1

यदि आप MySQL 5.x का उपयोग करते हैं तो आप इन प्रकार की बाधाओं के लिए ट्रिगर्स का उपयोग कर सकते हैं।

एक और (उप-शीर्ष) विकल्प मूल तालिका में "प्रकार" कॉलम का उपयोग चुपचाप नकल को अनदेखा करने और सही "एक्सटेंशन तालिका" चुनने में सक्षम होने के लिए होगा।

+1

इस तरह की बाधा के लिए आप ट्रिगर का उपयोग कैसे कर सकते हैं? क्या आप एक उदाहरण प्रदान कर सकते हैं? – Shabbyrobe

3

आप केवल एक प्राथमिक कुंजी से दूसरी प्राथमिक कुंजी में एक विदेशी कुंजी जोड़ सकते हैं। चूंकि पीके को अद्वितीय होना है, इसलिए आप स्वचालित रूप से एक-से-एक संबंध प्राप्त करते हैं।

+0

इनो डीबी का उपयोग करके, मेरे लिए यह काम नहीं करता है। रिवर्स-इंजीनियरिंग स्क्रिप्ट के बाद भी, रिश्ते एक-से-कई रहता है। एक-से-एक संबंध बनाए रखने का एकमात्र प्रभावी तरीका विदेशी कुंजी कॉलम को अद्वितीय पर सेट करना है; इस तरह हम निश्चित हैं कि इसके लिए केवल एक रिकॉर्ड बनाया जाएगा। और यदि आप इस बाधा का उल्लंघन करने का प्रयास करते हैं तो आपको निम्न त्रुटि (MySQL 5.1) प्राप्त होती है: '1 त्रुटि तालिका 'testdb' में परिवर्तन सहेजती है।'table4': ' testdb''table4' में INSERT ('idtable4', 'label',' table3_idtable3') VALUES (0, 'soso', 0) 1062: कुंजी 'table3_idtable3_UNIQUE' रोलबैक पूर्ण ' – Hanynowsky

4

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

और आपको उत्पाद तालिका में प्रकार कॉलम की आवश्यकता हो सकती है।

8

विदेशी कुंजी के कॉलम पर एक अद्वितीय बाधा परिभाषित करके 1: 0-1 या 1: 1 रिश्ते को लागू किया जा सकता है, इसलिए केवल एक संयोजन मौजूद हो सकता है। आम तौर पर यह बाल तालिका की प्राथमिक कुंजी होगी।

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

+4

माइनस 1 के लिए डुप्लिकेट प्रविष्टि' 0 'क्योंकि यह जवाब नहीं देता है सवाल, एक उदाहरण प्रदान नहीं करता है और अभी भी बहुत सारे वोट प्राप्त करता है। सवाल का एक हिस्सा है: 'क्या यह सुनिश्चित करने का कोई तरीका है कि product_cd और product_dvd दोनों पंक्तियां समान उत्पाद_आईडी साझा नहीं कर सकती हैं। आप इसका उत्तर नहीं देते हैं। आपको ये वोट कौन दे रहा है? – boes

1

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

`1 error(s) saving changes to table testdb`.table4: INSERT INTO testdb.table4 (idtable4, label, table3_idtable3) VALUES (0, 'soso', 0) 1062: Duplicate entry '0' for key 'table3_idtable3_UNIQUE' Rollback complete 
संबंधित मुद्दे