I am creating a class which, takes a table from a database, and displays it to a web-page, with as much functionality as possible. One of the things I would like to support, would be having the class detect which columns in the table have a foreign key constraint on them, so that it can then go to those tables, get all of their values and use them in a select-box which is called when you edit those fields, to avoid someone violating foreign key constraints,
The main problem is discovering which fields have a foreign key constraint on them, and which tables they are pointing to. Does anyone know how to do this???
Thanks,
Lemiant
Simple way to get foreign keys for given table:
SELECT
`column_name`,
`referenced_table_schema` AS foreign_db,
`referenced_table_name` AS foreign_table,
`referenced_column_name` AS foreign_column
FROM
`information_schema`.`KEY_COLUMN_USAGE`
WHERE
`constraint_schema` = SCHEMA()
AND
`table_name` = 'your-table-name-here'
AND
`referenced_column_name` IS NOT NULL
ORDER BY
`column_name`;
The INFORMATION_SCHEMA database contains details of the full schema of all other databases, including constraints:
http://dev.mysql.com/doc/refman/5.0/en/information-schema.html
You can also run a SHOW CREATE TABLE query to get the SQL to create a table, including its constraints.
Much can be retrieved from MySQL's information_schema
, foreign keys included, as pointed out by dev-null-dweller.
1
SELECT * FROM information_schema.table_constraints
WHERE table_schema = 'dbname' AND table_name='mytable';
Instead of dbname use the function SCHEMA()
to set the name of the database in USE
.
2
As pointed out by Dan Grossman, the command
SHOW CREATE TABLE `yourtablename`
can be used basically get an SQL dump of the create table statement.
~3
MySQL provides a SHOW KEYS command. As such you could theoretically get the FK if you know a lower cardinality threshold and have few other keys in the table.
SHOW KEYS FROM `address` WHERE Non_unique AND CARDINALITY > 10000
As the key's cardinality changes each time the internal database is changed, this is rather theoretical. See the cardinality change for instance with running ANALYZE TABLE
.
~4
It is useful to stick to a naming schema, such as foreigntablename_foreignfieldname
. For example the field user_id
in a table billing
. Several ORMs of big Web Content Frameworks use this schema.
based on Bill Karwin answer in this other thread, I used this solution to get all the info I needed, included on_delete and on_update rules:
SELECT kcu.referenced_table_schema, kcu.constraint_name, kcu.table_name, kcu.column_name, kcu.referenced_table_name, kcu.referenced_column_name,
rc.update_rule, rc.delete_rule
FROM INFORMATION_SCHEMA.key_column_usage kcu
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc on kcu.constraint_name = rc.constraint_name
WHERE kcu.referenced_table_schema = 'db_name'
AND kcu.referenced_table_name IS NOT NULL
ORDER BY kcu.table_name, kcu.column_name