Я настраиваю базу данных с помощью phpMyAdmin. У меня есть две таблицы (foo и bar), индексируются по их первичным ключам. Я пытаюсь создать между ними реляционную таблицу (foo_bar), используя их первичные ключи в качестве внешних ключей.
Я создал эти таблицы как MyISAM, но с тех пор изменил все три на InnoDB, потому что я читал, что MyISAM не поддерживает внешние ключи. Все поля id - это INT(11).
Когда я выбираю таблицу foo_bar, щелкаю ссылку «Просмотр отношений» и пытаюсь установить столбцы FK как database.foo.id и database.bar.id, рядом с каждым столбцом написано "Индекс не определен!".
Что мне не хватает?
Для простоты я хочу продолжать использовать phpMyAdmin. В настоящее время я использую XAMPP, что достаточно просто, чтобы я мог сосредоточиться на PHP / CSS / Javascript, и он поставляется с phpMyAdmin.
Кроме того, хотя я еще не смог настроить явные внешние ключи, у меня есть реляционная таблица, и я могу выполнять такие соединения:
SELECT *
FROM foo
INNER JOIN foo_bar
ON foo.id = foo_bar.foo_id
INNER JOIN bar
ON foo_bar.bar_id = bar.id;
Мне просто неудобно, что FK явно не определены в базе данных.






