কীভাবে অস্থায়ীভাবে মাইএসকিউএলে কোনও বিদেশী কী বাধা নিষ্ক্রিয় করবেন?


651

মাইএসকিউএলে সাময়িকভাবে সীমাবদ্ধতাগুলি অক্ষম করা কি সম্ভব?

আমার কাছে দুটি জ্যাঙ্গো মডেল রয়েছে, প্রত্যেকটির সাথে অন্যটির বিদেশীকি রয়েছে। কোনও মডেলের উদাহরণ মুছে ফেলা বিদেশী কী বাধার কারণে একটি ত্রুটি দেয়:

cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)
transaction.commit_unless_managed()  #a foreign key constraint fails here

cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)
transaction.commit_unless_managed()

সাময়িকভাবে সীমাবদ্ধতাগুলি অক্ষম করা এবং যাইহোক মুছে ফেলা সম্ভব?


3
হয় আপনি যা করতে চান তা আমি পাই না বা আপনি যা করার চেষ্টা করছেন তা খুব, খুব, খুব কুরুচিপূর্ণ । এমনকি যদি আপনি এটি করতে পারেন, আপনার সম্ভবত করা উচিত নয়।
দারিউজ

3
ড্রপ এবং reapplying একটি এফ কে হয় আপনার ডিবি পরিবর্তন। আপনি সেই প্রতিবন্ধকতাগুলি অস্বীকার করার চেষ্টা করছেন যা সিস্টেমটিকে কিছুটা বোঝার সুযোগ দেয়, কোনও এফকে কোনও অস্থায়ী জিনিস হতে পারে এবং এটি যদি জানত তবে তা আতঙ্কিত হবে no
গ্রান্ট থমাস

1
আপনি যা করার চেষ্টা করছেন তা অদ্ভুত। তবে আপনি কোন ডাটাবেস ব্যবহার করছেন?
andrefsp

4
আপনার সীমাবদ্ধতা অক্ষম করার পরিবর্তে, আপনি কী স্থায়ীভাবে এটিতে পরিবর্তন করেছেন ON DELETE SET NULL? এটি একটি অনুরূপ জিনিস সম্পাদন করবে এবং আপনাকে কী চেকিংটি চালু এবং বন্ধ করতে হবে না।
দিনআরগার্ল

1
@ ডানাগার্ল: এটি আরও ভাল, সত্যই হবে। আমি এটা কিভাবে করবো?
জুলাই

উত্তর:


1466

চেষ্টা করুন DISABLE KEYSবা

SET FOREIGN_KEY_CHECKS=0;

নিশ্চিত করা

SET FOREIGN_KEY_CHECKS=1;

পরে।


14
এটি কি এমন কিছু যা পুরোপুরি মাইএসকিএল-এর জন্য সেট করা হয় বা কেবল সেই অধিবেশন?
টিপু

28
আমি বিশ্বাস করি এটি প্রতি সেশনেই রয়েছে।
অ্যান্ড্রু ক্যাম্পবেল

13
serverfault.com/questions/291100/… , এছাড়াও নোট করুন যে আপনি ইনোডব disable keys
পেসারিয়ার

1
আমি কি কেবল একটি টেবিলের জন্য FOREIGN_KEY_CHECKS অক্ষম করতে পারি?
jDub9

@ পেসারিয়র এটি পড়ে, এটি প্রদর্শিত হয় তবে আপনি কেবল একটি একক অধিবেশনেই পারেন।
ব্রেট

150

বিদেশী কী বাধা বিশ্বব্যাপী বন্ধ করতে, নিম্নলিখিতটি করুন:

SET GLOBAL FOREIGN_KEY_CHECKS=0;

এবং আপনার কাজ শেষ হয়ে গেলে এটি আবার সেট করতে মনে রাখবেন

SET GLOBAL FOREIGN_KEY_CHECKS=1;

সতর্কতা: আপনি যখন একক ব্যবহারকারী মোড রক্ষণাবেক্ষণ করছেন তখন আপনার কেবল এটি করা উচিত। যেহেতু এটি ডেটাতে অসঙ্গতি হতে পারে। উদাহরণস্বরূপ, আপনি যখন কোনও মাইএসকিल्डম্প আউটপুট ব্যবহার করে প্রচুর পরিমাণে ডেটা আপলোড করবেন তখন এটি খুব সহায়ক হবে।


