【问题标题】:How do I see all foreign keys to a table or column?如何查看表或列的所有外键?
【发布时间】:2010-09-17 03:04:35
【问题描述】:

在 MySQL 中,如何获取指向特定表的所有外键约束的列表?特定的列?这与this Oracle question 相同,但用于 MySQL。

【问题讨论】:

    标签: mysql foreign-keys innodb


    【解决方案1】:

    如果您使用 InnoDB 并定义了 FK,您可以查询 information_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';
    

    【讨论】:

    • 实际上,这指向了错误的方向。该查询显示了所有指向 FROM 'mytable' 的外键,而不是所有指向 'mytable' 的外键。
    • 这个在我的情况下效果更好。我需要从表中删除每个外键约束(并且只有那些)才能更改 InnoDB 引擎 MyISAM 或 NDB。
    • 您可以从 REFERENTIAL_CONSTRAINTS 表中获得双向的外键——我已经为查询添加了另一个答案。
    【解决方案2】:

    我想出的解决方案很脆弱;它依赖于 django 的外键命名约定。

    USE information_schema;
    tee mysql_output
    SELECT * FROM TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_SCHEMA = 'database_name';
    notee
    

    然后,在 shell 中,

    grep 'refs_tablename_id' mysql_output
    

    【讨论】:

      【解决方案3】:

      对于表格:

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

      基本上,我们在 where 子句中将 REFERENCED_TABLE_NAME 更改为 REFERENCED_COLUMN_NAME。

      【讨论】:

      • 这总是给我一个空集,而下面节点提出的查询工作正常
      • @Acute:你确定你问的是正确的桌子吗?如果 Node 的查询有效,那么您可能会询问另一个方向(即,来自 mytable 的键,而不是来自 mytable 的键。)这期望您使用表名编写 '' 而没有 '' ?
      • 好像我误解了你的查询,因为我正在查询从
      • 引用的键 :) (是的,我写的是表名而不是“
        ”XD)
      • 除非您确定您的表名是唯一的,否则您可能还希望将查询限制在特定的数据库中。将 where 子句更改为:where REFERENCED_TABLE_SCHEMA = 'mydatabase' and REFERENCED_TABLE_NAME = 'mytable'
      • 我将 TABLE_SCHEMA 添加到列列表 (SELECT TABLE_SCHEMA, TABLE_NAME, …) 中,这在有多个数据库的表与我们感兴趣的表/列相关的情况下很有用。
      【解决方案4】:

      发布旧答案以添加一些有用的信息。

      我遇到了类似的问题,但我也想查看 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. 要查看数据库中的所有 FK:

        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;
      

      【讨论】:

      • 如果您在 WHERE 子句中指定 k.TABLE_SCHEMA = DATABASE() 和 k.TABLE_NAME = '',这些查询运行得更快(从 2 秒到 0.0015 秒),如此处所述@ 987654321@
      • 很好的答案。您有任何针对 MyISAM 的解决方案吗?
      • 不幸的是,MyISAM 不支持外键。 dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html
      【解决方案5】:

      编辑:正如 cmets 中所指出的,这不是 OPs 问题的正确答案,但了解此命令很有用。这个问题在 Google 中显示了我正在寻找的内容,并认为我会将这个答案留给其他人查找。

      SHOW CREATE TABLE `<yourtable>`;
      

      我在这里找到了这个答案: MySQL : show constraints on tables command

      我需要这种方式是因为我想看看 FK 是如何运作的,而不仅仅是看看它是否存在。

      【讨论】:

      • 这显示了&lt;yourtable&gt; 中的所有约束,而不是指向&lt;yourtable&gt; 的所有约束。
      • 正如@Barmar 所说,这是完全错误的;它将显示属于指定表的外键,但不会显示指向 TO 表的外键,这是问题所要求的。不知道这是怎么得到 50 票的;我猜人们在真正寻找相反问题的答案时最终来到了这里,无论如何都在这里找到了答案,并且在投票之前没有费心阅读原始问题(甚至它的标题)。
      • @MarkAmery : 这是display foreign keys mysql 在谷歌中的第一个结果,可能就是这个原因;)
      • thisi 实际上显示了所有存在的约束,phpmyadmin 只会显示指向您的表的约束。似乎足以避免使用 ORM 工具重复
      • 这就是我要找的东西,所以感谢您发布它,即使它没有回答 OP 的问题。知道如何看待一段关系中的两个方向永远不会有坏处!
      【解决方案6】:

      使用

      列出您的 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官方手册。

      【讨论】:

      • 我不认为脚注“此查询确实假定约束以及所有引用和引用表都在同一个模式中。”一定是真的吗?我刚刚使用了 KEY_COLUMN_USAGE 视图(非常有帮助)来查看跨模式约束
      【解决方案7】:

      此解决方案不仅会显示所有关系,还会显示约束名称,这在某些情况下是必需的(例如删除约束):

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

      同样,对于特定的列名,添加

      and table_name = 'table_name

      在查询结束时。

      受此帖子启发 here

      【讨论】:

        【解决方案8】:

        作为 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>'
        

        对于来自

        的外键,或
        SELECT CONSTRAINT_NAME, TABLE_NAME, REFERENCED_TABLE_NAME
        FROM information_schema.REFERENTIAL_CONSTRAINTS
        WHERE CONSTRAINT_SCHEMA = '<schema>'
        AND REFERENCED_TABLE_NAME = '<table>'
        

        的外键

        如果需要,您也可以获取 UPDATE_RULE 和 DELETE_RULE。

        【讨论】:

        • 我个人更喜欢这个答案,因为使用 REFERENTIAL_CONSTRAINTS 表可以为您提供更新和级联规则。 +1
        • 在发现表时不要忘记可以通过两种方式建立外键!
        【解决方案9】:

        查找所有包含特定外键的表,例如employee_id

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

        【讨论】:

          【解决方案10】:

          使用 REFERENCED_TABLE_NAME 并不总是有效,可以是 NULL 值。以下查询可以代替:

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

          【讨论】:

            【解决方案11】:

            如果还想获取外键列的名称:

            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'
            【解决方案12】:

            我不愿再添加另一个答案,但我不得不乞求、借用和窃取其他人以获得我想要的东西,这是给定模式中表上所有 FK 关系的完整列表,包括对其他模式中的表的 FK。两个关键记录集是 information_schema.KEY_COLUMN_USAGE 和 information_schema.referential_constraints。如果缺少您想要的属性,只需取消注释 KCU。,RC。 以查看可用的内容

            SELECT DISTINCT KCU.TABLE_NAME, KCU.COLUMN_NAME, REFERENCED_TABLE_SCHEMA, KCU.REFERENCED_TABLE_NAME, KCU.REFERENCED_COLUMN_NAME, UPDATE_RULE, DELETE_RULE #, KCU.*, RC.*
            FROM information_schema.KEY_COLUMN_USAGE KCU
            INNER JOIN information_schema.referential_constraints RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
            WHERE TABLE_SCHEMA = (your schema name)
            AND KCU.REFERENCED_TABLE_NAME IS NOT NULL
            ORDER BY KCU.TABLE_NAME, KCU.COLUMN_NAME;
            

            【讨论】:

              【解决方案13】:

              SQL 中的约束是为表中的数据定义的规则。约束还限制了进入表的数据类型。如果新数据不遵守这些规则,则中止操作。

              select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE = 'FOREIGN KEY';
              

              您可以使用select * from information_schema.table_constraints;查看所有约束

              (这样会产生很多表格数据)。

              您也可以将它用于 MySQL:

              show create table tableName;
              

              【讨论】:

              • 请添加对长期价值的解释,并将其转化为更有可能被投票的高质量答案。答案应该能够帮助未来的访问者学习一些东西并快速确定您的解决方案中的元素是否适用于他们自己的编码问题。
              【解决方案14】:

              我需要鸟瞰表之间的关系(在 ORM 中使用)。使用此页面中的建议,经过试验,我整理了以下查询:

              SELECT
                  KCU.CONSTRAINT_NAME,
                  KCU.TABLE_NAME,
                  KCU.COLUMN_NAME,
                  KCU.REFERENCED_TABLE_NAME,
                  KCU.REFERENCED_COLUMN_NAME
              FROM
                  INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
                  JOIN INFORMATION_SCHEMA.COLUMNS AS COLS
                      ON
                              COLS.TABLE_SCHEMA = KCU.TABLE_SCHEMA
                          AND COLS.TABLE_NAME   = KCU.TABLE_NAME
                          AND COLS.COLUMN_NAME  = KCU.COLUMN_NAME
              WHERE
                      KCU.CONSTRAINT_SCHEMA = {YOUR_SCHEMA_NAME}
                  AND KCU.REFERENCED_TABLE_NAME IS NOT NULL
              ORDER BY
                  KCU.TABLE_NAME,
                  COLS.ORDINAL_POSITION
              

              它只返回我需要的东西,并按照我想要的顺序。

              我也对结果进行少量处理(将其转换为某种字典),以便可以将其用于创建聚合。

              【讨论】:

                猜你喜欢
                相关资源
                最近更新 更多
                热门标签