Mysql SET FOREIGN_KEY_CHECKS=0

WMix

герр M:)ller
Партнер клуба
я всегда думал что после включения FOREIGN_KEY_CHECKS база проверяет консистентность

разве нет?

Код:
CREATE TABLE IF NOT EXISTS `aaa` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(15) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `aab` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `aaa_id` int(11) NOT NULL,
  `name` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `aaa_id` (`aaa_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

ALTER TABLE `aab`
  ADD CONSTRAINT `aab_ibfk_1` FOREIGN KEY (`aaa_id`) REFERENCES `aaa` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Код:
INSERT INTO  `test`.`aab` (`id` ,`aaa_id` ,`name`)
VALUES (null,  '1',  'aaa');

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`aab`, CONSTRAINT `aab_ibfk_1` FOREIGN KEY (`aaa_id`) REFERENCES `aaa` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
Код:
SET FOREIGN_KEY_CHECKS=0;
INSERT INTO  `test`.`aab` (`id` ,`aaa_id` ,`name`)
VALUES (null,  '1',  'aaa');
SET FOREIGN_KEY_CHECKS=1;

select * from aab;
+----+--------+------+
| id | aaa_id | name |
+----+--------+------+
|  2 |      1 |    0 |
+----+--------+------+
1 row in set (0.00 sec)

mysql> select * from aaa;
Empty set (0.00 sec)
 

MiksIr

miksir@home:~$
=) А что база должна сделать, если она неконсистентна? ;) Упасть? ;)
 

WMix

герр M:)ller
Партнер клуба
удалить, стоит же
ON DELETE CASCADE

ну на край откатится)) или сказать на команду
SET FOREIGN_KEY_CHECKS=1;
ERROR 1452 (23000): Cannot add or update a child row...
наивен, да?
 

Redjik

Джедай-мастер
ну какбе сам нагадил, сам за собой и прибираешь =)
ну на край откатится)) или сказать на команду
SET FOREIGN_KEY_CHECKS=1;
ERROR 1452 (23000): Cannot add or update a child row...
эм, команада работает на подключение, то есть на другом параллельном подключении будет уже стоять SET FOREIGN_KEY_CHECKS=1; (если в настройках не было указано иного)
ну то есть, это больше настройка текущей сессии, нежели глобальное состояние базы
 

WMix

герр M:)ller
Партнер клуба
нашел чтото похожее на решение
http://stackoverflow.com/questions/2250775/force-innodb-to-recheck-foreign-keys-on-a-table-tables

Код:
mysql> CALL ANALYZE_INVALID_FOREIGN_KEYS('test','aa%','N');Query OK, 0 rows affected, 1 warning (0.02 sec)

mysql> select TABLE_NAME, COLUMN_NAME, INVALID_KEY_COUNT FROM INVALID_FOREIGN_KEYS;
+------------+-------------+-------------------+
| TABLE_NAME | COLUMN_NAME | INVALID_KEY_COUNT |
+------------+-------------+-------------------+
| aab        | aaa_id      |                1 |
+------------+-------------+-------------------+
1 row in set (0.00 sec)
 

Redjik

Джедай-мастер
хах, а я так запросы составлял, чинил
может и автопочинка есть?
 

WMix

герр M:)ller
Партнер клуба
чую дальше придется рекурсивно вызывать (до тех пор пока... )), но можно проще сделать, все обернуть в трансакцию, и если набор строк > 1 то откатываться... по крайней маре для меня это сойдет
 

WMix

герр M:)ller
Партнер клуба
MiksIr, задача другая, взял охапку новых данных, залил, без какой либо логики (только перечисленные таблички и поля). а тут скриптик подправил ( добавил табличек, да забыл про одну ), и хорошо, что заметил, что фигня получилась. нужен простой механизм проверки на дурака
 

MiksIr

miksir@home:~$
Не отключай проверку. Или нормальную субд возьми ;)) А отключить проверку "что бы быстрее", а потом все-равно гонять проверку ключей - это как-то странно ;)
 

WMix

герр M:)ller
Партнер клуба
MiksIr, тогда последовательность сгрузки данных нужна (минимальная логика), плюс ко всему двухсторонний ключик бывает, вообще не получится.
какая БД стоит у клиента я не решаю ((, пофиг на прогонку проверки, по крайней мере пока )) будет тормозить в будущем подумаю о логике
 
Сверху