#mysql #sql #foreign-keys
#mysql #sql #внешние ключи
Вопрос:
ЗАПРОС СХЕМЫ
-- GRAPH INFO TABLE--------------------------------------------------------------
CREATE TABLE GRAPH
(
graph_id CHAR(32) NOT NULL PRIMARY KEY,
name VARCHAR(1024) NOT NULL
);
INSERT INTO GRAPH set graph_id = MD5('graph1'),
name = 'graph1';
INSERT INTO GRAPH set graph_id = MD5('graph2'),
name = 'graph2';
INSERT INTO GRAPH set graph_id = MD5('graph3'),
name = 'graph3';
-- FIELD INFO TABLE--------------------------------------------------------------
CREATE TABLE FIELD_TEST
(
field_id CHAR(50) NOT NULL PRIMARY KEY,
name VARCHAR(500) NOT NULL
);
INSERT INTO FIELD_TEST set field_id = MD5('field1'),
name = 'field1';
INSERT INTO FIELD_TEST set field_id = MD5('field2'),
name = 'field2';
INSERT INTO FIELD_TEST set field_id = MD5('field3'),
name = 'field3';
-- GRAPH FIELD RELATION TABLE-----------------------------------------------------
CREATE TABLE GRAPH_FIELD_INFO_TEST
(
field_id CHAR(32) NOT NULL,
graph_id CHAR(32) NOT NULL,
PRIMARY KEY (graph_id, field_id),
CONSTRAINT GRAPH_FIELD_INFO_TEST_FIELD_field_id_fk
FOREIGN KEY (field_id) REFERENCES FIELD_TEST (field_id)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT GRAPH_FIELD_INFO_TEST_GRAPH_STORAGE_graph_id_fk
FOREIGN KEY (graph_id) REFERENCES GRAPH (graph_id)
ON UPDATE CASCADE ON DELETE CASCADE
);
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field1'),
graph_id = MD5('graph1');
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field2'),
graph_id = MD5('graph2');
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field3'),
graph_id = MD5('graph3');
ЗАПРОС НА ОБНОВЛЕНИЕ
UPDATE FIELD_TEST
SET name = 'new field1',
field_id = MD5('new field1')
WHERE field_id = MD5('field1');
ОШИБКА
Query Error: Error: ER_ROW_IS_REFERENCED_2: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`GRAPH_FIELD_INFO_TEST`, CONSTRAINT `GRAPH_FIELD_INFO_TEST_FIELD_field_id_fk` FOREIGN KEY (`field_id`) REFERENCES `FIELD_TEST` (`field_id`) ON DELETE CASCADE ON UPDATE CASCADE)
Если я изменю идентификатор FIELD_TEST,
Чтобы изменить идентификатор GRAPH_FIELD_INFO_TEST, ссылающийся на идентификатор FIELD_TEST,
Я установил его как каскад в GRAPH_FIELD_INFO_TEST.
Однако это не удается из-за следующей ошибки.
Если я изменю идентификатор GRAPH, он будет работать нормально,
но это не работает должным образом, только если изменен идентификатор FIELD_TEST .
Могу ли я узнать причину ошибки?
Ответ №1:
field_id
В вашей FIELD_TEST
таблице это a CHAR(50)
, но в вашей GRAPH_FIELD_INFO_TEST
таблице это a CHAR(32)
.
CHAR
это тип фиксированной длины, поэтому при обновлении field_id
в FIELD_TEST
таблице система пытается также обновить ссылочный столбец с помощью a CHAR(50)
, который, конечно, терпит неудачу (хотя фактическое значение составляет всего 32 символа). Таким образом, ошибка. Измените field_id
столбец, чтобы он имел одинаковую длину во всех таблицах… Как отмечено в вашей db-скрипке, это работает для GRAPH...
отношений, потому что поля во всех таблицах имеют одинаковую длину.
Да, это работает, когда вы вставляете данные, потому 'foobar' = 'foobar'
что даже когда один из них поступает из CHAR(50)
столбца, а другой — из CHAR(32)
столбца. Поэтому, когда вы вставляете в свою дочернюю таблицу, он может найти соответствующий ключ в родительской таблице. Но он не может выполнить каскадное обновление, когда родительский ключ длиннее дочернего.
Комментарии:
1. Я не могу поверить, что не вижу этого. Большое спасибо!