Нужна помощь со сверхъестественной, воспроизводимой ОШИБКОЙ MySQL 1452 (23000) Ограничение внешнего ключа

#mysql #hibernate #macos #foreign-key-relationship

#mysql #переход в спящий режим #macos #foreign-key-relationship

Вопрос:

MySQL select version() — 5.5.9 в Mac OS / X 10.6

Вопрос

Когда я выполняю приведенный ниже sql-скрипт, я сталкиваюсь с очень запутанной ошибкой ограничения внешнего ключа. Кажется, что он не должен выдавать эту ошибку. Более того, я знаю, что другие пытались выполнить шаги, но не смогли повторить (см.: http://forums.mysql.com/read.php?10 ,415350,415350#msg-415350)

Кто-нибудь может определить, что мы делаем неправильно?

Для воспроизведения:

  1. создайте database constraint_test;
  2. создайте файл constraint_test.sql и вставьте приведенный ниже sql.
  3. из строки cmd выполните «mysql constraint_test < constraint_test.sql» (или в моем sql выполните «исходный код tmp / constraint_test.sql»

Ожидаемый результат: строка сохранена в таблицах client, insurated и beneficiary.

Фактический результат: Как вы увидите, ошибка ограничения внешнего ключа, которую мы постоянно получаем, похожа на:

«ОШИБКА 1452 (23000) в строке 55: не удается добавить или обновить дочернюю строку: сбой ограничения внешнего ключа ( constraint_test . beneficiary , ССЫЛКИ НА FK41BADEC55CE3480 ВНЕШНИЙ КЛЮЧ ( insured_id ) ОГРАНИЧЕНИЯ Insured ( insured_id ))»

Тем не менее, в родительской таблице insured определенно есть insured_id.

Пожалуйста, помогите, если можете!

содержимое constraint_test.sql:

 create table Beneficiary ( 
beneficiary_id bigint not null, 
district varchar(255), 
serviceUnit varchar(255), 
insuredNo integer, 
beneficiaryIndex integer, 
relationship varchar(255), 
percentage double precision, 
fullName varchar(255), 
lastUpdatedDate datetime, 
insured_id bigint, 
contractNo varchar(255), 
primary key (beneficiary_id) 
); 

create table Client ( 
client_id bigint not null, 
firstName varchar(255), 
lastName varchar(255), 
email varchar(255), 
initial varchar(255), 
birthDate datetime, 
district varchar(255), 
serviceUnit varchar(255), 
genderType varchar(255), 
externalId varchar(255), 
externalTempId varchar(255), 
taxationProvince varchar(255), 
children varchar(255), 
manufacturerClientNumber varchar(255), 
primary key (client_id) 
); 

create table Insured ( 
insured_id bigint not null, 
client_id bigint not null, 
insuredNo integer, 
primary key (insured_id) 
); 

alter table Beneficiary 
add index FK41BADEC55CE3480 (insured_id), 
add constraint FK41BADEC55CE3480 
foreign key (insured_id) 
references Insured (insured_id); 

alter table Insured 
add index FKD7E770CAC207FE14 (client_id), 
add constraint FKD7E770CAC207FE14 
foreign key (client_id) 
references Client (client_id); 

insert into Client (client_id) values (1); 
insert into Insured (insured_id, client_id ) values (1,1); 
insert into Beneficiary (beneficiary_id, insured_id) values (1,1);
  

Комментарии:

1. вывод состояния show engine innodb?

2. хорошо, по крайней мере, здесь достигнут некоторый прогресс. даже после добавления «not null» к типу данных Beneficiary.insurated мы смогли воспроизвести ошибку. Однако наш вывод show engine innodb содержит следующее в разделе «последние ошибки внешнего ключа»: «Но родительская таблица constraint_test . Insured или его файл .ibd в настоящее время не существует!» Застрахованная таблица определенно существует.

3. Большое вам спасибо. Я боролся с этой точной проблемой большую часть сегодняшнего дня, прежде чем наткнулся на эту ошибку. Если вы используете Hibernate, вы можете устранить эту проблему, используя класс ImprovedNamingStrategy для именования таблиц, а не по умолчанию.

Ответ №1:

Ваши типы данных не совсем совпадают:
Beneficiary.insured_id является bigint , в то время как Insured.insured_id bigint not null

Innodb очень-очень щепетилен в этом вопросе, убедитесь, что определения ваших столбцов FKs абсолютно одинаковы в обеих таблицах, включая возможность обнуления.

Комментарии:

1. был рад попробовать ваш ответ, потому что это казалось таким очевидным. к сожалению, не повезло, даже когда типы данных точно совпадали. есть другие предложения?

2. Похоже, это может быть связано: bugs.mysql.com/bug.php?id=18800 — вы могли бы попробовать изменить набор символов по умолчанию с UTF8 на latin1, чтобы узнать, является ли это вашей проблемой.

3. спасибо, что указали правильное направление @ggiroux!! Latin1, к сожалению, не помогло. Тем не менее, я переименовал все таблицы в нижний регистр, и это действительно изменило ситуацию. Быстрый поиск показывает, что, возможно, мне следует установить lower_case_table_names = 1, поскольку я использую InnoDB. В Mac OS / X по умолчанию равно 2 (и я забыл упомянуть, что я использую новое окно, которое может быть причиной того, что оно не работает локально). Как вы думаете, это имеет смысл? Спасибо еще раз за вашу помощь, ggiroux!

4. Вот ссылка на человека, у которого я нашел информацию: dev.mysql.com/doc/refman/5.0/en /…

5. о, здорово, похоже, вы справились с этим!