我得到了三个表,一个父级(称为配置文件)和两个可以考虑一个子级的表(值和url)。这只是一个测试,所以不要介意缺少 SQL 注入安全性。
CREATE TABLE `profiles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`profile` int(10) unsigned NOT NULL,
`url_hash` varchar(32) NOT NULL,
PRIMARY KEY (`id`,`profile`,`url_hash`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1
CREATE TABLE `urls` (
`id` int(10) unsigned NOT NULL,
`url` text NOT NULL,
`title` text,
PRIMARY KEY (`id`),
CONSTRAINT `urls_ibfk_1` FOREIGN KEY (`id`) REFERENCES `profiles` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `values` (
`id` int(10) unsigned NOT NULL,
`seller` text NOT NULL,
`seller_language` text,
`quality` tinyint(3) unsigned NOT NULL,
`note` text,
`price` int(10) unsigned NOT NULL,
`count` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `values_mtg_ibfk_1` FOREIGN KEY (`id`) REFERENCES `profiles` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
我正在执行以下三个查询作为事务(省略了 autocommit(false)、commit() 和 rollback()):
$db->query('INSERT INTO profiles(id, profile, url_hash)
VALUES (null, ' . $profile . ', "' . md5($url) . '")')
or throwException(...);
$db->query('INSERT INTO urls(id, url, title)
VALUES (' . mysqli_insert_id($db) . ', "' . $url . '", "' . $c->data('title') . '")')
or throwException(...);
$db->query('INSERT INTO values(id, seller, seller_language, quality,
note, price, count)
VALUES (' . mysqli_insert_id($db) . ', "'. $seller .'", "'. $seller_lang .'",
'. $qual .', "'. $notice .'", '. $price .', '. $ount .')')
or throwException(..);
导致
exception 'Exception' with message 'Query failed (table: values):
(1452) Cannot add or update a child row: a foreign key constraint fails
(`crawler`.`values`, CONSTRAINT `values_ibfk_1` FOREIGN KEY (`id`) REFERENCES
`profiles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)'
我只是不明白为什么。它说明缺少父表中的相应id。如果是这种情况,为什么第二个查询会起作用,因为它的表url与表配置文件(如表值)具有完全相同的外键关系?
编辑:我的数据库设计中有一个巨大的缺陷,关于 FK 的值不能是唯一的。明天再考虑。:)