質問

MySQLを使用しており、他の多くのテーブルで外部キーとして使用されるインデックスを持つテーブルがあります。インデックスのデータ型を(符号付きから符号なし整数に)変更したいのですが、これを行う最良の方法は何ですか?

インデックスフィールドのデータ型を変更しようとしましたが、他のテーブルの外部キーとして使用されているため失敗します。外部キーの1つでデータ型を変更しようとしましたが、インデックスのデータ型と一致しないため失敗しました。

すべての外部キー制約を手動で削除し、データ型を変更して制約を追加し直すことができると思いますが、このインデックスを外部キーとして使用するテーブルがたくさんあるため、これは大変な作業になります。変更中に外部キー制約を一時的にオフにする方法はありますか?また、インデックスを外部キーとして参照しているすべてのフィールドのリストを取得する方法はありますか?

更新: 外部キーチェックをオフにした後、1つの外部キーを変更しようとしましたが、チェックをオフにしないようです:

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 コマンドは許可しません制約。

他のヒント

これは、このスレッドへの私の小さな貢献です。インスピレーションとソリューションの大部分を提供してくれたDaniel 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と@changeを設定することにより、クエリを生成できます。 @table_nameは、主キーを持つテーブルのテーブル名(その列を外部キーとして使用するテーブルを検索する)で、そのタイプを@changeに変更する必要があります。

そのようにいくつかのテーブルを変更しなければならなかったので、それは魅力のように機能しました。 @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ステートメント(挿入、更新、削除)の制約のみを無効にし、DDLステートメント(変更テーブル、ドロップテーブルなど)を無効にしないように見えます... )。

データベースを停止してからテーブルをテキストファイルにダンプして、ファイル内の列定義を手動で変更し、テーブルをインポートして戻すことができる場合

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top