Як я бачу всі зовнішні ключі до таблиці чи стовпця?


Відповіді:


764

Для таблиці:

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 у пункті, де.


26
це завжди дає мені порожній набір, тоді як запит, запропонований Node нижче, працює нормально
Гострий

7
@Acute: Ви впевнені, що запитуєте про правильну таблицю? Якщо запит Node працює, то ви, ймовірно, запитуєте про інший напрямок (тобто клавіші від mytable, а не клавіші TO mytable.) Очікуючи, що ви написали '<table>' з назвою таблиці та без '<' і '>' ?
Вінко Врсалович

3
Схоже, я неправильно зрозумів ваш запит, тому що я запитував ключі, посилаючись на <table> :) (так, я написав ім'я таблиці замість "<table>" XD)
Гострий

4
Якщо ви не впевнені, що назва вашої таблиці унікальне, ви, ймовірно, захочете також обмежити свій запит певною базою даних. Змініть пункт де на це:where REFERENCED_TABLE_SCHEMA = 'mydatabase' and REFERENCED_TABLE_NAME = 'mytable'
user12345

Це не працює у випадку некористувача, навіть якщо користувач має всі дозволи на базу даних
Deepak Ram

275

EDIT: Як зазначено в коментарях, це не є правильною відповіддю на питання ОП, але корисно знати цю команду. Це питання з’явилося в Google для того, що я шукав, і подумав, що я залишу цю відповідь для інших.

SHOW CREATE TABLE `<yourtable>`;

Я знайшов цю відповідь тут: MySQL: показати обмеження в команді таблиць

Мені знадобився цей шлях, тому що я хотів побачити, як функціонує ФК, а не просто бачити, чи існує він чи ні.


37
Це показує всі обмеження <yourtable>, а не всі обмеження, на які вказує <yourtable>.
Бармар

18
Як говорить @Barmar, це абсолютно неправильно; він буде показувати зовнішні ключі , що відносяться до зазначеної таблиці, але не буде показувати зовнішні ключі , що вказують До столу, що і задає питання для. Не маю уявлення, як це отримало 50 результатів; Напевно, люди опинилися тут, коли насправді вони шукали відповіді на протилежне питання, так чи інакше, знайшли свою відповідь тут і не потурбувались прочитати оригінальне запитання (чи навіть його назву) перед тим, як звернутись із заявою.
Марк Амері

2
@MarkAmery: це перший результат роботи display foreign keys mysqlв google, можливо, тому;)
Jigar

1
це фактично показує всі існуючі обмеження, phpmyadmin покаже вам лише те, що вказує на вашу таблицю. здається досить гарним, щоб уникнути дублікатів із засобом ORM
william.eyidi

3
Це те, що я шукав, тому дякую, що розмістив його, хоча він не відповів на питання ОП. Ніколи не зашкодить знати, як шукати в обох напрямках відносин!
Чарльз Вуд

75

Якщо ви використовуєте InnoDB та визначені FK, ви можете запитати базу даних data_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';

15
насправді це вказує на неправильний напрямок. цей запит показує всі зовнішні ключі, що вказують на "mytable", а не всі зовнішні ключі, що вказують на "mytable".
Крістіан Оудар

1
У моєму випадку це працює краще. Мені потрібно скинути будь-яке обмеження зовнішнього ключа (і лише ті) з таблиці, щоб мати можливість змінити двигун InnoDB MyISAM або NDB.
Коханій Руберт

Ви можете отримати сторонні ключі в обох напрямках із таблиці REFERENTIAL_CONSTRAINTS - я додав ще одну відповідь із запитом.
ChrisV

45

Публікація за старою відповіддю, щоб додати корисну інформацію.

У мене була подібна проблема, але я також хотів побачити CONSTRAINT_TYPE разом із НАЗВАННЯМИ таблиці та стовпці REFERENCED. Тому,

  1. Щоб побачити всі 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>';
  2. Щоб побачити всі таблиці та 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();
  3. Щоб побачити всі ФК у вашій базі даних:

    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;

8
Ці запити запускаються набагато швидше (від 2 секунд до 0,0015 секунд), якщо ви вказали k.TABLE_SCHEMA = DATABASE () і k.TABLE_NAME = '<table>' у пункті WHERE, як це зафіксовано тут dev.mysql.com/doc/refman /5.5/uk/…
guigouz

2
чудова відповідь. Чи є у вас рішення для MyISAM?
Beau Bouchard

2
MyISAM, на жаль, не підтримує сторонні ключі. dev.mysql.com/doc/refman/5.7/uk/myisam-storage-engine.html
Енді

24

Як альтернатива відповіді 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, якщо бажаєте.


2
Я особисто віддаю перевагу цій відповіді, оскільки використання таблиці REFERENTIAL_CONSTRAINTS надає вам правило оновлення та каскаду. +1
Люк Мадханга

Роблячи відкриття про таблицю, ви не повинні забувати, що зовнішні ключі можна встановити ДІЯЛЬНО!
Енкодер

11

Це рішення не тільки відображатиме всі відносини, але і ім'я обмеження, яке потрібно в деяких випадках (наприклад, втратити контракт):

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';

Аналогічно для конкретного імені стовпця додайте

і table_name = 'ім'я_стол

в кінці запиту.

Натхненний цій посаді тут


7

Використання REFERENCED_TABLE_NAME не завжди працює і може бути значенням NULL. Натомість може працювати наступний запит:

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '<table>';

4

Швидкий спосіб перерахувати ваші 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.


3

Рішення, яке я придумав, є крихким; вона покладається на конвенцію про іменування джанго для іноземних ключів.

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

2

Щоб знайти всі таблиці, що містять певний зовнішній ключ, такий якemployee_id

SELECT DISTINCT TABLE_NAME 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME IN ('employee_id')
AND TABLE_SCHEMA='table_name';

2

Якщо ви також хочете отримати назву стовпця із зовнішнім ключем:

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"
Андреас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.