在MySQL中按外键依赖关系排序的表名列表

时间:2014-01-31 23:10:51

标签: mysql sql database

给定MySQL数据库,如何获取按外键依赖关系排序的表名列表,以便删除每个表?我知道外键存储在KEY_COLUMN_USAGE表中,但我不确定是否有一种实用工具方法可以按正确的顺序获取表名。我更喜欢100%的SQL解决方案。

3 个答案:

答案 0 :(得分:0)

如果您的外键遵循命名约定(因为它们应该:),那么您可以执行一些简单的操作,如

select table_name, group_concat(distinct constraint_name order by constraint_name) as fk_list
from   information_schema.key_column_usage
where  constraint_name rlike 'fk'
group  by table_name
order  by fk_list, table_name;

或者,如果您的外键不遵循命名约定,那么

select table_name, group_concat(distinct constraint_name order by constraint_name) as fk_list
from   information_schema.key_column_usage
where  referenced_table_name is not null
group  by table_name
order  by fk_list, table_name;

答案 1 :(得分:0)

试试这个:

CREATE DEFINER=`root`@`localhost` PROCEDURE `getDependencyOrder`()
BEGIN
    DECLARE done INT DEFAULT 0;
    declare _id int;
    declare _name varchar(50);
    declare _refname varchar(50);

    declare cur cursor for
        select table_name, referenced_table_name
        from   information_schema.key_column_usage
        where  constraint_schema = 'your_schema_name';/*************/

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    drop table if exists temp;
    create temporary table temp (id int, tablename varchar(50)) engine=memory;

    open cur;

    set _id = 1000000;

    REPEAT
        FETCH cur INTO _name, _refname;
        IF NOT done THEN
            if not exists(select * from temp where tablename = _name) then
                insert into temp(id, tablename) values(_id, _name);
                set _id = _id + 1000;
            end if;
        end if;
    UNTIL done END REPEAT;

    CLOSE cur;

    set done = 0;

    open cur;
    REPEAT
        FETCH cur INTO _name, _refname;
        IF NOT done THEN
            if not (_refname is null) then
                if _name <> _refname then
                    #Buscar el id de la tabla
                    select id into @Id from temp where tablename = _name;
                    #Buscar el id de la tabla de referencia, si su id es mayor, ajustar su id
                    select id into @refId from temp where tablename = _refname;

                    if @refId > @Id then
                        select max(id) + 1000 into _id from temp where id < @Id;

                        if _id is null then
                            select min(id) - 1000 into _id from temp;
                        end if;

                        if exists(select * from temp where id = _id) then
                            select max(id) into @max from temp where id < @Id;
                            set _id = (@max + @Id) / 2;
                        end if;

                        update temp set id = _id where id = @refId;
                    end if;
                end if;
            end if;
        end if;
    UNTIL done END REPEAT;

    CLOSE cur;

    select * from temp order by id;

    drop table temp;
END

答案 2 :(得分:0)

这就是我通常做的事情,我希望它也适用于你:

SELECT t.TABLE_NAME FROM information_schema.key_column_usage kcu RIGHT JOIN information_schema.Tables t ON t.TABLE_NAME=kcu.TABLE_NAME WHERE t.TABLE_SCHEMA='<name_of_your_schema>' GROUP BY t.TABLE_NAME ORDER BY t.TABLE_TYPE DESC, COUNT(TRUE) DESC;

选择按其依赖项计数排序的表,大多数相关表将首先出现,最少依赖将出现在最后。请注意,我之前要求提供意见,因为他们通常比其他表更依赖于表格,但他们通常没有任何外键。