1
এটি আমার জানা দরকার, তাই এটি দুর্দান্ত অনুশীলন নয়, তবে এই ছেলের উত্তরটি আরও বেশি স্কোর করা উচিত ...
ফ্রুটটার

1
এটি 'সেরা উত্তর' চেষ্টা করার পরেও আমার পক্ষে কাজ করে নি। সম্ভবত পার্থক্যের একটি ব্যাখ্যা যুক্ত করা যেতে পারে।
হেক্সনেট

7
@hexnet পার্থক্য হল যে ঠিক হয় SET FOREIGN_KEY_CHECKSমাত্র জন্য মান পরিবর্তন বর্তমান সংযোগ , যখন SET GLOBAL ..মান পরিবর্তন সব সংযোগ ভবিষ্যৎ সংযোগ সহ। আপনি যদি কেবল SET FOREIGN..একটি উইন্ডোতে করেন তবে বিবৃতিটি অন্য একটি উইন্ডোতে প্রয়োগ করার চেষ্টা করুন (ভিন্ন সংযোগের উপরে), মানটি সেখানে পরিবর্তন হয়নি। সাথে GLOBAL, একই ভেরিয়েবলের উভয় সংযোগের জন্য একই মান রয়েছে।
ম্যাটস লিন্ধ

বৃহত্তর ডাম্প (6+ গিগাবাইট) ফিরে খেললে আমার কেবল সেই জিনিসটি সাহায্য করতে পারে <3
সর্বোচ্চ

এটি আমার পক্ষে কাজ করে না। আমি যখন চেষ্টা করি, আমি দেখতে পাচ্ছি:ERROR 1228 (HY000): Variable 'foreign_key_checks' is a SESSION variable and can't be used with SET GLOBAL
মাইক বি

53

আমি সাধারণত যখন আমি কোনও টেবিলটি ছাঁটাই করতে চাই তখন কেবল বিদেশী কী বাধাগুলি অক্ষম করি এবং যেহেতু আমি এই উত্তরে ফিরে আসতে থাকি এটি আমার ভবিষ্যতের জন্য:

SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE table;
SET FOREIGN_KEY_CHECKS=1;

25

আপনার সীমাবদ্ধতা অক্ষম করার পরিবর্তে স্থায়ীভাবে এটিকে সেট মুছে ফেলুন permanent এটি একটি অনুরূপ কাজ সম্পাদন করবে এবং আপনাকে কী চেকিং চালু এবং বন্ধ করতে হবে না। তাই ভালো:

ALTER TABLE tablename1 DROP FOREIGN KEY fk_name1; //get rid of current constraints
ALTER TABLE tablename2 DROP FOREIGN KEY fk_name2;

ALTER TABLE tablename1 
  ADD FOREIGN KEY (table2_id) 
        REFERENCES table2(id)
        ON DELETE SET NULL  //add back constraint

ALTER TABLE tablename2 
  ADD FOREIGN KEY (table1_id) 
        REFERENCES table1(id)
        ON DELETE SET NULL //add back other constraint

এটি পড়ুন ( http://dev.mysql.com/doc/refman/5.5/en/alter-table.html ) এবং এটি ( http://dev.mysql.com/doc/refman/5.5/en ) /create-table-foreign-keys.html )।


7
সাবধানী পরিবর্তনের টেবিলটি দীর্ঘ সময় নিতে FOREIGN_KEY_CHECKSপারে, 0 থেকে সার্ভারকে বিশ্বব্যাপী সেট করা ভাল এবং নোংরা কাজ শেষ হয়ে গেলে এটি আবার রেখে দিতে পারে। এছাড়াও এটি আপনার টেবিলগুলি লেখার জন্য লক হতে পারে।
আকি

রিমোট কলামের ধরণের পরিবর্তন করার সময় কি রেফারেন্সটি ভঙ্গ করবে না? (দেখে মনে হচ্ছে আমার ক্লায়েন্টটি পরিবর্তিত টেম্প টেবিলের মূল টেবিলের নাম পরিবর্তন করে))
সিইস টিমারম্যান

15

