8

मैं दो पहले से मौजूद तालिकाओं (आंशिक रूप से) जो देखो है मोटे तौर पर इस तरह:MySQL प्राथमिक कुंजी बदल देते हैं विदेशी कुंजी contraints मौजूद

CREATE TABLE parent (
    old_pk CHAR(8) NOT NULL PRIMARY KEY 
) ENGINE=InnoDB; 

CREATE TABLE child (
    parent_key CHAR(8), 
    FOREIGN KEY (parent_key) REFERENCES parent(old_pk) 
     ON UPDATE CASCADE ON DELETE CASCADE 
) ENGINE=InnoDB; 

मैं एक नया ऑटो बढ़ाने पूर्णांक parent को id स्तंभ जोड़ना चाहते हैं और इसके बजाय इसे प्राथमिक कुंजी के रूप में उपयोग करें, जबकि old_pk को एक अनन्य कुंजी के रूप में रखते हुए और child जैसे अन्य तालिकाओं को विदेशी कुंजी उल्लंघनों में संदर्भित करने की अनुमति दें। दुर्भाग्य से, बस कह ALTER TABLE parent DROP PRIMARY KEY काम नहीं करता:

त्रुटि कोड: 1025

'./data/parent' को './data/#sql-4013_70f5e' (errno का नाम बदलने पर त्रुटि: 150)

कुछ googling से पता चलता है कि यह child से मौजूदा विदेशी कुंजी संदर्भ के कारण है। संक्षेप में, मुझे MySQL को बताने का एक तरीका चाहिए "इस अन्य कॉलम को प्राथमिक कुंजी के रूप में उपयोग करें, लेकिन मूल की अनूठी-कुंजी-नज़र को न भूलें"। child से मुख्य बाधाओं को छोड़ने और बाद में उन्हें बहाल करने के अलावा, इसे पूरा करने का कोई तरीका है?

मान लें कि मुझे उसी डेटा के साथ प्रतियां बनाने और बाद में उन्हें स्वैप करने के बजाय, तालिकाओं को स्थानांतरित करना होगा। मैंने टेबल को बदलने से पहले SET FOREIGN_KEY_CHECKS = 0 का उपयोग करने का प्रयास किया है, लेकिन यह मदद नहीं करता है।

+0

है यही कारण है कि मैं उपयोगकर्ता के लिए दृश्यमान प्राथमिक कुंजी नहीं बनाते हैं (i से किराए की प्राथमिक कुंजी के लिए सभी कर रहा हूँ गेट-गो), उपयोगकर्ता बदलती आवश्यकताएं सिरदर्द हैं, लेकिन यह जानना अच्छा है कि आप अपना डेटाबेस उपयोग सरोगेट प्राथमिक कुंजी http://en.wikipedia.org/wiki/Surrogate_key –

उत्तर

7

एक सूचकांक (यह भी अद्वितीय हो सकता है) प्राथमिक कुंजी छोड़ने से पहले old_pk में जोड़ें:

mysql> CREATE TABLE parent (
    ->  old_pk CHAR(8) NOT NULL PRIMARY KEY 
    ->) ENGINE=InnoDB; 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE child (
    ->  parent_key CHAR(8), 
    ->  FOREIGN KEY (parent_key) REFERENCES parent(old_pk) 
    ->   ON UPDATE CASCADE ON DELETE CASCADE 
    ->) ENGINE=InnoDB; 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO parent VALUES ('a'); 
Query OK, 1 row affected (0.01 sec) 

mysql> CREATE INDEX old_pk_unique ON parent (old_pk); 
Query OK, 1 row affected (0.01 sec) 
Records: 1 Duplicates: 0 Warnings: 0 

mysql> ALTER TABLE parent DROP PRIMARY KEY; 
Query OK, 1 row affected (0.01 sec) 
Records: 1 Duplicates: 0 Warnings: 0 

mysql> INSERT INTO child VALUES ('a'); 
Query OK, 1 row affected (0.00 sec) 

mysql> SHOW CREATE TABLE parent; 
+--------+------------------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                             | 
+--------+------------------------------------------------------------------------------------------------------------------------------+ 
| parent | CREATE TABLE `parent` (
    `old_pk` char(8) NOT NULL, 
    KEY `old_pk_unique` (`old_pk`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 
+--------+------------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> INSERT INTO child VALUES ('b'); 
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test/child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_key`) REFERENCES `parent` (`old_pk`) ON DELETE CASCADE ON UPDATE CASCADE) 

mysql> INSERT INTO parent VALUES ('b'); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO child VALUES ('b'); 
Query OK, 1 row affected (0.01 sec) 

mysql> ALTER TABLE parent ADD id INT; 
Query OK, 2 rows affected (0.00 sec) 
Records: 2 Duplicates: 0 Warnings: 0 

mysql> UPDATE parent SET id = 1 WHERE old_pk = 'a'; 
Query OK, 1 row affected (0.01 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> UPDATE parent SET id = 2 WHERE old_pk = 'b'; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> ALTER TABLE parent ADD PRIMARY KEY (id); 
Query OK, 2 rows affected (0.00 sec) 
Records: 2 Duplicates: 0 Warnings: 0 

mysql> SHOW CREATE TABLE parent; 
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                                            | 
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| parent | CREATE TABLE `parent` (
    `old_pk` char(8) NOT NULL, 
    `id` int(11) NOT NULL default '0', 
    PRIMARY KEY (`id`), 
    KEY `old_pk_unique` (`old_pk`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 
+0

मेरे लिए बिल्कुल काम नहीं करता है। –

-7

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

मैं इसे टिप्पणियों/चर्चा का विरोध करने के लिए खुले दिमाग के साथ कहता हूं। मैं यह नहीं कह रहा हूं कि यह सुझाव सही है, सिर्फ यह है कि मैंने जिन दुकानों में काम किया है, उनमें प्रचलित राय रही है।

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

+0

"[अधिकतम] पैमाने पर" प्रथाओं का उपयोग कर रहे हैं ! = सर्वोत्तम प्रथाओं। – ProfileTwist

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