2017-02-10 61 views
0

我有一個基於它所屬的組具有NOT NULL要求的實體。例如...組依賴關係SQL設計

  • 有三種類型的教會:佛教​​,穆斯林和基督教。
  • 所有的教堂都有一些共同的必需屬性,但是,每種類型的教會都有其他必需的屬性。
  • 所有人都有一些共同需要的屬性,但是,他們根據他們所屬的教堂類型有額外的必需屬性。
  • 但是,人們必須屬於一個且只有一個教會,但是,只要符合上述規則,他們可以將他們的教會更換爲任何宗教中的任何一個。他們所屬的人的「類型」是基於他們所屬的教堂類型。

要求屬性的實體應該如何基於實體所屬的組進行建模?或者根據我的情況,教會和人們應該如何建模?

這是目前我正在做的,但它似乎不正確。例如,一個人可以在他們成爲違反規則的佛教徒,穆斯林或基督徒之前加入。此外,一個人或教會可能不止一種類型,這也違反了規則。

enter image description here

-- MySQL Script generated by MySQL Workbench 
-- 02/10/17 21:41:31 
-- Model: New Model Version: 1.0 
SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@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 [email protected]_SQL_MODE; 
SET [email protected]_FOREIGN_KEY_CHECKS; 
SET [email protected]_UNIQUE_CHECKS; 
+0

您可以添加一些檢查約束。 – Zoltan

+2

使用相同模式的多個表(您的3個「教會」表)通常是一個糟糕的設計。用一個'churches'表重新考慮它,併爲'sect'添加一列。 –

+0

這是一個常見問題,谷歌'stackoverflow數據庫sql'加上子類型或多態,也多/許多/兩個FKs /關係/關聯多/很多表(儘管通常約束要求是*不* FK)。 [例如問題BillKarwin已經回答了多態關聯。](http://stackoverflow.com/search?q=user%3A20860%20%5Bpolymorphic-associations%5D) – philipxy

回答

0

一個成語聲明強制執行不相交的亞型:

  • 附加型判別/標籤欄religion_type父和子表
  • 添加超密鑰UNIQUE NOT NULL (id, religion_type)父表
  • FOREIGN(超級)KEY (id, religion_type)到子選項卡LES,參考父母
  • 附加約束CHECK(religion_type = 'religion')或常數計算列與價值religion到子表

這仍然沒有強制每一位家長是孩子。從this answer

需要觸發器來合理約束SQL數據庫。一個人使用習語來獲得可以聲明的約束。

只需找到每個相關應用程序關係的直接謂詞併爲其指定一個表即可。在這裏,這是父表和子表。約束遵循謂詞和可能的情況。聲明它們以防止不可能的更新。只要某些列中的值必須出現在其他列中,我們就會聲明一個FK。您不必考慮子類型實體ID的特殊情況。某些ID將會以某些表格結尾,因爲某些事情對他們來說是真實的。最終他們令人滿意的不同謂詞使不同「類型」的事物相反,而不是相反。

+0

謝謝philipxy,我會這樣做,並檢查出來。鑑於您額外推薦的約束條件,您是否同意每種教堂類型和人類類型的單獨表格都適合?關於你最後的陳述,我不想在可能的情況下使用觸發器,但是當我覺得應用程序執行過於冒險時會使用它們。 – user1032531

+0

是的,「分開的表格」是「合適的」。看到我的擴展答案。 PS Re我的「直截了​​當」:評論問題[在SQL數據庫中,當一對一關係應該在同一個表上並且在不同的表上時](https://stackoverflow.com/q/42183452/ 3404097)(在你的分鐘內發佈)我(只)回答「雖然你不反感你的表中的所有空列是單獨表的外部連接。」 – philipxy