एक विदेशी कुंजी विवश तालिका को कैसे काट दिया जाए?


648

काम पर ट्रंकट क्यों नहीं mygroup? हालांकि मेरे पास है ON DELETE CASCADE SET:

त्रुटि 1701 (42000): एक मेज एक विदेशी कुंजी बाधा में संदर्भित काट-छांट कर सकते हैं नहीं ( mytestinstance, बाधा instance_ibfk_1विदेशी कुँजी ( GroupID) दें संदर्भ mytestmygroup( ID))

drop database mytest;
create database mytest;
use mytest;

CREATE TABLE mygroup (
   ID    INT NOT NULL AUTO_INCREMENT PRIMARY KEY
) ENGINE=InnoDB;

CREATE TABLE instance (
   ID           INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   GroupID      INT NOT NULL,
   DateTime     DATETIME DEFAULT NULL,

   FOREIGN KEY  (GroupID) REFERENCES mygroup(ID) ON DELETE CASCADE,
   UNIQUE(GroupID)
) ENGINE=InnoDB;

जवाबों:


1000

आप TRUNCATEएक तालिका नहीं बना सकते हैं जिस पर एफके की कमी है, उस पर लागू है ( TRUNCATEजैसा नहीं है DELETE)।

इसके चारों ओर काम करने के लिए, इनमें से किसी भी एक समाधान का उपयोग करें। दोनों डेटा अखंडता को नुकसान पहुंचाने के जोखिम पेश करते हैं।

विकल्प 1:

  1. अड़चनें दूर करें
  2. प्रदर्शन TRUNCATE
  3. मैन्युअल पंक्तियों अब के लिए संदर्भ को नष्ट कहीं नहीं
  4. अड़चन पैदा करो

विकल्प 2: उनके उत्तर में user447951 द्वारा सुझाया गया

SET FOREIGN_KEY_CHECKS = 0; 
TRUNCATE table $table_name; 
SET FOREIGN_KEY_CHECKS = 1;

46
@barjonah: वास्तव में, यह डेटा अखंडता को तोड़ सकता है (देखें stackoverflow.com/questions/5452760/… )। तो, जिसे आप वास्तविक दुनिया में "प्रकाश" कहते हैं, उसे एक बुरा अभ्यास माना जाता है। पुनश्च:
डाउनवोट के

1
यहाँ अनाथ विदेशी कुंजियों को खोजने का एक बहुत अच्छा तरीका है (डेटा अखंडता को पुनर्स्थापित करें) http://stackoverflow.com/a/12085689/997776
SandorRacz

Truncate से पहले विदेशी कुंजी को अक्षम करना भी एक अच्छा तरीका है, मैंने इसे स्रोत से सफलता के साथ किया: stackoverflow.com/questions/8641703/…
गोबर

2
@ विदेशी कुंजी जांच अक्षम करना केवल विकास की अवधि में अनुमत है। यह किसी भी मौजूदा रिश्ते को तोड़ता है। डेटा अखंडता के बारे में zerkms 100% सही है। जब तक आप इसे पूरी तरह से (या कम से कम सभी संबंधित तालिकाओं) को खाली करने की योजना नहीं बना रहे हों, तब तक आप विदेशी कुंजी जांच को अक्षम नहीं कर सकते हैं
NoobishPro

1
@ कमलेश यह मेरा समाधान नहीं है, मैंने सलाह दी कि इसे बर्बर तरीके से मत करो।
झटके

1308

हाँ तुम कर सकते हो:

SET FOREIGN_KEY_CHECKS = 0;

TRUNCATE table1;
TRUNCATE table2;

SET FOREIGN_KEY_CHECKS = 1;

इन कथनों के साथ, आप अपनी तालिकाओं में पंक्तियों को देने का जोखिम उठाते हैं जो FOREIGN KEYबाधाओं का पालन नहीं करते हैं ।


30
क्या हमें SET FOREIGN_KEY_CHECKS = 1 सेट करना है; फिर बाद में?
vinc3m1

77
नहीं, तुम नहीं। कनेक्शन के दौरान सेटिंग केवल मान्य है। जैसे ही आप डिस्कनेक्ट करते हैं, अगला कनेक्शन 1 पर वापस आ जाएगा।
पेलेमिस्टर

7
यह संदर्भित तालिका में 'ON DELETE' घटना पर लागू नहीं होता है, इसलिए यह पूर्ण उत्तर नहीं है।
ओमर सबिक

