繁体   English   中英

确保SQL超类型表具有子类型

[英]Ensure SQL supertype table has subtype

我有以下数据库架构。

由于非NULL FK约束,确保每个父记录都存在一个实体记录是微不足道的。

如何确保每个父记录都有一个子记录?

ERD

-- MySQL Script generated by MySQL Workbench
-- 01/07/15 06:01:50
-- Model: New Model    Version: 1.0
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `mydb` ;

-- -----------------------------------------------------
-- Table `mydb`.`entity`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`entity` (
  `identity` INT NOT NULL,
  `stuff` VARCHAR(45) NULL,
  PRIMARY KEY (`identity`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`parent1`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`parent1` (
  `entity_identity` INT NOT NULL,
  `stuff` VARCHAR(45) NULL,
  PRIMARY KEY (`entity_identity`),
  CONSTRAINT `fk_parent1_entity`
    FOREIGN KEY (`entity_identity`)
    REFERENCES `mydb`.`entity` (`identity`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`parent2`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`parent2` (
  `entity_identity` INT NOT NULL,
  `stuff` VARCHAR(45) NULL,
  PRIMARY KEY (`entity_identity`),
  CONSTRAINT `fk_parent2_entity1`
    FOREIGN KEY (`entity_identity`)
    REFERENCES `mydb`.`entity` (`identity`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`child1_1`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`child1_1` (
  `parent1_entity_identity` INT NOT NULL,
  `stuff` VARCHAR(45) NULL,
  PRIMARY KEY (`parent1_entity_identity`),
  CONSTRAINT `fk_child1_1_parent11`
    FOREIGN KEY (`parent1_entity_identity`)
    REFERENCES `mydb`.`parent1` (`entity_identity`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`child1_2`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`child1_2` (
  `parent1_entity_identity` INT NOT NULL,
  `stuff` VARCHAR(45) NULL,
  PRIMARY KEY (`parent1_entity_identity`),
  CONSTRAINT `fk_child1_2_parent11`
    FOREIGN KEY (`parent1_entity_identity`)
    REFERENCES `mydb`.`parent1` (`entity_identity`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

我认为这必须由应用程序强制执行。

尝试使用触发器强制执行此操作会导致序列问题。 如果您不能在没有实体的情况下创建父项,并且在没有父项的情况下也不能创建实体,那么首先创建哪个? 在创建任何一条记录时,数据库引擎都无法“知道”是否要在接下来的几毫秒内创建另一条记录。

但是,在代码中,您可以收集所有数据,如果所有必需的数据都可用,则可以写两条记录,如果没有,则发出错误消息。

根据您的要求,您可能会在创建实体记录时触发该触发器,该记录会自动创建具有默认值的父记录,反之亦然。 这样的虚拟记录是否有用,我不能不对您的应用程序有更多了解。

您可能有一个创建实体和父记录的存储过程,因此,如果程序调用该存储过程,则必须同时创建该记录。 但是我不知道,在我熟悉的任何数据库引擎中,要说程序创建记录的唯一方式就是通过特定的存储过程。 因此,强制使用该程序将取决于程序员遵循该约定。 而且,如果程序员遵循约定使用存储过程,则他们应该能够遵循约定以始终使用他们使用的任何方法创建两个记录。

我的想法是创建一个库函数来创建该对,并且如果您没有创建两个库所需要的全部数据,则该函数会返回某种错误情况。 彻底调试此功能。 然后告诉程序员要始终使用此函数来创建记录。 然后,如果有问题,那就去哪里看看。

在您的设计中拥有超级类型将确保添加更多子表成为可能,而无需重构现有表和应用程序。 这意味着父母不会意识到孩子。

如果您面对的是没有孩子的父母记录,则可能是应用程序有缺陷的证据。
顺便说一句,强制执行此检查约束的机制将使用触发器。

作为提示(如果使用ORM),则可以将父实体作为抽象类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM