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






Если вы используете InnoDB и определили FK, вы можете запросить базу данных information_schema, например:
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE information_schema.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND information_schema.TABLE_CONSTRAINTS.TABLE_SCHEMA = 'myschema'
AND information_schema.TABLE_CONSTRAINTS.TABLE_NAME = 'mytable';
В моем случае это работает лучше. Мне нужно удалить все ограничения внешнего ключа (и только те) из таблицы, чтобы иметь возможность изменять движок InnoDB MyISAM или NDB.
Вы можете получить внешние ключи в обоих направлениях из таблицы REFERENTIAL_CONSTRAINTS - я добавил еще один ответ с запросом.
Решение, которое я придумал, хрупкое; он основан на соглашении об именах внешних ключей django.
USE information_schema;
tee mysql_output
SELECT * FROM TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_SCHEMA = 'database_name';
notee
Затем в оболочке
grep 'refs_tablename_id' mysql_output
Для стола:
SELECT
TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
REFERENCED_TABLE_SCHEMA = '<database>' AND
REFERENCED_TABLE_NAME = '<table>';
Для столбца:
SELECT
TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
REFERENCED_TABLE_SCHEMA = '<database>' AND
REFERENCED_TABLE_NAME = '<table>' AND
REFERENCED_COLUMN_NAME = '<column>';
По сути, мы изменили REFERENCED_TABLE_NAME на REFERENCED_COLUMN_NAME в предложении where.
это всегда дает мне пустой набор, в то время как запрос, предложенный Node ниже, отлично работает
@Acute: Вы уверены, что спрашиваете о правильной таблице? Если запрос узла работает, то вы, вероятно, спрашиваете о другом направлении (например, о ключах ОТ mytable, а не о ключах TO mytable). Ожидается, что вы написали '<table>' с именем таблицы и без '<' и '>' ?
Похоже, я неправильно понял ваш запрос, потому что я запрашивал ключи, ссылающиеся на FROM <table> :) (да, я написал имя таблицы вместо "<table>" XD)
Если вы не уверены, что имя вашей таблицы уникально, вы, вероятно, захотите также ограничить свой запрос определенной базой данных. Измените предложение where на это: where REFERENCED_TABLE_SCHEMA = 'mydatabase' and REFERENCED_TABLE_NAME = 'mytable'
Это не будет работать в случае пользователя без полномочий root, даже если у пользователя есть все права доступа к базе данных.
@DeepakRam Это отлично работает для меня с привилегированным пользователем, который не является пользователем root.
Согласен, я получаю здесь только пустой набор! Ответ Энди сработал для меня лучше всего.
Зачем это нужно так много? Почему бы не упростить процесс выбора строк?
Это сработало идеально для меня. У меня есть большинство привилегий, но не root. Ты спасатель.
Я добавил TABLE_SCHEMA в список столбцов (SELECT TABLE_SCHEMA, TABLE_NAME, …), что полезно в случае наличия нескольких баз данных, в которых есть таблицы, относящиеся к нашей таблице / столбцу, представляющему интерес.
Публикация старого ответа, чтобы добавить полезную информацию.
У меня была аналогичная проблема, но я также хотел увидеть CONSTRAINT_TYPE вместе с REFERENCED именами таблиц и столбцов. Так,
Чтобы увидеть все FK в вашей таблице:
USE '<yourschema>';
SELECT i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME
FROM information_schema.TABLE_CONSTRAINTS i
LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND i.TABLE_SCHEMA = DATABASE()
AND i.TABLE_NAME = '<yourtable>';
Чтобы увидеть все таблицы и FK в вашей схеме:
USE '<yourschema>';
SELECT i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME
FROM information_schema.TABLE_CONSTRAINTS i
LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND i.TABLE_SCHEMA = DATABASE();
Чтобы увидеть все FK в вашей базе данных:
SELECT i.TABLE_SCHEMA, i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME
FROM information_schema.TABLE_CONSTRAINTS i
LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY';
Помнить!
Это использует механизм хранения InnoDB. Если вы не можете отобразить какие-либо внешние ключи после их добавления, это, вероятно, связано с тем, что ваши таблицы используют MyISAM.
Проверить:
SELECT * TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = '<yourschema>';
Чтобы исправить это, используйте это:
ALTER TABLE `<yourtable>` ENGINE=InnoDB;
Эти запросы выполняются намного быстрее (от 2 секунд до 0,0015 секунды), если вы укажете k.TABLE_SCHEMA = DATABASE () и k.TABLE_NAME = '<table>' в предложении WHERE, как описано здесь dev.mysql.com/doc/refman/5.5/en/…
отличный ответ. У вас есть решения для MyISAM?
К сожалению, MyISAM не поддерживает внешние ключи. dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html
Обновлено: Как указано в комментариях, это не правильный ответ на вопрос OP, но полезно знать эту команду. Этот вопрос появился в Google для того, что я искал, и решил, что оставлю этот ответ, чтобы другие нашли его.
SHOW CREATE TABLE `<yourtable>`;
Я нашел здесь ответ: MySQL: команда показать ограничения для таблиц
Мне нужен этот способ, потому что я хотел увидеть, как функционирует ФК, а не просто посмотреть, существует он или нет.
Это показывает все ограничения в <yourtable>, а не все ограничения, которые указывают на <yourtable>.
Как говорит @Barmar, это совершенно неправильно; он покажет внешние ключи, принадлежащие указанной таблице, но не покажет внешние ключи, указывающие на К таблицу, что и требуется в вопросе. Понятия не имею, как это получило 50 голосов; Я предполагаю, что люди оказались здесь, когда действительно искали ответ на противоположный вопрос, все равно нашли здесь ответ и не удосужились прочитать исходный вопрос (или даже его заголовок) перед голосованием.
@MarkAmery: это первый результат display foreign keys mysql в гугле, может быть поэтому;)
thisi на самом деле показывает все существующие ограничения, phpmyadmin покажет вам только то, что указывает на вашу таблицу. кажется достаточно хорошим, чтобы избежать дублирования с помощью инструмента ORM
Это то, что я искал, поэтому спасибо за публикацию, даже если он не ответил на вопрос OP. Никогда не помешает уметь смотреть в обе стороны в отношениях!
Я люблю такие ответы, сэр.
Быстрый способ перечислить ваши FK (ссылки на внешние ключи) с помощью
KEY_COLUMN_USAGE view:
SELECT CONCAT( table_name, '.',
column_name, ' -> ',
referenced_table_name, '.',
referenced_column_name ) AS list_of_fks
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_SCHEMA = (your schema name here)
AND REFERENCED_TABLE_NAME is not null
ORDER BY TABLE_NAME, COLUMN_NAME;
Этот запрос действительно предполагает, что ограничения и все ссылочные и ссылочные таблицы находятся в одной схеме.
Добавьте свой комментарий.
Источник: официальное руководство по mysql.
Я не думаю, что сноска «Этот запрос действительно предполагает, что ограничения и все ссылочные и ссылочные таблицы находятся в одной и той же схеме». обязательно верно? Я только что использовал представление KEY_COLUMN_USAGE (очень полезно), чтобы увидеть ограничения перекрестной схемы
Это решение будет отображать не только все отношения, но и имя ограничения, которое требуется в некоторых случаях (например, ограничение отбрасывания):
select
concat(table_name, '.', column_name) as 'foreign key',
concat(referenced_table_name, '.', referenced_column_name) as 'references',
constraint_name as 'constraint name'
from
information_schema.key_column_usage
where
referenced_table_name is not null;
Если вы хотите проверить таблицы в конкретной базе данных, в конце запроса добавьте имя схемы:
select
concat(table_name, '.', column_name) as 'foreign key',
concat(referenced_table_name, '.', referenced_column_name) as 'references',
constraint_name as 'constraint name'
from
information_schema.key_column_usage
where
referenced_table_name is not null
and table_schema = 'database_name';
Аналогичным образом, для определенного имени столбца добавьте
and table_name = 'table_name
в конце запроса.
На основе этого поста здесь
В качестве альтернативы ответу Node, если вы используете InnoDB и определили FK, вы можете запросить базу данных information_schema, например:
SELECT CONSTRAINT_NAME, TABLE_NAME, REFERENCED_TABLE_NAME
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = '<schema>'
AND TABLE_NAME = '<table>'
для внешних ключей из <table>, или
SELECT CONSTRAINT_NAME, TABLE_NAME, REFERENCED_TABLE_NAME
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = '<schema>'
AND REFERENCED_TABLE_NAME = '<table>'
для внешних ключей к <table>
Вы также можете получить UPDATE_RULE и DELETE_RULE, если хотите.
Я лично предпочитаю этот ответ, поскольку использование таблицы REFERENTIAL_CONSTRAINTS дает вам правило обновления и каскадирования. +1
Делая открытие таблицы, вы не должны забывать, что внешние ключи могут быть установлены ОБОИМ способами!
Чтобы найти все таблицы содержащий конкретный внешний ключ, например employee_id
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME IN ('employee_id')
AND TABLE_SCHEMA='table_name';
Использование REFERENCED_TABLE_NAME не всегда работает и может иметь значение NULL. Вместо этого может работать следующий запрос:
select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '<table>';
Если вы также хотите получить имя столбца внешнего ключа:
SELECT i.TABLE_SCHEMA, i.TABLE_NAME,
i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME,
k.COLUMN_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME
FROM information_schema.TABLE_CONSTRAINTS i
LEFT JOIN information_schema.KEY_COLUMN_USAGE k
ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
WHERE i.TABLE_SCHEMA = '<TABLE_NAME>' AND i.CONSTRAINT_TYPE = 'FOREIGN KEY'
ORDER BY i.TABLE_NAME;
Спасибо отличное решение! Мне также нужно было имя столбца, чтобы добавить: 'k.COLUMN_NAME'
Я не хочу добавлять еще один ответ, но мне пришлось просить, брать взаймы и воровать у других, чтобы получить то, что я хочу, а именно полный список всех отношений FK в таблицах в данной схеме, ВКЛЮЧАЯ FK для таблицы в других схемах. Два важных набора записей - это information_schema.KEY_COLUMN_USAGE и information_schema.referential_constraints. Если нужный атрибут отсутствует, просто раскомментируйте KCU., RC., чтобы увидеть, что доступно.
SELECT DISTINCT KCU.TABLE_NAME, KCU.COLUMN_NAME, REFERENCED_TABLE_SCHEMA, KCU.REFERENCED_TABLE_NAME, KCU.REFERENCED_COLUMN_NAME, UPDATE_RULE, DELETE_RULE #, KCU.*, RC.*
FROM information_schema.KEY_COLUMN_USAGE KCU
INNER JOIN information_schema.referential_constraints RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
WHERE TABLE_SCHEMA = (your schema name)
AND KCU.REFERENCED_TABLE_NAME IS NOT NULL
ORDER BY KCU.TABLE_NAME, KCU.COLUMN_NAME;
Ограничения в SQL - это правила, определенные для данных в таблице. Ограничения также ограничивают типы данных, которые входят в таблицу. Если новые данные не соответствуют этим правилам, действие прерывается.
select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE = 'FOREIGN KEY';
Вы можете просмотреть все ограничения с помощью select * from information_schema.table_constraints;
(Это приведет к появлению большого количества табличных данных).
Вы также можете использовать это для MySQL:
show create table tableName;
Пожалуйста, добавьте объяснение долгосрочной ценности и превратите его в качественный ответ, который с большей вероятностью получит одобрение. Ответы должны помочь будущим посетителям что-то узнать и быстро определить, применимы ли элементы вашего решения к их собственным проблемам с кодированием.
на самом деле, это указывает неверное направление. этот запрос показывает все внешние ключи, указывающие ОТ 'mytable', а не все внешние ключи, указывающие НА 'mytable'.