Внешний ключ, не работающий в MySQL: Почему я могу ВСТАВИТЬ значение, это не находится во внешнем столбце?

19
задан stalepretzel 5 February 2012 в 19:25
поделиться

5 ответов

Я нашел следующую статью. У меня нет времени для проверения его, в настоящее время, но это может быть полезно:

http://forums.mysql.com/read.php?22,19755,43805

автор, Edwin Dando, говорит:

обе таблицы должны быть INNODB. Поле внешнего ключа должно иметь индекс на нем. foeign поле ключа и ссылаемое поле должны иметь тот же тип (я только использую целое число), и, после часов боли, они должны быть НЕ ПОДПИСАНЫ.

1
ответ дан 30 November 2019 в 02:04
поделиться

Я предположил бы, что Вашим механизмом устройства хранения данных по умолчанию является MyISAM, который игнорирует ограничения внешнего ключа. Это тихо принимает объявление внешнего ключа, но не хранит ограничение или осуществляет его впоследствии.

Однако это действительно неявно создает индекс на столбцах, которые Вы объявили для внешнего ключа. В MySQL, "KEY" синоним для" INDEX". Это - то, что показывают в ОПИСАТЬ выводе: индекс, но не ограничение.

Вы можете вставить недопустимые значения в таблицу прямо сейчас, потому что нет никакого ограничения. Для получения ограничения, которое осуществляет ссылочную целостность необходимо использовать механизм устройства хранения данных InnoDB:

CREATE TABLE actions (
  A_id int NOT NULL AUTO_INCREMENT,
  ...
  CONSTRAINT fk_Question FOREIGN KEY (Q_id) REFERENCES questions(P_id),
  CONSTRAINT fk_User FOREIGN KEY (U_id) REFERENCES users(P_id)
) ENGINE=InnoDB;

я всегда думал, что это была большая ошибка на части MySQL к тихо , игнорируют ограничительные объявления внешнего ключа. Нет никакой ошибки или предупреждения, что механизм устройства хранения данных не поддерживает их.

то же верно для ограничений CHECK. По тому, как никакой механизм устройства хранения данных, используемый с MySQL, не поддерживает ограничения CHECK, но синтаксический анализатор SQL принимает их без жалобы.

<час>

проблема errno 150 происходит, когда она не может составить таблицу InnoDB, потому что она не могла понять ограничение внешнего ключа. Можно получить еще некоторую информацию с:

SHOW ENGINE INNODB STATUS;

Некоторые требования для внешних ключей InnoDB:

  • таблицей Referenced должен также быть InnoDB.
  • таблица Referenced должна иметь индекс и первичный ключ.
  • типы данных SQL столбца FK и столбца PK, на который ссылаются, должны быть идентичными. Например, INT не соответствует BIGINT или НЕПОДПИСАННОМУ INT.
<час>

можно изменить механизм устройства хранения данных таблицы, которая имеет данные в нем:

ALTER TABLE actions ENGINE=InnoDB;

Это эффективно копирует всю таблицу MyISAM в таблицу InnoDB, затем после того как это успешно выполняется, она отбрасывает таблицу MyISAM и переименовывает новую таблицу InnoDB к названию бывшей таблицы MyISAM. Это называют, "таблица реструктурируют", и это может быть трудоемким, в зависимости от того, сколько данных находится в таблице. Таблица реструктурирует, происходит во время ALTER TABLE, даже в некоторых случаях, где это может казаться ненужным.

<час>

Ре Ваше обновление 2:

мне говорят, что важно осуществить целостность данных с функциональными внешними ключами, но также и что InnoDB не должен использоваться с MySQL.Что Вы порекомендуете?

, Кто сказал Вам это? Это абсолютно ложно. InnoDB имеет лучшую производительность, чем MyISAM (хотя InnoDB нужно больше внимания к настройка конфигурации ), InnoDB поддерживает атомарные изменения, транзакции, внешние ключи, и InnoDB является намного более стойким к повреждению данных в катастрофическом отказе.

, Если Вы не выполняете старую, неподдерживаемую версию MySQL (5.0 или ранее) необходимо использовать InnoDB в качестве Вашего значение по умолчанию выбор механизма устройства хранения данных и использовать MyISAM, только если можно продемонстрировать определенную рабочую нагрузку, которая извлекает выгоду из MyISAM.

53
ответ дан 30 November 2019 в 02:04
поделиться

Как отмечено, Ваша таблица должен быть InnoDB для ограничений FK, которые будут осуществлены.

я только столкнулся, 'Не может составить таблицу' в случае, где я пытаюсь создать ограничение внешнего ключа, где мой локальный столбец является другим типом из внешнего столбца.

0
ответ дан 30 November 2019 в 02:04
поделиться

проблема наиболее вероятна, что вопросы p_id и пользователи p_id не определяются как INT NOT NULL. чтобы внешние ключи работали, определение столбцов и на стороне внешнего ключа должно соответствовать точно, за исключением auto_increment и на значения по умолчанию.

1
ответ дан 30 November 2019 в 02:04
поделиться

Я знаю, что эта ветка была открыта давным-давно, но я отправляю это сообщение для будущих пользователей, которые будут искать ответ. Я была такая же проблема с внешним ключом в mysql. У меня сработало следующее.

Родительская таблица:

CREATE TABLE NameSubject (
  Autonumber INT NOT NULL AUTO_INCREMENT,
  NameorSubject nvarchar(255),
  PRIMARY KEY (Autonumber)
 ) ENGINE=InnoDB;

Дочерняя таблица:

CREATE TABLE Volumes (
  Autonumber INT NOT NULL,
  Volume INT,
  Pages nvarchar(50),
  Reel int,
  Illustrations bit,
  SSMA_TimeStamp timestamp,
  Foreign KEY (Autonumber) references NameSubject(Autonumber)
  ON  update cascade 
)engine=innodb;

«ON update cascade» творит чудеса для меня.

Надеюсь, это сработает и для других. Удачи.

6
ответ дан 30 November 2019 в 02:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: