親テーブル ( profileと呼ばれる) と、子と見なすことができる 2 つのテーブル ( valuesおよびurl ) の 3 つのテーブルを取得しました。これはただのテストなので、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
次の 3 つのクエリをトランザクションとして実行しています (周囲の 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が欠落していることを示しています。その場合、2 番目のクエリが機能するのはなぜですか。そのテーブルのURLは、テーブルの値などのテーブルプロファイルに対して非常に同じ外部キー関係を取得しているためです。
編集:一意にできない値の FK に関して、データベース設計に大きな欠陥があります。明日考えよう。:)