বিদেশী কী বাধা বিশ্বব্যাপী বন্ধ করতে:

SET GLOBAL FOREIGN_KEY_CHECKS = 0;

এবং সক্রিয় বিদেশী কী সীমাবদ্ধতার জন্য

SET GLOBAL FOREIGN_KEY_CHECKS = 1;

10

Phpmyadmin সহ একটি খুব সাধারণ সমাধান:

  • আপনার টেবিলে, SQLট্যাবে যান
  • আপনি যে এসকিউএল কমান্ডটি চালাতে চান তা সম্পাদনা করার পরে, পাশে রয়েছে একটি চেক বাক্স GO, যার নাম রয়েছে ' বিদেশী কী চেকগুলি সক্ষম করুন'
  • এই চেক বাক্সটি আনচেক করুন এবং আপনার এসকিউএল চালান । এটি কার্যকর করার পরে স্বয়ংক্রিয়ভাবে পুনরায় চেক করা হবে।

3
ধন্যবাদ! পিএইচপিএমইএডমিনে প্রকৃতপক্ষে সমাধানটি SET FOREIGN_KEY_CHECKS=0; ..... SET FOREIGN_KEY_CHECKS=1;আমার পক্ষে কার্যকর হয়নি কারণ আমি 'বিদেশী কী চেকগুলি সক্ষম করুন' চেকবাক্সটি আনচেক করতে ভুলে গিয়েছি। পিএইচপিএমআইএডমিনে আপনি এই এসইটি কমান্ডগুলি এড়িয়ে যেতে পারেন এবং কেবলমাত্র চেকবাক্সটি আনচেক করতে পারেন।
জানুয়ারী

5

আমার জন্য SET FOREIGN_KEY_CHECKS=0;যথেষ্ট ছিল না। আমি এখনও একটি ছিল com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException

আমি যোগ করতে হবে ALTER TABLE myTable DISABLE KEYS;

তাই:

SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE myTable DISABLE KEYS;
DELETE FROM myTable;
ALTER TABLE myTable ENABLE KEYS;
SET FOREIGN_KEY_CHECKS=1;

এফওয়াইআই, মাইএসকিউএল 5.7 সতর্কতা দেয়, অক্ষম কীগুলি কমান্ড চালানোর সময় ইনোডিবি ইঞ্জিনের এই বিকল্প নেই।
jDub9

এটি কাজ করেছিল, পরিবর্তিত টেবিল ছাড়া এটি আমার
পক্ষেও

3

কী ক্ষেত্রটি যদি অযোগ্য হয় তবে এটি মুছে ফেলার চেষ্টা করার আগে আপনি মানটি নালিতে সেট করতে পারেন:

cursor.execute("UPDATE myapp_item SET myapp_style_id = NULL WHERE n = %s", n)
transaction.commit_unless_managed() 

cursor.execute("UPDATE myapp_style SET myapp_item_id = NULL WHERE n = %s", n)
transaction.commit_unless_managed()

cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)
transaction.commit_unless_managed()

cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)
transaction.commit_unless_managed()

2

পিএইচপিএমআইএডমিনে আপনি একাধিক সারি নির্বাচন করতে পারেন তারপরে মুছুন ক্রিয়াটি ক্লিক করতে পারেন। আপনি মুছা প্রশ্নগুলি তালিকাভুক্ত এমন একটি স্ক্রিন প্রবেশ করবেন, আপনি বৈদেশিক কী চেকটি চেক করতে পারেন এবং এগুলি কার্যকর করতে হ্যাঁতে ক্লিক করুন।

এটি মুছে ফেলার সীমাবদ্ধতা সীমাবদ্ধ থাকলেও এটি আপনাকে সারিগুলি মুছতে সক্ষম করবে।


-2

বিদেশী কী বাধা 0 তে সেট করা ভাল ধারণা নয়, কারণ আপনি যদি এটি করেন তবে আপনার ডাটাবেসটি নিশ্চিত করবে না যে এটি রেফারেন্সিয়াল অখণ্ডতা লঙ্ঘন করছে না। এটি ভুল, বিভ্রান্তিকর, বা অসম্পূর্ণ ডেটা হতে পারে।

