是否有高性能方式来获取分配给MySQL表的外键列表?
使用
查询信息架构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`;
可以工作,但是在我尝试过的MySQL版本上却很慢。出现了一些研究this bug,这似乎表明这是一个没有明确解决方案的持续问题。暗示的解决方案需要使用补丁重新配置或重新编译mysql,这对我正在进行的项目不起作用。
我意识到可以发布以下内容
SHOW CREATE TABLE table_name;
并获取CREATE TABLE语句的字符串表示形式,该语句将包含外键约束。但是,解析这个字符串似乎很脆弱,而且我没有大量的CREATE TABLE语句来测试。 (如果那里有一个标准的解析代码,我会喜欢一些链接)
我也意识到我可以使用以下
列出索引SHOW CREATE TABLE table_name;
索引列表将包含外键,但似乎没有办法确定哪些索引是外键,哪些是“常规”MySQL索引。同样,使用SHOW CREATE表信息进行交叉引用可能会有所帮助,但这会让我们回到脆弱的字符串解析。
任何帮助,甚至是关于该问题的其他智能讨论的链接,都将不胜感激。
答案 0 :(得分:3)
SequelPro和Magento都使用SHOW CREATE TABLE查询来加载外键信息。 Magento的实现是我要引用的,因为它既是基于PHP的系统,也是我们都非常熟悉的系统。但是,以下代码段可以应用于任何基于PHP的系统。
使用相对简单的RegEx在Varien_Db_Adapter_Pdo_Mysql::getForeignKeys()
方法(the code for this class can be found here)中完成解析:
$createSql = $this->getCreateTable($tableName, $schemaName);
// collect CONSTRAINT
$regExp = '#,\s+CONSTRAINT `([^`]*)` FOREIGN KEY \(`([^`]*)`\) '
. 'REFERENCES (`[^`]*\.)?`([^`]*)` \(`([^`]*)`\)'
. '( ON DELETE (RESTRICT|CASCADE|SET NULL|NO ACTION))?'
. '( ON UPDATE (RESTRICT|CASCADE|SET NULL|NO ACTION))?#';
$matches = array();
preg_match_all($regExp, $createSql, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$ddl[strtoupper($match[1])] = array(
'FK_NAME' => $match[1],
'SCHEMA_NAME' => $schemaName,
'TABLE_NAME' => $tableName,
'COLUMN_NAME' => $match[2],
'REF_SHEMA_NAME' => isset($match[3]) ? $match[3] : $schemaName,
'REF_TABLE_NAME' => $match[4],
'REF_COLUMN_NAME' => $match[5],
'ON_DELETE' => isset($match[6]) ? $match[7] : '',
'ON_UPDATE' => isset($match[8]) ? $match[9] : ''
);
}
在doc块中,它描述了生成的数组,如下所示:
/**
* The return value is an associative array keyed by the UPPERCASE foreign key,
* as returned by the RDBMS.
*
* The value of each array element is an associative array
* with the following keys:
*
* FK_NAME => string; original foreign key name
* SCHEMA_NAME => string; name of database or schema
* TABLE_NAME => string;
* COLUMN_NAME => string; column name
* REF_SCHEMA_NAME => string; name of reference database or schema
* REF_TABLE_NAME => string; reference table name
* REF_COLUMN_NAME => string; reference column name
* ON_DELETE => string; action type on delete row
* ON_UPDATE => string; action type on update row
*/
我知道它不是完全你所要求的,因为它使用SHOW CREATE TABLE输出,但根据我的发现,它似乎是普遍接受的做事方式。