سؤال

أنا باستخدام MySQL و لدي جدول مع مؤشر يستخدم المفتاح الخارجي في العديد من الجداول الأخرى.أريد تغيير نوع بيانات مؤشر (من توقيع غير صحيح) ما هي أفضل طريقة للقيام بذلك ؟

حاولت تغيير نوع بيانات على مؤشر المجال ، ولكن فشل ذلك لأنه يتم استخدام المفتاح الخارجي على الجداول الأخرى.حاولت تغيير نوع البيانات في واحدة من المفاتيح الخارجية ، ولكن هذا فشل لأنه لم يطابق نوع بيانات الفهرس.

أعتقد أنني يمكن أن يدويا إسقاط كافة قيود المفاتيح الخارجية ، تغيير أنواع البيانات و إضافة القيود مرة أخرى ، ولكن هذا من شأنه أن يكون هناك الكثير من العمل لأن لدي الكثير من الجداول باستخدام هذا المؤشر بمثابة المفتاح الخارجي.هل هناك طريقة لإيقاف قيود المفاتيح الخارجية مؤقتا في حين صنع التغيير ؟ أيضا, هل هناك طريقة للحصول على قائمة من كافة الحقول الرجوع مؤشر الخارجية المفتاح ؟

تحديث: حاولت تعديل واحد الأجنبية الرئيسية بعد إيقاف الأجنبية الرئيسية الشيكات ، ولكن لا يبدو أن يكون إيقاف الشيكات:

SET foreign_key_checks = 0;

ALTER TABLE `escolaterrafir`.`t23_aluno` MODIFY COLUMN `a21_saida_id` INTEGER DEFAULT NULL;

هنا الخطأ:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
090506 11:57:34 Error in foreign key constraint of table escolaterrafir/t23_aluno:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match to the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
  CONSTRAINT FK_t23_aluno_8 FOREIGN KEY (a21_saida_id) REFERENCES t21_turma (A21_ID)

تعريف مؤشر الجدول:

DROP TABLE IF EXISTS `escolaterrafir`.`t21_turma`;
CREATE TABLE  `escolaterrafir`.`t21_turma` (
  `A21_ID` int(10) unsigned NOT NULL auto_increment,
  ...
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=latin1;

و الجدول الذي يحتوي على المفاتيح الخارجية التي تشير إلى ذلك:

DROP TABLE IF EXISTS `escolaterrafir`.`t23_aluno`;
CREATE TABLE  `escolaterrafir`.`t23_aluno` (
  ...
  `a21_saida_id` int(10) unsigned default NULL,
  ...
  KEY `Index_7` (`a23_id_pedagogica`),
  ...
  CONSTRAINT `FK_t23_aluno_8` FOREIGN KEY (`a21_saida_id`) REFERENCES `t21_turma` (`A21_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=387 DEFAULT CHARSET=latin1;
هل كانت مفيدة؟

المحلول 2

للإجابة على سؤالي, أنا لا يمكن أن اكتشاف أبسط طريقة للقيام بذلك.لقد انتهت بإسقاط جميع قيود المفاتيح الخارجية ، وتغيير أنواع الحقول ثم إضافة جميع قيود المفاتيح الخارجية مرة أخرى.

كما R.Bemrose لاحظ استخدام SET foreign_key_checks = 0; يساعد فقط عند إضافة أو تغيير البيانات ، ولكن لا تسمح ALTER TABLE الأوامر التي من شأنها كسر قيود المفاتيح الخارجية.

نصائح أخرى

هنا هو بلدي مساهمة صغيرة في هذا الموضوع.بفضل دانيال Schneller للإلهام و إعطائي جزءا كبيرا من الحل!

set group_concat_max_len = 2048;
set @table_name = "YourTableName";
set @change = "bigint unsigned";
select distinct table_name,
       column_name,
       constraint_name,
       referenced_table_name,
       referenced_column_name,
       CONCAT(
           GROUP_CONCAT('ALTER TABLE ',table_name,' DROP FOREIGN KEY ',constraint_name SEPARATOR ';'),
           ';',
           GROUP_CONCAT('ALTER TABLE `',table_name,'` CHANGE `',column_name,'` `',column_name,'` ',@change SEPARATOR ';'),
           ';',
           CONCAT('ALTER TABLE `',@table_name,'` CHANGE `',referenced_column_name,'` `',referenced_column_name,'` ',@change),
           ';',
           GROUP_CONCAT('ALTER TABLE `',table_name,'` ADD CONSTRAINT `',constraint_name,'` FOREIGN KEY(',column_name,') REFERENCES ',referenced_table_name,'(',referenced_column_name,')' SEPARATOR ';')
       ) as query
from   INFORMATION_SCHEMA.key_column_usage
where  referenced_table_name is not null
   and referenced_column_name is not null
   and referenced_table_name = @table_name
group by referenced_table_name

من خلال وضع @table_name و @تغيير يمكنك إنشاء استعلام.@table_name يجب أن يكون الجدول اسم الجدول مع المفتاح الأساسي (سوف ابحث عن الجداول التي تستخدم هذا العمود أجنبية مفتاح) و تغيير نوع @تغيير.

اضطررت إلى تغيير عدد قليل من الجداول مثل ذلك ، بحيث تعمل مثل السحر.أود فقط أن تغيير @table_name ثم تنفيذ الاستعلام.

لمعرفة المزيد عن استخدام قيود المفاتيح الخارجية ، العدد الاستعلام التالي على INFORMATION_SCHEMA قاعدة البيانات:

select distinct table_name, 
       column_name, 
       constraint_name,  
       referenced_table_name, 
       referenced_column_name 
from   key_column_usage 
where  constraint_schema = 'XXX' 
   and referenced_table_name is not null 
   and referenced_column_name is not null;

محل XXX مع اسم المخطط.هذا وسوف تعطيك قائمة الجداول والأعمدة التي تشير إلى أعمدة أخرى مثل المفاتيح الخارجية.

للأسف التغييرات المخطط غير المعاملات ، لذلك أخشى أنك سوف يكون في الواقع مؤقتا تعطيل foreign_key_checks لهذه العملية.أوصي - إن أمكن - إلى منع اتصالات من أي من العملاء خلال هذه المرحلة للحد من مخاطر عرضي القيد الانتهاكات.

أما بالنسبة مفاتيح أنفسهم:سوف تحتاج إلى إسقاط صوغه وكذلك عندما قمت بتغيير الجدول أنواع البيانات.

يمكنك تعطيل مفاتيح خارجية مؤقتا عن طريق كتابة

SET foreign_key_checks = 0;

و إلى إعادة تمكين لهم

SET foreign_key_checks = 1;

أعتقد أن هذا يتطلب امتيازات المسؤول ، لأنه يهدف إلى استيراد البيانات إلى قاعدة البيانات.

تحرير:في رد فعل على تحرير الخاص بك ، يبدو أنه فقط تعطيل القيود عبارات DML (insert, update, delete) ولكن لا جمل DDL (alter table, إسقاط الجدول ، الخ...).

إذا كان يمكنك إيقاف قاعدة البيانات ثم حاول تفريغ الجداول إلى ملف نصي تغيير أعمدة التعريف يدويا في الملف واستيراد الجداول مرة أخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top