MySQL正在尝试删除所有不受外键约束的行
好的,这(可能)是一个非常简单的问题,但我恐怕我几乎不知道MySQL,所以请容忍我。我只是试图删除一个表中的每一行,而这不受另一个表中外键的约束—一个特定的表,这里只涉及两个表。create语句看起来有点像:MySQL正在尝试删除所有不受外键约束的行,mysql,foreign-keys,sql-delete,Mysql,Foreign Keys,Sql Delete,好的,这(可能)是一个非常简单的问题,但我恐怕我几乎不知道MySQL,所以请容忍我。我只是试图删除一个表中的每一行,而这不受另一个表中外键的约束—一个特定的表,这里只涉及两个表。create语句看起来有点像: CREATE TABLE `testschema`.`job` ( `Job_Id` int(10) unsigned NOT NULL AUTO_INCREMENT, `Comment` varchar(255) DEFAULT NULL, PRIMARY KEY (`Jo
CREATE TABLE `testschema`.`job` (
`Job_Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Comment` varchar(255) DEFAULT NULL,
PRIMARY KEY (`Job_Id`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `ermieimporttest`.`jobassignment` (
`JobAssignment_Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`JobId` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`JobAssignment_Id`),
KEY `FK_jobassignment_1` (`JobId`),
CONSTRAINT `FK_jobassignment_1` FOREIGN KEY (`JobId`) REFERENCES `job` (`Job_Id`),
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
任何my SQL语句都是:
DELETE FROM job USING job INNER JOIN jobAssignment WHERE job.Job_Id != jobAssignment.JobId;
我认为这是正确的-它应该从job表中删除不存在将该job作为外键的job assignment的每个job。但是,当我尝试执行它时,它失败了,并出现以下错误:
无法删除或更新父行:
外键约束失败
(testdatabase
jobsignment
,
约束FK\u作业分配\u 1
外键(JobId
)引用job
(作业Id
))
那么我做错了什么蠢事
编辑:和往常一样,我在这里发布后几秒钟就找到了答案。我使用了(完全不同的)查询:
出于好奇,这是更好的方法吗?我最初的想法可行吗?如果是这样的话,那又有什么问题呢 您可能需要一个子查询,不确定它在mySQL中是否有效,但至少类似于:
DELETE FROM job USING job
LEFT JOIN jobAssignment ON(job.Job_Id = jobAssignment.JobId)
WHERE jobAssignment.JobId IS NULL;
DELETE FROM job
WHERE job.Job_Id NOT IN (
SELECT JobId FROM jobAssignment
)
Naktibalda认为子查询可能效率低下;如果是这样,你可以试试
DELETE FROM job
WHERE NOT EXISTS (SELECT *
FROM jobassignment
WHERE job.Job_Id = jobassignment.Job_Id);
在过去,我曾经有过不好的经历;不存在这样的问题。在您的语句中,对作业表中的每一行执行依赖于语句的子查询,因此效率非常低。您发布的
DELETE
语句似乎有点混乱,但为了回答您的好奇:对于作业中的每一行
,您的JOIN
正在为jobsignment
中id不等于作业id的每一行生成一个行列表。要更清楚地看到这一点,请将DELETE
语句转换为SELECT
语句。类似于以下内容:SELECT*FROM job internal job job job\u Id!=jobsignment.JobId谢谢你,迈克。我现在明白你的意思了——我的语句是两个表的叉积,减去Job_Id==JobId的行。当然,尝试删除它会失败,因为它包含受约束的作业。干杯。我选择这个作为答案,因为这是我关于如何使用连接进行删除的问题的答案。虽然我确实使用了Jaymz的答案,但我发现在这里使用它是不恰当的,所以当我给他我的梯度时,这是我最后一个问题的更接近的答案。谢谢,Naktibalda,谢谢。恐怕我选择Naktibalda的答案作为“正确”答案,因为它最接近我编辑的问题,但这个解决方案是我实际找到并首先使用的!谢谢Jaymz。谢谢你的建议-子查询方法确实在6500行中运行了不到1秒(至少,我认为-最多它不是一个明显的停顿),但我知道,当涉及到数据库时,可以很容易地得到更多的行!
DELETE FROM job
WHERE NOT EXISTS (SELECT *
FROM jobassignment
WHERE job.Job_Id = jobassignment.Job_Id);