Mysql
 sql >> база данни >  >> RDS >> Mysql

INSERT IGNORE INTO &външни ключове на MySQL

[НОВ ОТГОВОР]

Благодаря на @NeverEndingQueue, че повдигна това. Изглежда MySQL най-накрая е отстранил този проблем. Не съм сигурен в коя версия за първи път беше отстранен този проблем, но в момента тествах със следната версия и проблемът вече не е там:

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                        |
+-------------------------+------------------------------+

За да бъде ясно:

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

За да разберете по-добре значението на тази последна заявка и защо тя показва, че проблемът е отстранен, моля, продължете със стария отговор по-долу.

[СТАР ОТГОВОР]

Моето решение е заобикаляне на проблема и действителното решение винаги ще бъде отстраняване на проблема в самия MySQL.

Следните стъпки решиха проблема ми:

а. Помислете за наличието на следните таблици и данни:

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 |
+----+

б. Сега трябва да изтрием някои от редовете, за да демонстрираме проблема:

mysql>
DELETE FROM parent WHERE id IN (3, 5);

в. ПРОБЛЕМ: Проблемът възниква, когато се опитате да вмъкнете следните дъщерни редове:

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)

Въпреки че IGNORE се използва ключова дума, но MySQL отменя заявената операция, тъй като генерираната грешка не се превръща в предупреждение (както би трябвало). Сега, когато проблемът е очевиден, нека видим как можем да изпълним последното вмъкване в оператор, без да се сблъскаме с грешка.

г. РЕШЕНИЕ: Ще увия вмъкването в оператор с някои други константни оператори, които не зависят нито от вмъкнатите записи, нито от техния брой.

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;

Знам, че това не е оптимално, но докато MySQL не е отстранил проблема, това е най-доброто, което знам. Още повече, че всички оператори могат да бъдат изпълнени в една заявка, ако използвате mysqli библиотека в PHP.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Съхранение на шведски знаци в базата данни на mysql

  2. Получаване на процент от MySql с група по условие и прецизност

  3. php pdo получава само една стойност от mysql; стойност, равна на променлива

  4. Пример за JDBC изявление – пакетно вмъкване, актуализиране, изтриване

  5. mysqldump - Експортирайте структура само без автоматично инкремент