Я использую MySQL 5.7.21 на Amazon RDS.
Я знаю этот вопрос был задан тысяча раз , но я получаю проблема в сценарии, которого я не ожидал, поэтому, пожалуйста, прочитайте, прежде чем понижать или пометить как дубликат.
- Я не восстанавливаю базу данных, просто запускаю одиночные
INSERT
запросы, так что это не вопрос порядка.
- Ссылочная строка существует в таблице; мне и моим коллегам сделали тройную проверку.
- Как и следовало ожидать, отключение проверок FK с помощью
SET foreign_key_checks = 0
заставляет запрос работать.
- Я видел, как это происходит из-за разных кодировок таблиц, но в этом случае оба используют
utf8mb4
. Также для обоих параметров сортировки установлено значение utf8mb4_general_ci
.
- Это происходит в производственной среде, поэтому я хотел бы избежать удаления таблиц и их воссоздания.
Некоторая дополнительная информация:
- Создано ограничение FK ПОСЛЕ исходные таблицы уже заполнены.
Вот соответствующая часть текущего DDL:
CREATE TABLE `VehicleTickets` (
`id` varchar(50) NOT NULL,
`vehiclePlate` char(7) NOT NULL,
`organizationId` varchar(50) NOT NULL,
`createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` timestamp NULL DEFAULT NULL,
`status` varchar(15) NOT NULL DEFAULT 'OPEN',
`description` text NULL DEFAULT NULL,
`ticketInfo` json DEFAULT NULL,
`externalId` varchar(100) GENERATED ALWAYS AS (json_unquote(json_extract(`ticketInfo`,'$.externalId'))) VIRTUAL,
`value` decimal(10,2) GENERATED ALWAYS AS (json_unquote(json_extract(`ticketInfo`,'$.value'))) VIRTUAL,
`issuedAt` timestamp GENERATED ALWAYS AS (json_unquote(json_extract(`ticketInfo`,'$.issuedAt'))) VIRTUAL NOT NULL,
`expiresAt` timestamp GENERATED ALWAYS AS (json_unquote(json_extract(`ticketInfo`,'$.expiresAt'))) VIRTUAL NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `VehicleTickets_externalId_unq_idx` (`externalId`,`organizationId`),
KEY `VehicleTickets_vehiclePlate_idx` (`vehiclePlate`),
KEY `VehicleTickets_organizationId_idx` (`organizationId`),
KEY `VehicleTickets_issuedAt_idx` (`createdAt`),
KEY `VehicleTickets_expiresAt_idx` (`expiresAt`),
CONSTRAINT `VehicleTickets_Organizations_fk`
FOREIGN KEY (`organizationId`) REFERENCES `Organizations` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `Organizations` (
`id` varchar(50) NOT NULL,
`name` varchar(100) NOT NULL,
`taxPayerId` varchar(50) DEFAULT NULL,
`businessName` varchar(100) DEFAULT NULL,
`status` varchar(15) NOT NULL DEFAULT 'TESTING',
`createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`activatedAt` timestamp NULL DEFAULT NULL,
`assetConfiguration` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Когда я бегу:
select * from VehicleTickets where organizationId not in (
select id from Organizations
);
Я получил пустой набор результатов.
Однако, если я выполню запрос, подобный этому:
insert into `VehicleTickets` (
`id`,
`createdAt`,
`organizationId`,
`ticketInfo`,
`vehiclePlate`
)
values (
'... application generated id',
'... current date ',
'cjlchoksi01r8nfks3f51kht8', -- DOES EXIST on Organizations
'{ ... some JSON payload }',
'... vehicle plate'
)
Это приводит к следующей ошибке:
Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполнено
(VehicleTickets
, ОГРАНИЧЕНИЕ VehicleTickets_Organizations_fk
ИНОСТРАННЫЙ КЛЮЧ (organizationId
) ССЫЛКИ Organizations
(id
))
Кроме того, это дает мне:
"errno": 1452,
"sqlState": "23000",
Я прочитал несколько веток по этой проблеме, но не смог найти похожий случай.