271

I have tables that I've tried setting PK FK relationships on but I want to verify this. How can I show the PK/FK restraints? I saw this manual page, but it does not show examples and my google search was fruitless also. My database is credentialing1 and my constrained tables are practices and cred_insurances.

engin
  • 27
  • 1
  • 6
Captain Claptrap
  • 3,839
  • 5
  • 25
  • 29

8 Answers8

494

I use

SHOW CREATE TABLE mytable;

This shows you the SQL statement necessary to receate mytable in its current form. You can see all the columns and their types (like DESC) but it also shows you constraint information (and table type, charset, etc.).

Adrian Smith
  • 17,236
  • 11
  • 71
  • 93
  • 10
    i don't think it shows the incoming fk relations? as in for example, `a.col_one references b.col_one` and in `show create table b` will not contain detail about the aforementioned relation. – Vineet Menon Oct 10 '14 at 09:44
  • 4
    I confirmed that this command does not display the foreign key constraint. – Kemin Zhou Jun 06 '16 at 22:34
  • 2
    Beware that MariaDB starting with 10.2 will return awkward results here. https://jira.mariadb.org/browse/MDEV-15377 – stamster Feb 24 '18 at 18:14
  • I believe this wont show constrains further than PK – alilloig Feb 11 '21 at 08:56
  • 2
    This should be the accepted answer!!! It's simple and gives an amazing and detailed output!!! I use mysql **Ver 8.0.23 for Win64** and I get FK information: ```CONSTRAINT `t_incomes_ibfk_3` FOREIGN KEY (`f_production_id`) REFERENCES `t_productions` (`m_id`) ON DELETE CASCADE, CONSTRAINT `t_incomes_ibfk_4` FOREIGN KEY (`f_field_id`) REFERENCES `t_fields` (`m_id`) ON DELETE CASCADE``` – babaliaris Apr 26 '21 at 12:01
141

Simply query the INFORMATION_SCHEMA:

USE INFORMATION_SCHEMA;
SELECT TABLE_NAME,
       COLUMN_NAME,
       CONSTRAINT_NAME,
       REFERENCED_TABLE_NAME,
       REFERENCED_COLUMN_NAME
FROM KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = "<your_database_name>" 
      AND TABLE_NAME = "<your_table_name>" 
      AND REFERENCED_COLUMN_NAME IS NOT NULL;
simhumileco
  • 31,877
  • 16
  • 137
  • 115
Resh32
  • 6,500
  • 3
  • 32
  • 40
  • 18
    This is the best answer because it gives you the result in a format that you can use programmatically. Of course you will need to add a WHERE clause to narrow down the results – Naveed Hasan Jan 27 '14 at 10:30
  • This helped me find a corrupt table that had the column 'id' referencing several foreign keys. No wonder the table got 1452 IntegrityError. – Vicky T Sep 05 '15 at 16:03
  • I love that you prefixed your answer with "Simply." Great answer, though! – leviathanbadger Oct 23 '17 at 23:16
  • That will not display actual constraint rules - e.g. `ON UPDATE CASCADE` – stamster Feb 24 '18 at 18:39
  • 3
    The only disadvantage of the above is, key_column_usage will only show keys that are in use. So for empty tables you won't get any results. – Gerbrand Aug 19 '20 at 12:56
22

The main problem with the validated answer is you'll have to parse the output to get the informations. Here is a query allowing you to get them in a more usable manner :

SELECT cols.TABLE_NAME, cols.COLUMN_NAME, cols.ORDINAL_POSITION,
cols.COLUMN_DEFAULT, cols.IS_NULLABLE, cols.DATA_TYPE,
    cols.CHARACTER_MAXIMUM_LENGTH, cols.CHARACTER_OCTET_LENGTH,
    cols.NUMERIC_PRECISION, cols.NUMERIC_SCALE,
    cols.COLUMN_TYPE, cols.COLUMN_KEY, cols.EXTRA,
    cols.COLUMN_COMMENT, refs.REFERENCED_TABLE_NAME, refs.REFERENCED_COLUMN_NAME,
    cRefs.UPDATE_RULE, cRefs.DELETE_RULE,
    links.TABLE_NAME, links.COLUMN_NAME,
    cLinks.UPDATE_RULE, cLinks.DELETE_RULE
FROM INFORMATION_SCHEMA.`COLUMNS` as cols
LEFT JOIN INFORMATION_SCHEMA.`KEY_COLUMN_USAGE` AS refs
ON refs.TABLE_SCHEMA=cols.TABLE_SCHEMA
    AND refs.REFERENCED_TABLE_SCHEMA=cols.TABLE_SCHEMA
    AND refs.TABLE_NAME=cols.TABLE_NAME
    AND refs.COLUMN_NAME=cols.COLUMN_NAME
