конфликт первичных и внешних ключей

эта вставка не работает в моей базе данных -

insert into tig_pairs (pkey, pval, uid) select 'schema-version', '4.0', uid from tig_users where (sha1_user_id = sha1(lower('db-properties')));
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`tigasedb`.`tig_pairs`, CONSTRAINT `tig_pairs_constr_2` FOREIGN KEY (`nid`) REFERENCES `tig_nodes` (`nid`))

Где определения таблиц:

create table if not exists tig_pairs (
   nid int unsigned,
   uid int unsigned NOT NULL,

   pkey varchar(255) NOT NULL,    
   pval mediumtext,

   PRIMARY KEY (nid, pkey),      --        ***
             key pkey (pkey),
         key uid (uid),
         key nid (nid),
         constraint tig_pairs_constr_1 foreign key (uid) references tig_users (uid),
         constraint tig_pairs_constr_2 foreign key (nid) references tig_nodes (nid)
)
ENGINE=InnoDB default character set utf8 ROW_FORMAT=DYNAMIC;

а также

create table if not exists tig_nodes (
   nid int unsigned NOT NULL auto_increment,
   parent_nid int unsigned,
   uid int unsigned NOT NULL,

   node varchar(255) NOT NULL,

   primary key (nid), 
   unique key tnode (parent_nid, uid, node),
   key node (node),
         key uid (uid),
         key parent_nid (parent_nid),
         constraint tig_nodes_constr foreign key (uid) references tig_users (uid)
)
ENGINE=InnoDB default character set utf8 ROW_FORMAT=DYNAMIC;

Строка PRIMARY KEY (nid, pkey), -- ***пропущена, тогда мой запрос проходит нормально. Есть ли конфликт между этим первичным ключом и тревожным ограничением внешнего ключа? Как я могу этого избежать? Первичный ключ должен оставаться там :)

Спасибо!

EDIT: избавился от ошибки, изменив определение tig_pairs в одной строке:

nid int unsigned NOT NULL auto_increment,

person kellogs    schedule 15.06.2012    source источник


Ответы (1)


У вас есть внешнее ограничение на таблицу tig_pairs, ссылающееся на таблицу tig_nodes. Однако вы не вставляете никаких данных в это поле nid. Поле, на которое указывает ссылка, tig_nodes.nid, не допускает значений NULL. Из-за этих двух ограничений вы не можете ВСТАВИТЬ null в поле nid поля tig_pairs.

См. также этот вопрос: Внешний ключ MySQL для разрешения NULL?

Изменить: также значения первичного ключа никогда не могут быть NULL; поэтому, пока nid включено в этот первичный ключ, вы не можете сделать его NULL.

person Yhn    schedule 15.06.2012
comment
хм... в точку. Теперь, не могли бы вы подсказать мне, как обойти это? Эта строка *** является лишней (т. е. ее там не было, как все продумал первоначальный программист), и она должна оставаться там. если PK нельзя сделать нулевым, то, я думаю, есть много запросов и логики сервера, которые необходимо изменить [gulp]. Любые ярлыки? - person kellogs; 15.06.2012
comment
Я точно не знаю, какова цель таблиц; но без изменения их структуры. Возможно, вы сможете поместить какое-то значение по умолчанию в таблицу tig_nodes и использовать его идентификатор в качестве значения по умолчанию для nid в tig_pairs? - person Yhn; 18.06.2012
comment
Я сделал настройку, как показано в разделе EDIT, и теперь все работает нормально (я думаю: D) - person kellogs; 22.06.2012