mysqldatabasemysql-workbenchpolymorphic-associations

polymorphic relation in MySQL


First Question

I wanted to make an polymorphic relation in MySQL. I had this post as an example: Creating a polymorphic association using MySQL Workbench

My Question, with this solution an join doesn't work. Is there any Way to make an join work?

That was my try:

SELECT * FROM tblstall INNER JOIN tblstall ON tblstall.animal = tbldogs.ID;

And The Error Message was:

Error Code: 1066. Not unique table/alias: 'tblstall' 0.000 sec

Second Question:

How can I make an dynamically Select request? So that when tblstall.animalType = 2, the data gets taken from tblDogs and when tblstall.animalType = 1 it gets taken from tblHorses.

Thats my current SELECT request

SELECT * FROM tblstall, tbldogs WHERE tblstall.animalType = 2 AND tbldogs.ID = tblstall.animal;

used Database

This is my current DB i created: This is my current DB i created:

And the SQL Script

-- MySQL Workbench Forward Engineering

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='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

-- -----------------------------------------------------
-- Schema test
-- -----------------------------------------------------

-- -----------------------------------------------------
-- Schema test
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `test` DEFAULT CHARACTER SET utf8 ;
USE `test` ;

-- -----------------------------------------------------
-- Table `test`.`tblDogs`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test`.`tblDogs` (
  `ID` INT NOT NULL,
  `name` VARCHAR(45) NULL,
  PRIMARY KEY (`ID`))
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `test`.`tblHorses`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test`.`tblHorses` (
  `ID` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  PRIMARY KEY (`ID`))
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `test`.`tblStall`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test`.`tblStall` (
  `ID` INT NOT NULL,
  `Sizes` VARCHAR(45) NULL,
  `animal` INT NOT NULL,
  `animalType` INT NOT NULL,
  PRIMARY KEY (`ID`),
  CONSTRAINT `fk_tblStall_tblDogs`
    FOREIGN KEY (`animal`)
    REFERENCES `test`.`tblDogs` (`ID`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_tblStall_tblHorses1`
    FOREIGN KEY (`animal`)
    REFERENCES `test`.`tblHorses` (`ID`)
    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;

Ohh and Stall is the German word for stable if thats confusing.


Solution

  • This is what you're looking for:

    SELECT * 
    FROM tblstall AS s
    LEFT OUTER JOIN tblhorses AS h ON h.ID = s.animal AND s.animalType = 1
    LEFT OUTER JOIN tbldogs AS d ON h.ID = s.animal AND s.animalType = 2;
    

    Polymorphic associations is a tricky design, because it's fundamentally incompatible with relational databases.

    I've written more about this several times on Stack Overflow, see my past answers on the polymorphic-associations tag.

    I also wrote a chapter about this subject in my book, SQL Antipatterns, Volume 1: Avoiding the Pitfalls of Database Programming.