外键约束失败,但存在被引用的行

时间:2018-08-28 19:35:07

标签: mysql foreign-keys

我正在Amazon RDS上运行MySQL 5.7.21。

我知道this question has been asked a thousand times,但是我在意料之外的情况下遇到了问题,请阅读在降低投票权或将其标记为重复项之前。

  • 我不还原数据库,仅运行单个INSERT查询,所以不是顺序问题。
  • 被引用的行确实存在于表中;我和我的同事对它进行了三重检查。
  • 正如人们所期望的那样,使用SET foreign_key_checks = 0禁用FK检查确实可以使查询工作。
  • 由于不同的表字符集,我已经看到了这种情况,但是在这种情况下,两者都使用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)参考Organizationsid))

另外,它给了我

"errno": 1452,
"sqlState": "23000",

我已经阅读了有关此问题的多个主题,但是找不到类似的情况。

0 个答案:

没有答案