LEFT JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS cRefs
ON cRefs.CONSTRAINT_SCHEMA=cols.TABLE_SCHEMA
    AND cRefs.CONSTRAINT_NAME=refs.CONSTRAINT_NAME
LEFT JOIN INFORMATION_SCHEMA.`KEY_COLUMN_USAGE` AS links
ON links.TABLE_SCHEMA=cols.TABLE_SCHEMA
    AND links.REFERENCED_TABLE_SCHEMA=cols.TABLE_SCHEMA
    AND links.REFERENCED_TABLE_NAME=cols.TABLE_NAME
    AND links.REFERENCED_COLUMN_NAME=cols.COLUMN_NAME
LEFT JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS cLinks
ON cLinks.CONSTRAINT_SCHEMA=cols.TABLE_SCHEMA
    AND cLinks.CONSTRAINT_NAME=links.CONSTRAINT_NAME
WHERE cols.TABLE_SCHEMA=DATABASE()
    AND cols.TABLE_NAME="table"
dolmen
  • 8,126
  • 5
  • 40
  • 42
nfroidure
  • 1,531
  • 12
  • 20
21

afaik to make a request to information_schema you need privileges. If you need simple list of keys you can use this command:

SHOW INDEXES IN <tablename>
pleerock
  • 18,322
  • 16
  • 103
  • 128
7

You can use this:

select
    table_name,column_name,referenced_table_name,referenced_column_name
from
    information_schema.key_column_usage
where
    referenced_table_name is not null
    and table_schema = 'my_database' 
    and table_name = 'my_table'

Or for better formatted output use this:

select
    concat(table_name, '.', column_name) as 'foreign key',  
    concat(referenced_table_name, '.', referenced_column_name) as 'references'
from
    information_schema.key_column_usage
where
    referenced_table_name is not null
    and table_schema = 'my_database' 
    and table_name = 'my_table'
Abhishek Gupta
  • 6,465
  • 10
  • 50
  • 82
  • ORA-00942: table or view does not exist 00942. 00000 - "table or view does not exist" *Cause: *Action: Error at Line: 29 Column: 5 Line 29 is "information_schema.key_column_usage" – Jeyan Aug 28 '13 at 10:37
  • 3
    @noboundaries you're trying that on Oracle, the question is about MySQL – ymajoros Sep 12 '14 at 05:05
6

Try doing:

SHOW TABLE STATUS FROM credentialing1;

The foreign key constraints are listed in the Comment column of the output.

codaddict
  • 445,704
  • 82
  • 492
  • 529
  • 3
    I see only table comments in the Comment column. It is probably something to do with InnoDB types. – clockworkgeek Dec 30 '12 at 13:48
  • 3
    Comments are only for user comments. That's for sure not the place where FK definitions are stored! If they're for you - it must have been done on your behalf by some RDBMS tool. – stamster Feb 24 '18 at 18:13
1

There is also a tool that oracle made called mysqlshow

If you run it with the --k keys $table_name option it will display the keys.

SYNOPSIS
   mysqlshow [options] [db_name [tbl_name [col_name]]]
.......
.......
.......
·   --keys, -k
   Show table indexes.

example:

╰─➤  mysqlshow -h 127.0.0.1 -u root -p --keys database tokens
Database: database  Table: tokens
+-----------------+------------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
| Field           | Type             | Collation          | Null | Key | Default | Extra          | Privileges                      | Comment |
+-----------------+------------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
| id              | int(10) unsigned |                    | NO   | PRI |         | auto_increment | select,insert,update,references |         |
| token           | text             | utf8mb4_unicode_ci | NO   |     |         |                | select,insert,update,references |         |
| user_id         | int(10) unsigned |                    | NO   | MUL |         |                | select,insert,update,references |         |
| expires_in      | datetime         |                    | YES  |     |         |                | select,insert,update,references |         |
| created_at      | timestamp        |                    | YES  |     |         |                | select,insert,update,references |         |
| updated_at      | timestamp        |                    | YES  |     |         |                | select,insert,update,references |         |
+-----------------+------------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
+--------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name                 | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tokens | 0          | PRIMARY                  | 1            | id          | A         | 2           |          |        |      | BTREE      |         |               |
| tokens | 1          | tokens_user_id_foreign   | 1            | user_id     | A         | 2           |          |        |      | BTREE      |         |               |
+--------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
GardenRouteGold
  • 5,979
  • 2
  • 14
  • 23
1

Analogous to @Resh32, but without the need to use the USE statement:

SELECT TABLE_NAME,
       COLUMN_NAME,
       CONSTRAINT_NAME,
       REFERENCED_TABLE_NAME,
       REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = "database_name" 
      AND TABLE_NAME = "table_name" 
      AND REFERENCED_COLUMN_NAME IS NOT NULL;

Useful, e.g. using the ORM.

simhumileco
  • 31,877
  • 16
  • 137
  • 115