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

时间:2017-02-13 02:21:34

标签: php mysql sql mariadb relationships

我想知道是否有办法以编程方式列出数据库中的表关系及其类型,基于外键关系?

以这些表为例:

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;

我们可以通过此查询获得外键关系:

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

现在......我认为 上面的关系信息应足以推断出存在哪些关系及其类型,但我无法将其转换为算法...回答我原来的问题:我知道有办法,但一直无法找到它。

所以,我希望有人比我更聪明,或者知道如何能够做到这一点,或者是为了解决脑筋急转弯(大脑杀手,在我的情况下)?

基本上,在这种情况下,“答案”应该是有4种关系:

  • A→B,一对多
  • B→A,多对一
  • B→C,多对多,通过b_c
  • C→B,多对多,通过b_c

我需要在PHP中执行此操作,但任何可理解的算法/伪代码都有望帮助很多。

2 个答案:

答案 0 :(得分:1)

我认为one to many很简单,你已经明白了。迭代这个表

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

并且您拥有所有one to many

  • 第1行:A→B,一对多
  • 第2行:C→B_C,一对多
  • 第3行:B→B_C,一对多

并且所有many to one都与那些

相反
  • 第1行:B→A,多对一(与之前相反)
  • 第2行:B_C→C,多对一(与之前相反)
  • 第3行:B_C→B,多对一(与之前相反)

困难在于找到many-to-many,从头到尾我认为你应该使用图表并导航它以找到所有many-to-many关系,但我可以想到你可以用表格制作一个技巧你有:按照这样的列表分组

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;

你应该以这样的结尾

结束
row   through   tables
1     b_c       c,b

将为您提供第一列中的直通表的名称,以及"表格中的多个多对多表的名称。行(可能是2或更多)

答案 1 :(得分:0)

USE information_schema;
SELECT * FROM `REFERENTIAL_CONSTRAINTS`;
SELECT * FROM `TABLE_CONSTRAINTS` where constraint_type LIKE 'F%';
SELECT * FROM `INNODB_SYS_FOREIGN_COLS`;
SELECT * FROM `INNODB_SYS_FOREIGN`;

这就是我在5.6和MariaDB 10.2.2上找到的。

对于很多:很多桌子,你也可以同时走两个方向。 Tips