Mysql 组依赖SQL设计

Mysql 组依赖SQL设计,mysql,sql,database-design,relational-database,schema,Mysql,Sql,Database Design,Relational Database,Schema,我有一个实体,根据它所属的组,它没有空的要求。例如 教堂有三种类型:佛教、穆斯林和基督教 所有教堂都有一些共同的必需属性,然而,每种类型的教堂都有额外的必需属性 所有人都有一些共同的必需属性,但是,基于他们所属的教堂类型,他们有额外的必需属性 人们必须属于一个且仅属于一个教会,但是,如果符合上述规则,可以将其教会改为任何其他宗教。他们的“类型”基于他们所属的教会类型 具有所需属性的实体应如何基于该实体所属的组进行建模?或者根据我的设想,教会和人们应该如何建模 这是我目前正在做的,但它似乎不正

我有一个实体,根据它所属的组,它没有空的要求。例如

  • 教堂有三种类型:佛教、穆斯林和基督教
  • 所有教堂都有一些共同的必需属性,然而,每种类型的教堂都有额外的必需属性
  • 所有人都有一些共同的必需属性,但是,基于他们所属的教堂类型,他们有额外的必需属性
  • 人们必须属于一个且仅属于一个教会,但是,如果符合上述规则,可以将其教会改为任何其他宗教。他们的“类型”基于他们所属的教会类型
具有所需属性的实体应如何基于该实体所属的组进行建模?或者根据我的设想,教会和人们应该如何建模

这是我目前正在做的,但它似乎不正确。例如,一个人可以在成为违反规则的佛教徒、穆斯林或基督徒之前加入。此外,一个人或一个教会可能不止一种类型,这也违反了规则


