ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

列出MySQL表外键的高效方法?

2019-06-30 14:02:20  阅读:163  来源: 互联网

标签:mysql performance


是否有一种高效的方法来获取分配给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表信息进行交叉引用可能会有所帮助,但这会让我们回到脆弱的字符串解析.

任何帮助,甚至是关于该问题的其他智能讨论的链接,将不胜感激.

解决方法:

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输出,但根据我的发现,它似乎是普遍接受的做事方式.

标签:mysql,performance
来源: https://codeday.me/bug/20190630/1337209.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有