基于外键的SQL约束检查

时间:2017-09-14 19:24:55

标签: mysql sql mariadb

我在数据库中有几个表,我试图为其中一些建立一个稍微复杂的约束。

该问题主要涉及四个表:

  • “主”表,主键id可以引用。
  • 两个中间表(我们称之为“a”和“b”),每个表都有自己的id,每个中间表都有一列引用(foreign key)到main.id
  • “最终”表格,有自己的id,并且有两列分别引用ab

在“final”表中,“a”和“b”表引用的元素需要引用“main”中的相同条目。

表格的简化定义:

CREATE TABLE `main_table` (
    `id` INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
    -- other fields, indexes, etc
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `table_a` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `main_ref` INT NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `main` (`main_ref`),
    FOREIGN KEY (`main_ref`) REFERENCES `main_table` (`id`)
    -- other fields, indexes, etc
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `table_b` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `main_ref` INT NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `main` (`main_ref`),
    FOREIGN KEY (`main_ref`) REFERENCES `main_table` (`id`)
    -- other fields, indexes, etc
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `final` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `ref_a` INT NOT NULL,
    `ref_b` INT NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `a` (`ref_a`),
    FOREIGN KEY (`ref_a`) REFERENCES `table_a` (`id`),
    INDEX `b` (`ref_b`),
    FOREIGN KEY (`ref_b`) REFERENCES `table_b` (`id`)
    -- other fields, indexes, etc
    -- The `main_ref` value in the entries referenced by `ref_a` and `ref_b` should match!!
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

UI和后端代码都应该已经无法实现无效条目,但是这个项目最终将涉及连接到同一数据库的其他应用程序,所以我更喜欢数据库引擎来处理尽可能多的数据完整性检查。

此外,值得一提的是,在目前的开发阶段,添加新的列和/或索引是完全正常的。

信息在那里,我所缺少的是一种告诉引擎需要检查的方法。我怀疑生成的虚拟列和CHECK约束可能会有所帮助,但在查看了几个来源(包括MariaDB和MySQL文档以及一些网络搜索)后,我找不到这样做的方法。

我在Fedora 25上运行MariaDB 10.2.5(x86_64 arch)。如果它是相关的,后端代码是用Perl(v5.24.1)编写的,并使用DBI模块连接到数据库。

1 个答案:

答案 0 :(得分:2)

此(业务逻辑)无法在SCHEMA约束级别处理,而是通过TRIGGERSSTORED PROCEDURES处理。

存储过程将验证(再次)并允许INSERT / UPDATE / DELETE

如果未遵循业务逻辑,触发器将无效。

个人品味,将业务逻辑留给显示器和后端。将其保存在数据库中非常困难且容易出错并且不易变更。但我听说有关外部应用程序 m uck up up ...因此提供API而不是直接DB操作