MySQL प्राइमरी की को अपडेट करना


103

मेरे पास user_interactions4 कॉलम वाली एक तालिका है :

 user_1
 user_2
 type
 timestamp

प्राथमिक कुंजी है (user_1,user_2,type)
और मैं इसे बदलना चाहता हूं(user_2,user_1,type)

तो मैंने क्या किया:

drop primary key ...  
add primary key (user_2,user_1,type)...

और वोइला ...

समस्या यह है कि डेटाबेस एक सर्वर पर लाइव है।

इसलिए, इससे पहले कि मैं प्राथमिक कुंजी को अपडेट कर पाता, कई डुप्लिकेट पहले ही क्रेप कर चुके हैं, और वे लगातार रेंग रहे हैं।

क्या करें?

अब मैं जो करना चाहता हूं वह डुप्लिकेट को हटाने और लोगों को नवीनतम timestamp(जो तालिका में एक स्तंभ है) के साथ रखना है ।

और फिर किसी तरह प्राथमिक कुंजी को फिर से अपडेट करें।


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

5
अगली बार जब एक अद्वितीय कुंजी प्राथमिक कुंजी के रूप में एक ही कॉलम के साथ के बाद अपडेट प्राथमिक कुंजी जोड़ने के लिए,
Knittl

1
@Ignacio, यह एक सर्वर पर लाइव है, लेकिन यह एक बैकअप-बैकअप सर्वर :-) है। मैं एक डीबीए नहीं हूं, लेकिन मैं इस बात को वास्तव में लाइव सर्वर पर नहीं
आज़माऊंगा

1
@knittl, हाँ यही मैंने अभी सोचा है, हालांकि बहुत देर हो चुकी है :-)
simplefuzz

4
@pixeline: यह एक कंपाउंड प्राथमिक कुंजी है।
इग्नासियो वाज़केज़-अब्राम्स

जवाबों:


231

अगली बार, प्राथमिक कुंजी को अपडेट करने के लिए एकल "परिवर्तन तालिका" कथन का उपयोग करें।

alter table xx drop primary key, add primary key(k1, k2, k3);

चीजों को ठीक करने के लिए:

create table fixit (user_2, user_1, type, timestamp, n, primary key( user_2, user_1, type) );
lock table fixit write, user_interactions u write, user_interactions write;

insert into fixit 
select user_2, user_1, type, max(timestamp), count(*) n from user_interactions u 
group by user_2, user_1, type
having n > 1;

delete u from user_interactions u, fixit 
where fixit.user_2 = u.user_2 
  and fixit.user_1 = u.user_1 
  and fixit.type = u.type 
  and fixit.timestamp != u.timestamp;

alter table user_interactions add primary key (user_2, user_1, type );

unlock tables;

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

मुख्य समस्या यह है कि यदि आपके पास समान टाइमस्टैम्प के साथ कुछ डुप्लिकेट हैं।


11

यदि प्राथमिक कुंजी एक auto_increment मान होती है, तो आपको स्वतः वेतन वृद्धि को हटाना होगा, फिर प्राथमिक कुंजी को छोड़ना होगा और फिर ऑटो-वृद्धि को जोड़ना होगा

ALTER TABLE `xx`
MODIFY `auto_increment_field` INT, 
DROP PRIMARY KEY, 
ADD PRIMARY KEY (new_primary_key);

फिर ऑटो वेतन वृद्धि वापस जोड़ें

ALTER TABLE `xx` ADD INDEX `auto_increment_field` (auto_increment_field),
MODIFY `auto_increment_field` int auto_increment;

फिर पिछले मूल्य पर ऑटो वेतन वृद्धि वापस सेट करें

ALTER TABLE `xx` AUTO_INCREMENT = 5;

2

आप IGNOREकीवर्ड का उपयोग कर सकते हैं , उदाहरण:

 update IGNORE table set primary_field = 'value'...............
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.