[JAWABAN BARU]
Terima kasih kepada @NeverEndingQueue karena telah mengemukakan hal ini. Tampaknya MySQL akhirnya memperbaiki masalah ini. Saya tidak yakin di versi mana masalah ini pertama kali diperbaiki, tetapi saat ini saya menguji dengan versi berikut dan masalahnya tidak ada lagi:
mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+------------------------------+
| Variable_name | Value |
+-------------------------+------------------------------+
| innodb_version | 5.7.22 |
| protocol_version | 10 |
| slave_type_conversions | |
| tls_version | TLSv1,TLSv1.1 |
| version | 5.7.22 |
| version_comment | MySQL Community Server (GPL) |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+-------------------------+------------------------------+
Untuk lebih jelasnya:
mysql> INSERT IGNORE INTO child -> VALUES -> (NULL, 1) -> , (NULL, 2) -> , (NULL, 3) -> , (NULL, 4) -> , (NULL, 5) -> , (NULL, 6); Query OK, 4 rows affected, 2 warnings (0.03 sec) Records: 6 Duplicates: 2 Warnings: 2
Untuk lebih memahami arti dari kueri terakhir ini dan mengapa ini menunjukkan bahwa masalah telah diperbaiki, lanjutkan dengan jawaban lama di bawah.
[JAWABAN LAMA]
Solusi saya adalah mengatasi masalah tersebut dan solusi sebenarnya akan selalu memperbaiki masalah di dalam MySQL itu sendiri.
Langkah-langkah berikut memecahkan masalah saya:
a. Pertimbangkan untuk memiliki tabel dan data berikut:
mysql>
CREATE TABLE parent (id INT AUTO_INCREMENT NOT NULL
, PRIMARY KEY (id)
) ENGINE=INNODB;
mysql>
CREATE TABLE child (id INT AUTO_INCREMENT
, parent_id INT
, INDEX par_ind (parent_id)
, PRIMARY KEY (id)
, FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=INNODB;
mysql>
INSERT INTO parent
VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL);
mysql>
SELECT * FROM parent;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+----+
b. Sekarang kita perlu menghapus beberapa baris untuk menunjukkan masalahnya:
mysql>
DELETE FROM parent WHERE id IN (3, 5);
c. MASALAH: Masalah muncul ketika Anda mencoba memasukkan baris anak berikut:
mysql>
INSERT IGNORE INTO child
VALUES
(NULL, 1)
, (NULL, 2)
, (NULL, 3)
, (NULL, 4)
, (NULL, 5)
, (NULL, 6);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint f
ails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERE
NCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
mysql>
SELECT * FROM child;
Empty set (0.00 sec)
Meskipun IGNORE
kata kunci digunakan, tetapi MySQL membatalkan operasi yang diminta karena kesalahan yang dihasilkan tidak berubah menjadi peringatan (sebagaimana seharusnya). Sekarang masalahnya sudah jelas, mari kita lihat bagaimana kita bisa menjalankan penyisipan terakhir ke dalam pernyataan tanpa menghadapi kesalahan apa pun.
d. SOLUSI: Saya akan membungkus sisipan ke dalam pernyataan dengan beberapa pernyataan konstan lainnya yang tidak bergantung pada catatan yang dimasukkan, maupun pada nomornya.
mysql>
SET FOREIGN_KEY_CHECKS = 0;
mysql>
INSERT INTO child
VALUES
(NULL, 1)
, (NULL, 2)
, (NULL, 3)
, (NULL, 4)
, (NULL, 5)
, (NULL, 6);
mysql>
DELETE FROM child WHERE parent_id NOT IN (SELECT id FROM parent);
mysql>
SET FOREIGN_KEY_CHECKS = 1;
Saya tahu ini tidak optimal tetapi selama MySQL belum memperbaiki masalahnya, ini yang terbaik yang saya tahu. Terutama karena semua pernyataan dapat dieksekusi dalam satu permintaan jika Anda menggunakan perpustakaan mysqli di PHP.