InnoDB позволяет вам добавить новое ограничение внешнего ключа к таблице с помощью ALTER TABLE:
ALTER TABLE tbl_name
ADD [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
С другой стороны, если MyISAM имеет преимущества перед InnoDB в вашем контексте, зачем вам вообще создавать ограничения внешнего ключа. Вы можете справиться с этим на уровне модели вашего приложения. Просто убедитесь, что столбцы, которые вы хотите использовать в качестве внешних ключей, проиндексированы!
@ Натан: Вот что я говорю в своем посте. Вы можете справиться и с этим на уровне модели. Вы можете реализовать каскад удаления из модели.
Вы почти всегда добавляете ссылочную целостность к таблицам базы данных. База данных должна защищать себя от неправильного программирования приложений. Не полагайтесь только на свое приложение для поддержания целостности данных. Конечно, из каждого правила всегда есть исключения, но я не нашел ни одного для этого.
Если вы хотите использовать phpMyAdmin для настройки отношений, вам нужно сделать 2 вещи. Прежде всего, вы должны определить индекс для столбца внешнего ключа в ссылающейся таблице (в вашем случае foo_bar.foo_id). Затем перейдите в представление отношения (в ссылающейся таблице) и выберите указанный столбец (в вашем случае foo.id) и действия при обновлении и удалении.
Я думаю, что внешние ключи полезны, если у вас есть несколько таблиц, связанных друг с другом, в частности, ваши сценарии удаления станут очень короткими, если вы правильно установите параметры ссылки.
Обновлено: убедитесь, что в обеих таблицах выбран движок InnoDB.
Совет: просмотр отношений - это небольшая ссылка под вашей таблицей, мне было трудно ее найти в первую очередь
Если эта ссылка там не отображается, в этом случае: убедитесь, что ваша таблица имеет тип InnoDB (на вкладке «Операции» в phpMyAdmin), чтобы этого не произошло.
@ muttley91 Моя таблица - InnoDB. Я перепроверил. Ссылка по-прежнему не отображается.
@afilina В новой версии phpMyAdmin он отображается вверху внутри вкладки «Структура», сразу под строкой вкладки, которая показывает «Обзор», «Структура» и т. д.
phpMyAdmin позволяет вам определять внешние ключи, используя их представление «отношения». Но поскольку MySQL поддерживает только внешние ограничения для таблиц INNO DB, первым делом нужно убедиться, что используемые вами таблицы относятся к этому типу.
Чтобы настроить внешний ключ таким образом, чтобы столбец PID в таблице с именем CHILD ссылался на столбец идентификатора в таблице с именем PARENT, вы можете сделать следующее:
Выполнив экспорт таблицы CHILD, вы должны увидеть, что для столбца PID было создано ограничение внешнего ключа.
Ого, очень важно знать. Эта страница была не первым, что я нашел, когда искал помощи по добавлению внешнего ключа, я бы хотел, чтобы об этом упоминали чаще.
Не забывайте, что два столбца должны иметь один и тот же тип данных.
например, если один столбец имеет тип INT, а другой - тип tinyint, вы получите следующую ошибку:
Ошибка создания внешнего ключа в [столбец PID] (проверьте типы данных)
Это резюме статьи в Википедии. Он определяет различные типы отношений, которые вы можете установить в PHPmyadmin. Я помещаю его здесь, потому что он имеет отношение к комментарию @Nathan о настройке параметров внешних ключей для "при обновлении / удалении", но слишком велик для комментария - надеюсь, это поможет.
КАСКАД
Всякий раз, когда строки в главной (ссылочной) таблице удаляются (соответственно обновляются), соответствующие строки дочерней (ссылающейся) таблицы с соответствующим столбцом внешнего ключа также удаляются (соответственно обновляются). Это называется каскадным удалением (соответственно, обновление [2]).
ОГРАНИЧИВАТЬ
Значение не может быть обновлено или удалено, если в таблице внешнего ключа существует строка, которая ссылается на значение в указанной таблице. Точно так же строку нельзя удалить, пока на нее есть ссылка из таблицы внешнего ключа.
БЕЗДЕЙСТВИЕ
ОТСУТСТВИЕ ДЕЙСТВИЙ и ОГРАНИЧЕНИЕ очень похожи. Основное различие между NO ACTION и RESTRICT состоит в том, что при NO ACTION проверка ссылочной целостности выполняется после попытки изменить таблицу. RESTRICT выполняет проверку перед попыткой выполнения оператора UPDATE или DELETE. Оба ссылочных действия действуют одинаково, если проверка ссылочной целостности не удалась: оператор UPDATE или DELETE приведет к ошибке.
УСТАНОВИТЬ NULL
Значения внешнего ключа в ссылающейся строке устанавливаются в NULL, когда указанная строка обновляется или удаляется. Это возможно только в том случае, если соответствующие столбцы в ссылающейся таблице допускают значение NULL. Из-за семантики NULL ссылочная строка с NULL в столбцах внешнего ключа не требует ссылочной строки.
УСТАНОВИТЬ ПО УМОЛЧАНИЮ
Подобно SET NULL, значения внешнего ключа в ссылающейся строке устанавливаются на значение столбца по умолчанию, когда указанная строка обновляется или удаляется.
А еще лучше перейти непосредственно к исходной документации MySQL: dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.ht мл
Для тех, кто плохо знаком с базой данных .... и им нужно ИЗМЕНИТЬ существующую таблицу. Многие вещи кажутся довольно простыми, но всегда есть что-то ... между A и B.
Прежде всего, обратите внимание на это.
Перейдите на вкладку SQL (я использую phpMyAdmin, должен быть похож на другие) и выполните эту команду:
ALTER TABLE child_table_name
ADD FOREIGN KEY (P_ID)
REFERENCES parent_table_name (P_ID)
Щелкните дочернюю таблицу, затем структуру и, наконец, реляционное представление. Завершите планирование своей БД на этом. До этого был хороший ответ о каскаде, ограничении и т. д. Конечно, это можно было сделать с помощью команд ...
Внешний ключ означает, что непервичный атрибут таблицы ссылается на главный атрибут другой * в phpMyAdmin * сначала установите столбец, в котором вы хотите установить внешний ключ в качестве индекса
затем нажмите ОБЗОР СВЯЗИ
там вы можете найти параметры для установки внешнего ключа
В phpmyadmin вы можете назначить внешний ключ просто через его графический интерфейс. Щелкните по таблице и перейдите на вкладку «Структура». найдите Relation View только под таблицей (показанной на изображении ниже).
Вы можете назначить ключ ковки из списка рядом с первичным ключом (см. Изображение ниже). и сохранить
соответствующий SQL-запрос автоматически сгенерирован и выполнен.
Шаг 1:
Вам нужно добавить строку:
по умолчанию-хранилище-движок = InnoDB
в разделе [mysqld] вашего конфигурационного файла mysql (my.cnf или my.ini в зависимости от вашей ОС) и перезапустите службу mysqld.

Шаг 2: Теперь, когда вы создадите таблицу, вы увидите, что тип таблицы: InnoDB
Шаг 3: Создайте как родительскую, так и дочернюю таблицу. Теперь откройте дочернюю таблицу и выберите столбец U, чтобы иметь внешний ключ: Выберите ключ индекса из метки действия, как показано ниже.
Шаг 4: Теперь откройте представление отношений в той же дочерней таблице снизу рядом с представлением печати, как показано ниже.
Шаг 5:
Выберите столбец U, чтобы иметь внешний ключ как Выберите родительский столбец из раскрывающегося списка.
dbName.TableName.ColumnName
Выберите соответствующие значения для ON DELETE и ON UPDATE.

Из официальной документации MySQL на https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html:
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan.
Это старая ветка, но ответьте, потому что, если это кому-то полезно.
Шаг 1. Ваш Db Storage Engine установлен на InnoDB
Шаг 2. Создать основную таблицу
здесь customer - первичная таблица, а customer_id - первичный ключ
Шаг 3. создать таблицу внешнего ключа и дать индекс
здесь у нас есть customer_addresses в качестве связанной таблицы и хранятся адреса клиентов, поэтому здесь связь customer_id с таблицей customer
мы можем выбрать индекс напрямую при создании таблицы, как показано ниже
Если вы забыли указать индекс при создании таблицы, тогда вы можете указать индекс из вкладки состав таблицы, как показано ниже.
Шаг 4. После добавления индекса в поле перейдите на вкладку структуры и щелкните Просмотр отношений, как показано на рисунке ниже.
Шаг 5. Теперь выберите ON DELETE и ON UPDATE, что вы хотите сделать, выберите столбец из текущей таблицы, выберите DB (SAME DB), выберите таблицу отношений и первичный ключ из этой таблицы, как показано на рисунке ниже и Сохранить это
Теперь проверьте, успешно ли установлено отношение, перейдите к списку данных сторонней таблицы и щелкните значение внешнего ключа, вы перенаправите на запись основной таблицы, после чего связь будет успешно установлена.
В более новых версиях phpMyAdmin больше нет параметра «Просмотр отношений», и в этом случае вам придется выполнить оператор, чтобы добиться того же. Например
ALTER TABLE employees
ADD CONSTRAINT fk_companyid FOREIGN KEY (companyid)
REFERENCES companies (id)
ON DELETE CASCADE;
В этом примере, если строка из компаний удаляется, все сотрудники с этим идентификатором компании также удаляются.
Убедитесь, что вы выбрали свой механизм хранения mysql как Innodb, а не MYISAM, поскольку механизм хранения Innodb поддерживает внешние ключи в Mysql.
Шаги по созданию внешних ключей в phpmyadmin:
INDEX для столбца, который вы хотите использовать в качестве внешнего ключа.ОБНОВЛЕНИЕ КАСКАДА указывает, что столбец будет обновлен при обновлении указанного столбца,
Строки, указанные в УДАЛИТЬ КАСКАД, будут удалены при удалении указанных строк.
В качестве альтернативы вы также можете запустить sql-запрос для того же
ALTER TABLE table_name
ADD CONSTRAINT fk_foreign_key_name
FOREIGN KEY (foreign_key_name)
REFERENCES target_table(target_key_name);
Ограничения внешнего ключа экономят мне много усилий и избавляют от потенциальных ошибок. Например, скажем, я собираюсь удалить пользователя из своей системы. Я мог бы написать код, определяющий каждое место в базе данных, где существуют данные об этом пользователе, и сказать ему, чтобы он удалил их. Но я должен постоянно поддерживать эту функцию удаления в актуальном состоянии. С другой стороны, если все связанные с пользователем данные имеют FK для идентификатора пользователя и настроены на каскадное удаление при удалении, весь мой код должен сказать «удалить этого пользователя», и база данных позаботится об удалении всего, что имеет ссылка FK на этого пользователя. Гораздо чище в обслуживании.