2017-02-17 3 views
0

Wie sollte man mehrere Mitglieder von Gruppen modellieren? Lassen Sie mich ein Beispiel geben.Wie man mehrere Mitglieder von Gruppen modelliert?

Ich habe Menschen, Häuser und Haushaltsgegenstände.

Alle Häuser sind im Besitz einer einzelnen Person und eine Person kann mehr als ein Haus besitzen.

Alle Haushaltsgegenstände befinden sich in einem einzigen Haus und sind im Besitz des Eigentümers des Hauses. Für meine spezielle Situation möchte ich auch einen zusätzlichen Zähler für alle Haushaltsgegenstände, die einer bestimmten Person gehören, haben.

Darüber hinaus, während alle Haushaltsgegenstände einige Eigenschaften teilen, haben sie auch einige Eigenschaften basierend auf der Art des Haushalts Artikels sie sind. Angenommen, es gibt nur wenige Arten von Haushaltsgegenständen wie Wasserbetten, Fernseher und Kühlschränke. Beachten Sie, dass es auch möglich sein muss, einen Haushaltsartikel mit einer anderen Tabelle zu verknüpfen (zum Beispiel muss otherPeopleInterestedInBuyingAHouseholdItem einen Fremdschlüssel für Haushaltsartikel unabhängig von der Art des Haushaltsgegenstands haben).

Also, Häuser sind die Gruppe, und Haushaltsmitglieder sind Mitglieder dieser Gruppe.

Wie soll das modelliert werden? Zwei Möglichkeiten sind unten. Ist einer der oben genannten Regeln besser als der andere? Ich erkenne, dass die erste Option mit houses composite incrementing Primärschlüssel nicht gut mit InnoDB spielt, kann aber mit Trigger/etc implementiert werden, die akzeptabel ist. Oder vielleicht eine dritte Option, die besser ist?

enter image description here

