Почему этот запрос SQL работает? - PullRequest
1 голос
/ 14 апреля 2011

Я следую Учебник Фила Гринспуна по SQL.

Фил использует Oracle для обучения, но я использую MySQL.Вот мои запросы:

mysql> CREATE TABLE mailing (
    -> email varchar(100) not null primary key,
    -> name varchar(100)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO mailing (email, name) VALUES ('foo@bar.com', 'FooBar');
Query OK, 1 row affected (0.00 sec)

mysql> CREATE TABLE phone (
    -> email varchar(100) not null references mailing,
    -> phone varchar(20)
    -> );
Query OK, 0 rows affected (0.00 sec)

Как видите, я установил в качестве справки столбец email таблицы phone.

В учебном пособии сказано:

В таблице phone есть ограничение ссылочной целостности («ссылки mailing»), чтобы мы не записывали адреса электронной почты.для людей, чьи имена мы не знаем

Тогда почему этот запрос работает ?:

mysql> INSERT INTO phone (email, phone) VALUES ('new@new.com', '112223');
Query OK, 1 row affected (0.00 sec)

... обратите внимание, что у меня нет new@new.com вmailing стол.

Чего мне не хватает?

Ответы [ 3 ]

5 голосов
/ 14 апреля 2011

Ссылки в MySQL доступны только для движка InnoDB, перепишите ваш CREATE TABLE следующим образом:

 CREATE TABLE phone (
    -> email varchar(100) not null references `mailing` (`email`),
    -> phone varchar(20)
    -> ) ENGINE=InnoDB;

По умолчанию MySQL использует движок MyISAM, который игнорирует оператор «links». Подробнее документация о создании таблиц в MySQL

UPDATE: Ссылка на внешний ключ должна быть размещена вне оператора CREATE TABLE. Спасибо, @jswolf и @ a_horse_with_no_name

CREATE TABLE phone (
-> email varchar(100) not null,
-> phone varchar(20),
-> REFERENCES `mailing` (`email`)
-> ON DELETE NO ACTION
-> ON UPDATE NO ACTION
-> ) ENGINE=InnoDB;

Не тестировал, но, скорее всего, будет работать.

3 голосов
/ 14 апреля 2011

В дополнение к ответу Немодена:

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

1 голос
/ 14 апреля 2011

В качестве ответа Немодена вы должны использовать InnoDB, а не MyISAM.

Отношение FOREIGN KEY можно (и должно быть в MYSQL) добавить следующим образом:

CREATE TABLE phone
( email varchar(100) NOT NULL
, phone varchar(20) DEFAULT NULL

, FOREIGN KEY fk_mailing (email)         --- the "fk_mailing" name is optional
    REFERENCES mailing (email)
) 
  ENGINE=InnoDB 
  DEFAULT CHARSET = utf8 ;               --- or other charset you prefer

Из учебникавы используете:

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

Насколько я могу сказать:

a) MySQL поддерживает различные «механизмы хранения» для таблиц.Это, по-видимому, хорошая вещь.Однако не все механизмы поддерживают ограничения ссылок.

b) Чтобы таблица MySQL поддерживала ограничение «ссылки», она должна иметь тип InnoDB.В моей установке (в SuSE Linux, прямо из стандартного двоичного пакета RPM), это , а не по умолчанию.Таким образом, вы должны либо изменить конфигурацию сервера, чтобы сделать это по умолчанию, либо указать «ENGINE = InnoDB» после закрывающей скобки в определении таблицы.

c) Даже для InnoDB синтаксис, описанный Филом выше, делаетне работает, хотя не отклонено, просто проигнорировано .Согласно руководству, это фактически просто комментарий для разработчика о том, что этот столбец должен ссылаться на другой столбец, даже если ограничение не применяется mysql.

d) Итак,единственный способ заставить этот тип ограничения работать: 1. сделать таблицу InnoDB и 2. использовать формат «FOREIGN KEY (email) REFERENCES mailing_list (email)» в качестве отдельной записи внутри определения таблицы.

[MySQL даже не предупредит!Даже не напоминание о том, что такие ссылочные предложения являются просто «комментариями».Он просто с радостью проигнорирует их и допустит любое старое значение в этом ряду.Тьфу.]

  -- Antonio Ramirez, March 19, 2007
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...