5
यदि PHPMYADMIN में उपयोग किया जाता है, तो यह केवल तभी काम करता है जब आप एक ही SQL विंडो में (सभी द्वारा अलग किए गए ;) लेनदेन का उपयोग करते हैं । ऐसा इसलिए है क्योंकि प्रत्येक ताजा वेब एसक्यूएल कॉल FOREIGN_KEY_CHECKS1.
सेबलफोस्टे

1
अनाथ विदेशी कुंजियों को खोजने का एक बहुत अच्छा तरीका यहाँ है (डेटा अखंडता को पुनर्स्थापित करें) यदि आप रुचि रखते हैं तो http://stackoverflow.com/a/12085689/997776
SandorRacz

173

मैं बस इसके साथ करूँगा:

DELETE FROM mytest.instance;
ALTER TABLE mytest.instance AUTO_INCREMENT = 1;

5
होशियार। जब भी आप सभी रिकॉर्ड हटाना चाहते हैं, तो आप ऑटो वेतन वृद्धि को रीसेट कर सकते हैं।
winkbrace

6
यह स्पष्ट रूप से इसे करने का सबसे अच्छा तरीका है। बाधाओं को खोने का कोई जोखिम नहीं, बस सादा हटाएं। यह ध्यान देने योग्य है कि DELETEतुलना में धीमा प्रदर्शन करता है TRUNCATE। लेकिन चूंकि यह क्रिया आमतौर पर केवल शायद ही कभी की जाती है, इससे कोई फर्क नहीं पड़ता।
फिल्प २

यह अच्छा है यदि आप यह सब करना चाहते हैं, लेकिन DELETEआप बहुत क्रूर हो सकते हैं यदि आपके पास बहुत अधिक पंक्तियाँ हैं - क्योंकि यह लॉग को हिट करता है, जबकि TRUNCATEबस डेटा को बाहर निकालता है। वास्तव में उपयोग के मामले पर निर्भर करता है।
जेफ़

1
जब मैं डिलीट स्टेटमेंट का उपयोग कर रहा हूं, तो यह त्रुटि 1175 की रिपोर्ट करता है: आप सुरक्षित अपडेट मोड का उपयोग कर रहे हैं, बस SET SQL_SAFE_UPDD = 0 जोड़ें; फिर यह ठीक है
tyan

इस समाधान का उपयोग करते समय, यह रिपोर्ट को error 1175: You are using safe update mode,...हटाता है DELETE FROM mydb.mytable where id != 0जो इसे सही बनाता है।
शीहे जांग जूल

17

तुम कर सकते हो

DELETE FROM `mytable` WHERE `id` > 0

1
मैंने इसे दफनाने की कोशिश की, निम्नलिखित त्रुटि दिखाई दी: त्रुटि कोड: 1142. DELETE कमांड ने तालिका 'mytable' के लिए उपयोगकर्ता 'रूट' @ 'लोकलहोस्ट' से इनकार किया
AAEM

या सिर्फ DELETE FROMmytable
Miloslav Milo Janoušek

यह ऑटो वेतन वृद्धि को रीसेट नहीं करेगा।
vivek_23

13

Mysql प्रलेखन के अनुसार , TRUNCATE का उपयोग विदेशी कुंजी संबंधों के साथ तालिकाओं पर नहीं किया जा सकता है। कोई पूर्ण वैकल्पिक AFAIK नहीं है।

कन्ट्रोलिंटर को छोड़ना अभी भी ON DELETE और ON UPDATE को लागू नहीं करता है। एकमात्र उपाय जो मैं सोच सकता हूं, वह है:

  • सभी पंक्तियों को हटाएं, विदेशी कुंजियों को छोड़ें, अलग करें, कुंजी को फिर से बनाएं
  • सभी पंक्तियों को हटा दें, ऑटो पुनर्जन्म (यदि उपयोग किया गया है) रीसेट करें

ऐसा लगता है कि MySQL में TRUNCATE अभी तक एक पूर्ण विशेषता नहीं है (यह भी ट्रिगर नहीं करता है)। टिप्पणी देखें


7
MySQL के TRUNCATEअधूरे होने के बारे में आपकी बात पर ध्यान दें - ट्रंकट को ट्रिगर आदि को लागू करने के लिए नहीं माना जाता है। अगर ऐसा किया गया, तो यह उसी तरह होगा DELETE! यह पंक्ति-अज्ञेयवादी है, इसलिए यह पंक्ति-संबंधी संचालन (जैसे ट्रिगर ट्रिगर करना या विदेशी कुंजियों की जांच करना) करने में असमर्थ है। यह Oracle और Sql Server में उसी तरह से काम करता है ।
साइमन M SimonKenzie

8

आसान है अगर आप phpMyAdmin का उपयोग कर रहे हैं।

टैब और रन के Enable foreign key checksतहत बस अनचेक करें विकल्पSQLTRUNCATE <TABLE_NAME>

यहाँ छवि विवरण दर्ज करें


8

हालांकि यह सवाल पूछा गया था लेकिन मुझे इसके बारे में पता नहीं था, लेकिन अब अगर आप phpMyAdmin का उपयोग करते हैं तो आप बस डेटाबेस खोल सकते हैं और उस तालिका का चयन कर सकते हैं जिसे आप कम करना चाहते हैं।

  • नीचे कई विकल्पों के साथ एक ड्रॉप डाउन है। इसे खोलें और Emptyहेडिंग के तहत विकल्प चुनें Delete data or table
  • यह आपको स्वचालित रूप से अगले पृष्ठ पर ले जाता है जहां चेकबॉक्स में एक विकल्प होता है जिसे कहा जाता है Enable foreign key checks। बस इसे अचयनित Yesकरें और बटन दबाएं और चयनित तालिका को छोटा कर दिया जाएगा।

हो सकता है कि यह आंतरिक रूप से सुझाई गई क्वेरी को चलाता हो user447951 के उत्तर , लेकिन यह phpMyAdmin इंटरफ़ेस से उपयोग करना बहुत सुविधाजनक है।


7

MYSQL डेटाबेस पर परीक्षण किया गया

समाधान 1:

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE table1;

समाधान 2:

DELETE FROM table1;
ALTER TABLE table1 AUTO_INCREMENT = 1;
TRUNCATE table1;

यह मेरे लिए काम करता है। मुझे उम्मीद है, यह आपकी भी मदद करेगा। यह सवाल पूछने के लिए धन्यवाद।


6

उत्तर वास्तव में zerkms द्वारा प्रदान किया गया एक है , जैसा कि विकल्प 1 पर कहा गया है :

विकल्प 1 : जो डेटा अखंडता को नुकसान नहीं पहुंचाता है:

  1. अड़चनें दूर करें
  2. TRUNCATE करें
  3. उन पंक्तियों को मैन्युअल रूप से हटा दें जिनके पास अब संदर्भ हैं
  4. अड़चन पैदा करो

मुश्किल हिस्सा बाधाओं को दूर कर रहा है , इसलिए मैं आपको बताना चाहता हूं कि, अगर किसी को यह जानने की जरूरत है कि कैसे करना है:

  1. SHOW CREATE TABLE <Table Name>यह देखने के लिए क्वेरी चलाएं कि आपका FOREIGN KEY का नाम क्या है (नीचे की छवि में लाल फ्रेम):

    यहाँ छवि विवरण दर्ज करें

  2. भागो ALTER TABLE <Table Name> DROP FOREIGN KEY <Foreign Key Name>। इससे विदेशी कुंजी बाधा दूर होगी।

  3. संबंधित सूचकांक (तालिका संरचना पृष्ठ के माध्यम से) को गिराएं, और आप कर रहे हैं।

विदेशी कुंजी बनाने के लिए:

ALTER TABLE <Table Name>
ADD FOREIGN KEY (<Field Name>) REFERENCES <Foreign Table Name>(<Field Name>);

3

बस CASCADE का उपयोग करें

TRUNCATE "products" RESTART IDENTITY CASCADE;

लेकिन कैस्केड डिलीट के लिए तैयार रहें)


3
ओपी ने MySQL को टैग किया। जबकि यह Postgres में मान्य है, यह MySQL में गलत है।
पीटर

1

यदि तालिकाओं के लिए डेटाबेस इंजन अलग है, तो आपको यह त्रुटि मिलेगी इसलिए उन्हें InnoDB में बदल दें

ALTER TABLE my_table ENGINE = InnoDB;

0

पुराने विदेशी कुंजी चेक स्टेट और sql मोड को प्राप्त करना सबसे अच्छा तरीका है, टेबल को ड्रॉप / ड्रॉप करना जैसा कि माईस्क्लल वर्कबेन्च मॉडल को डेटाबेस में सिंक्रोनाइज़ करते समय करता है।

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;`
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

DROP TABLE TABLE_NAME;
TRUNCATE TABLE_NAME;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.