আপনি কোনও কারণে বিদেশী কী তৈরি করেন: কারণ শিশু কলামের সমস্ত মান প্যারেন্ট কলামের মান হিসাবে সমান হবে। যদি কোনও বিদেশী কী বাধা না থাকে তবে একটি শিশু সারির একটি মান থাকতে পারে যা প্যারেন্ট সারিতে নেই, যা ভুল তথ্য নিয়ে যেতে পারে।

উদাহরণস্বরূপ, ধরা যাক শিক্ষার্থীদের জন্য লগইন করার জন্য আপনার কাছে একটি ওয়েবসাইট রয়েছে এবং প্রতিটি ছাত্রকে অবশ্যই ব্যবহারকারী হিসাবে অ্যাকাউন্টের জন্য নিবন্ধন করতে হবে। ব্যবহারকারী আইডির জন্য আপনার কাছে একটি টেবিল রয়েছে, প্রাথমিক আইডি হিসাবে ব্যবহারকারী আইডি; এবং ছাত্র অ্যাকাউন্টগুলির জন্য অন্য একটি সারণী, কলাম হিসাবে শিক্ষার্থী আইডি। যেহেতু প্রত্যেক শিক্ষার্থীর অবশ্যই একটি ব্যবহারকারী আইডি থাকতে হবে, তাই ছাত্রদের অ্যাকাউন্ট থেকে শিক্ষার্থী আইডিটি একটি বিদেশী কী তৈরি করা বোধগম্য হবে যা ব্যবহারকারী আইডির টেবিলে প্রাথমিক কী ব্যবহারকারী আইডি উল্লেখ করে। যদি কোনও বিদেশী কী চেক না থাকে তবে একজন শিক্ষার্থীর স্টুডেন্ট আইডি এবং কোনও ইউজার আইডি থাকা শেষ হতে পারে, যার অর্থ একজন শিক্ষার্থী ব্যবহারকারী না হয়ে অ্যাকাউন্ট পাবে, যা ভুল।

এটি বিপুল পরিমাণে ডেটা হয়ে যায় কিনা তা কল্পনা করুন। এজন্য আপনার বিদেশী কী চেক দরকার।

কী কারণে ত্রুটি ঘটছে তা নির্ধারণ করা ভাল। সম্ভবত, আপনি সন্তানের সারিটি মোছা ছাড়াই প্যারেন্ট সারি থেকে মোছার চেষ্টা করছেন। প্যারেন্ট সারি থেকে মোছার আগে সন্তানের সারি থেকে মোছার চেষ্টা করুন।


সত্য, সবসময় একটি বাণিজ্য বন্ধ আছে।
পেসারিয়ার

21
এটিকে চিরকালের জন্য চালানোর জন্য কেউ বলছে না। আপনি সীমাবদ্ধতাগুলি বন্ধ করুন, কিছু পরিমাণে কিছু ডেটা লোড করুন এবং এটিকে আবার ফ্লিপ করুন। কোনও বড় কথা নয়, লোকেরা সারাক্ষণ তা করে।
বাইওয়াক

এটি বাল্ক আমদানির জন্য প্রয়োজনীয়, কমপক্ষে পারফরম্যান্সের জন্য, এটি খুব সাধারণ। এছাড়াও কখনও কখনও আপনার পুনরুদ্ধার করার জন্য কেবলমাত্র ডেটা দরকার হয়, তারপরে আপনি নিজের চেকগুলি তৈরি করতে পারেন।
ফিরস আবদ

3
এটি প্রশ্নের উত্তর নয়।
Koray Tugay

দ্রষ্টব্য, অস্থায়ীভাবে এটি কীভাবে করা যায় তার প্রশ্ন। নির্দিষ্ট রক্ষণাবেক্ষণ এবং ডেটা আমদানি করার সময় এটি প্রয়োজন is অবশ্যই সতর্কতাই হ'ল আপনার আমদানি স্ক্রিপ্টগুলি ডেটা অখণ্ডতার জন্য দায়ী হয়ে যায়। তারপরে, পরে যখন সূচীগুলি এবং সীমাবদ্ধতাগুলি আবার চালু করা হবে, তখন ডিবি কিছু ভেঙে গেছে কিনা তা আপনাকে জানায়।
এমসিস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.