문제

저는 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 외래 키 제약 조건을 위반하는 명령.

다른 팁

이 스레드에 대한 나의 작은 기여는 다음과 같습니다.영감을 주고 솔루션의 큰 부분을 제공한 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