一种惯用法声明性地强制执行不相交的子类型:

  • 向父表和子表添加类型鉴别器/标记列
    u type
  • 将superkey
    UNIQUE NOT NULL(id,类型)
    添加到父表
  • FOREIGN
    (super)
    键(id,宗教类型)
    添加到子表中,引用父表
  • 将约束
    检查(宗教类型='
    宗教
    ')
    或值为
    宗教
    的常量计算列添加到子表中
这仍然不能强制每个父母都是孩子。发件人:

我们需要触发器来合理地约束SQL数据库。我们可以使用习惯用法来获取所能得到的声明性约束


只需找到每个相关应用程序关系的直接谓词,并给它一个表。这里是父表和子表。约束来自谓词和可能的位置。声明它们以防止不可能的更新。每当某些列中的值必须出现在其他列中时,我们就声明一个FK。您不必考虑子类型实体ID的特殊情况。某些ID最终会出现在某些表中,因为它们的某些情况是真实的。最终是它们满足不同的谓词,使事物具有不同的“类型”,而不是相反。

您可以添加一些检查约束。使用相同模式的多个表(您的3个“church”表)通常是一个糟糕的设计。用一个
sect
表和一列
sect
重新考虑它。这是一个常见问题解答,谷歌的“stackoverflow数据库sql”加上子类型或多态性,还有多个/多个/两个FKs/关系/关联多个/多个表(尽管通常需要的约束不是FK)。卡温很犀利;他值得一听。OO技术很难嵌入SQL。而
外键
则增加了难度。FK生成的
索引
是唯一的“需求”。谢谢philipxy,我会这样做并查看它。考虑到您建议的其他限制条件,您是否同意为每种教堂类型和个人类型提供单独的表格?关于你的上一句话,我不希望在可能的情况下使用触发器,但当我觉得应用程序强制执行太危险时,我会使用触发器。是的,“单独的表”是“合适的”。请看我的扩展答案。PS Re我的“直截了当”:在评论问题(在你的几分钟内发布)时,我(只是)回答“虽然你不讨厌表中的所有空列都是单独表的外部联接。”
-- MySQL Script generated by MySQL Workbench
-- 02/10/17 21:41:31
-- 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`.`churches`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`churches` (
  `idchurches` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  `address` VARCHAR(45) NOT NULL,
  `members` INT NOT NULL,
  PRIMARY KEY (`idchurches`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`churches_buddhist`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`churches_buddhist` (
  `churches_idchurches` INT NOT NULL,
  `number_of_buddas_in_church` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`churches_idchurches`),
  CONSTRAINT `fk_churches_buddhist_churches`
    FOREIGN KEY (`churches_idchurches`)
    REFERENCES `mydb`.`churches` (`idchurches`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`churches_muslim`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`churches_muslim` (
  `churches_idchurches` INT NOT NULL,
  `savior` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`churches_idchurches`),
  CONSTRAINT `fk_churches_muslim_churches1`
    FOREIGN KEY (`churches_idchurches`)
    REFERENCES `mydb`.`churches` (`idchurches`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`churches_christian`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`churches_christian` (
  `churches_idchurches` INT NOT NULL,
  `savior` VARCHAR(45) NOT NULL,
  `number_of_crosses_in_church` INT NOT NULL,
  PRIMARY KEY (`churches_idchurches`),
  CONSTRAINT `fk_churches_christian_churches1`
    FOREIGN KEY (`churches_idchurches`)
    REFERENCES `mydb`.`churches` (`idchurches`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`people`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`people` (
  `idpeople` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  `age` TINYINT NOT NULL,
  `race` VARCHAR(45) NOT NULL,
  `gender` VARCHAR(45) NOT NULL,
  `favoriteVegitable` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`idpeople`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`buddhists`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`buddhists` (
  `people_idpeople` INT NOT NULL,
  `WidthOfBelly` BIGINT NOT NULL,
  `LevelOfCconsciousness` INT NOT NULL,
  `churches_buddhist_churches_idchurches` INT NOT NULL,
  PRIMARY KEY (`people_idpeople`),
  INDEX `fk_buddhists_churches_buddhist1_idx` (`churches_buddhist_churches_idchurches` ASC),
  CONSTRAINT `fk_buddhists_people1`
    FOREIGN KEY (`people_idpeople`)
    REFERENCES `mydb`.`people` (`idpeople`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_buddhists_churches_buddhist1`
    FOREIGN KEY (`churches_buddhist_churches_idchurches`)
    REFERENCES `mydb`.`churches_buddhist` (`churches_idchurches`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`muslims`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`muslims` (
  `people_idpeople` INT NOT NULL,
  `DaysOffTakenForRamadan` INT NOT NULL,
  `favoriteMeat` VARCHAR(45) NOT NULL,
  `churches_muslim_churches_idchurches` INT NOT NULL,
  PRIMARY KEY (`people_idpeople`),
  INDEX `fk_muslims_churches_muslim1_idx` (`churches_muslim_churches_idchurches` ASC),
  CONSTRAINT `fk_muslims_people1`
    FOREIGN KEY (`people_idpeople`)
    REFERENCES `mydb`.`people` (`idpeople`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_muslims_churches_muslim1`
    FOREIGN KEY (`churches_muslim_churches_idchurches`)
    REFERENCES `mydb`.`churches_muslim` (`churches_idchurches`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`christians`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`christians` (
  `people_idpeople` INT NOT NULL,
  `ChristmasPresentsReceived` INT NOT NULL,
  `HolyMarysSaidPerDay` INT NOT NULL,
  `favoriteMeat` VARCHAR(45) NOT NULL,
  `FavoritePork` VARCHAR(45) NOT NULL,
  `churches_christian_churches_idchurches` INT NOT NULL,
  PRIMARY KEY (`people_idpeople`),
  INDEX `fk_christians_churches_christian1_idx` (`churches_christian_churches_idchurches` ASC),
  CONSTRAINT `fk_christians_people1`
    FOREIGN KEY (`people_idpeople`)
    REFERENCES `mydb`.`people` (`idpeople`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_christians_churches_christian1`
    FOREIGN KEY (`churches_christian_churches_idchurches`)
    REFERENCES `mydb`.`churches_christian` (`churches_idchurches`)
    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;