-- MySQL Script generated by MySQL Workbench 
-- 02/16/17 16:01:38 
-- 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`.`people` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`people` (
    `idpeople` INT NOT NULL AUTO_INCREMENT, 
    `name` VARCHAR(45) NOT NULL, 
    `age` INT NOT NULL, 
    PRIMARY KEY (`idpeople`)) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`houses` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`houses` (
    `idhouses` INT NOT NULL AUTO_INCREMENT, 
    `people_idpeople` INT NOT NULL, 
    `address` VARCHAR(45) NOT NULL, 
    `square_feet` INT NOT NULL, 
    PRIMARY KEY (`idhouses`), 
    INDEX `fk_houses_people1_idx` (`people_idpeople` ASC), 
    CONSTRAINT `fk_houses_people1` 
    FOREIGN KEY (`people_idpeople`) 
    REFERENCES `mydb`.`people` (`idpeople`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`houseHoldItems` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`houseHoldItems` (
    `idhouseHoldItems` INT NOT NULL AUTO_INCREMENT, 
    `houses_idhouses` INT NOT NULL, 
    `value` DECIMAL(6,2) NOT NULL, 
    `dateBought` DATETIME NOT NULL, 
    PRIMARY KEY (`idhouseHoldItems`, `houses_idhouses`), 
    INDEX `fk_houseHoldItems_houses_idx` (`houses_idhouses` ASC), 
    CONSTRAINT `fk_houseHoldItems_houses` 
    FOREIGN KEY (`houses_idhouses`) 
    REFERENCES `mydb`.`houses` (`idhouses`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 

-- ----------------------------------------------------- 
-- Table `mydb`.`waterBeds` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`waterBeds` (
    `houseHoldItems_idhouseHoldItems` INT NOT NULL, 
    `houseHoldItems_houses_idhouses` INT NOT NULL, 
    `gallonsWaterSize` INT NOT NULL, 
    PRIMARY KEY (`houseHoldItems_idhouseHoldItems`, `houseHoldItems_houses_idhouses`), 
    CONSTRAINT `fk_waterBeds_houseHoldItems1` 
    FOREIGN KEY (`houseHoldItems_idhouseHoldItems` , `houseHoldItems_houses_idhouses`) 
    REFERENCES `mydb`.`houseHoldItems` (`idhouseHoldItems` , `houses_idhouses`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`televisions` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`televisions` (
    `houseHoldItems_idhouseHoldItems` INT NOT NULL, 
    `houseHoldItems_houses_idhouses` INT NOT NULL, 
    `screenSize` INT NOT NULL, 
    `brandName` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`houseHoldItems_idhouseHoldItems`, `houseHoldItems_houses_idhouses`), 
    CONSTRAINT `fk_televisions_houseHoldItems1` 
    FOREIGN KEY (`houseHoldItems_idhouseHoldItems` , `houseHoldItems_houses_idhouses`) 
    REFERENCES `mydb`.`houseHoldItems` (`idhouseHoldItems` , `houses_idhouses`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`refrigerators` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`refrigerators` (
    `houseHoldItems_idhouseHoldItems` INT NOT NULL, 
    `houseHoldItems_houses_idhouses` INT NOT NULL, 
    `icecubeCapacity` INT NOT NULL, 
    `color` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`houseHoldItems_idhouseHoldItems`, `houseHoldItems_houses_idhouses`), 
    CONSTRAINT `fk_refrigerators_houseHoldItems1` 
    FOREIGN KEY (`houseHoldItems_idhouseHoldItems` , `houseHoldItems_houses_idhouses`) 
    REFERENCES `mydb`.`houseHoldItems` (`idhouseHoldItems` , `houses_idhouses`) 
    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; 

enter image description here

-- MySQL Script generated by MySQL Workbench 
-- 02/16/17 16:00:37 
-- 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`.`people` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`people` (
    `idpeople` INT NOT NULL AUTO_INCREMENT, 
    `name` VARCHAR(45) NOT NULL, 
    `age` INT NOT NULL, 
    PRIMARY KEY (`idpeople`)) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`houses` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`houses` (
    `idhouses` INT NOT NULL AUTO_INCREMENT, 
    `people_idpeople` INT NOT NULL, 
    `address` VARCHAR(45) NOT NULL, 
    `square_feet` INT NOT NULL, 
    PRIMARY KEY (`idhouses`), 
    INDEX `fk_houses_people1_idx` (`people_idpeople` ASC), 
    CONSTRAINT `fk_houses_people1` 
    FOREIGN KEY (`people_idpeople`) 
    REFERENCES `mydb`.`people` (`idpeople`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`houseHoldItems` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`houseHoldItems` (
    `idhouseHoldItems` INT NOT NULL AUTO_INCREMENT, 
    `houses_idhouses` INT NOT NULL, 
    `uniqueKey` INT NOT NULL, 
    `value` DECIMAL(6,2) NOT NULL, 
    `dateBought` DATETIME NOT NULL, 
    PRIMARY KEY (`idhouseHoldItems`), 
    INDEX `fk_houseHoldItems_houses1_idx` (`houses_idhouses` ASC), 
    UNIQUE INDEX `unique_key` (`houses_idhouses` ASC, `uniqueKey` ASC), 
    CONSTRAINT `fk_houseHoldItems_houses1` 
    FOREIGN KEY (`houses_idhouses`) 
    REFERENCES `mydb`.`houses` (`idhouses`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`waterBeds` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`waterBeds` (
    `gallonsWaterSize` INT NOT NULL, 
    `houseHoldItems_idhouseHoldItems` INT NOT NULL, 
    PRIMARY KEY (`houseHoldItems_idhouseHoldItems`), 
    CONSTRAINT `fk_waterBeds_houseHoldItems1` 
    FOREIGN KEY (`houseHoldItems_idhouseHoldItems`) 
    REFERENCES `mydb`.`houseHoldItems` (`idhouseHoldItems`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`televisions` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`televisions` (
    `screenSize` INT NOT NULL, 
    `brandName` VARCHAR(45) NOT NULL, 
    `houseHoldItems_idhouseHoldItems` INT NOT NULL, 
    PRIMARY KEY (`houseHoldItems_idhouseHoldItems`), 
    CONSTRAINT `fk_televisions_houseHoldItems1` 
    FOREIGN KEY (`houseHoldItems_idhouseHoldItems`) 
    REFERENCES `mydb`.`houseHoldItems` (`idhouseHoldItems`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`refrigerators` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`refrigerators` (
    `icecubeCapacity` INT NOT NULL, 
    `color` VARCHAR(45) NOT NULL, 
    `houseHoldItems_idhouseHoldItems` INT NOT NULL, 
    PRIMARY KEY (`houseHoldItems_idhouseHoldItems`), 
    CONSTRAINT `fk_refrigerators_houseHoldItems1` 
    FOREIGN KEY (`houseHoldItems_idhouseHoldItems`) 
    REFERENCES `mydb`.`houseHoldItems` (`idhouseHoldItems`) 
    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

Sie können es einfacher finden, ein EAV-Modell für Haushaltsgegenstände zu übernehmen, aber das kann seine eigenen Probleme auch bringen, so denke ich, Ihre Vorgehensweise ist in Ordnung - außer ich würde mich nicht mit einem zusammengesetzten Schlüssel kümmern Dieser Schlüssel wird inkrementiert. – Strawberry

+0

@Strawberry Also, wenn nicht ein EAV-Modell, empfehlen Sie die zweite Option? Es erfordert ein zusätzliches Feld im Feld 'householdItems', entfernt jedoch eine Spalte in den Tabellen für bestimmte Haushaltsgegenstände und erleichtert das Zusammenfügen ein wenig. Sind das Ihre Gründe, oder gibt es mehr? – user1032531

Antwort

0

Voranstellen Spaltennamen mit den Tabellennamen umständlich und unnötig wird.

EAV ist ein schlechter Weg zu gehen, aber es ist besser als separate Tabellen für Kühlschränke und Fernseher. Folge dem Tag, den ich hinzugefügt habe. Die Quintessenz: haben Sie Spalten für Spalten, die Sie in MySQL manipulieren müssen, werfen Sie den Rest in eine einzelne JSON-Spalte.

Für "viele: viele" Tabellen, siehe my tips.

+1

Ich denke manchmal, EAV macht Sinn, aber man sollte nicht so leichtfertig sein und sich besser der aktuellen und zukünftigen Anforderungen sicher sein. – user1032531

Verwandte Themen