Сбой ограничения внешнего ключа, но указанная строка существует - PullRequest
0 голосов
/ 28 августа 2018

Я использую 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",

Я прочитал несколько веток по этой проблеме, но не смог найти похожий случай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...