douchao0358 2017-02-13 02:21
浏览 45

列出数据库表关系及其类型

I'm wondering if there is a way to programmatically list table relationships in a database, and their type, based on foreign key relationships?


Take for example these tables:

CREATE TABLE `a` (
    `id` int NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `b` (
    `id` int NOT NULL,
    `a_id` int NOT NULL,
    PRIMARY KEY (`id`),
    CONSTRAINT `fk.b.a.b` FOREIGN KEY (`a_id`) REFERENCES `a` (`id`)
) ENGINE=InnoDB;

CREATE TABLE `c` (
    `id` int NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `b_c` (
    `b_id` int NOT NULL,
    `c_id` int NOT NULL,
    PRIMARY KEY (`b_id`,`c_id`),
    CONSTRAINT `fk.b_c.b.c` FOREIGN KEY (`c_id`) REFERENCES `c` (`id`),
    CONSTRAINT `fk.b_c.c.b` FOREIGN KEY (`b_id`) REFERENCES `b` (`id`)
) ENGINE=InnoDB;

We can get the foreign key relationships with this query:

SELECT 
    table_name 'table',
    column_name 'column',
    referenced_table_name 'referenced_table',
    referenced_column_name 'referenced_column'
    FROM
        information_schema.key_column_usage
    WHERE
        referenced_table_name IS NOT NULL
        AND table_schema = 'test';

table   column   referenced_table   referenced_column
b       a_id     a                  id
b_c     c_id     c                  id
b_c     b_id     b                  id

Now... I think the relationship information above should be enough to deduce what relationships exists and their types, but I'm not able to translate it into an algorithm... To answer my original question: I know there is a way, but haven't been able to find it.

  • 写回答

2条回答 默认 最新

  • douyaosi3164 2017-02-13 03:02
    关注

    I think the one to many is easy, you already got it. Iterate through this table

    row table   column   referenced_table   referenced_column
    1   b       a_id     a                  id
    2   b_c     c_id     c                  id
    3   b_c     b_id     b                  id
    

    and there you have all the one to many

    • row 1: A → B, one-to-many
    • row 2: C → B_C, one-to-many
    • row 3: B → B_C, one-to-many

    and all the many to one are the reversed of those

    • row 1: B → A, many-to-one (reverse of previous)
    • row 2: B_C → C, many-to-one (reverse of previous)
    • row 3: B_C → B, many-to-one (reverse of previous)

    The difficulty would be to find the many-to-many, teoretically I think you should use a graph and navigate it to find all many-to-many relations, but I can think of a trick you could make with the table you have: group by column table like this

    SELECT
        table as through,
        GROUP_CONCAT(referenced_table SEPARATOR ',') as tables
    FROM (
        SELECT 
            table_name 'table',
            referenced_table_name 'referenced_table',
        FROM
            information_schema.key_column_usage
        WHERE
            referenced_table_name IS NOT NULL
            AND table_schema = 'test';
        ) as yourQuery
    GROUP BY table
    HAVING count(referenced_table) > 1;
    

    You should end with something like this

    row   through   tables
    1     b_c       c,b
    

    wich would give to you the name of the through-table in the first column, and the name of the multiple many-to-many tables on the "tables" row (could be 2 or more)

    评论

报告相同问题?

悬赏问题

  • ¥15 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序