Search code examples
mysqlsqldatabase-designcreate-table

SQL : ERROR 1005: Can't create table 'obl2.itemsubjects' (errno: 121)


I have the following tables:

CREATE  TABLE `OBL2`.`item` (
`itemID` INT NOT NULL AUTO_INCREMENT ,
`itemName` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`itemID`) ,
INDEX `itemName` (`itemName` ASC) );

CREATE  TABLE `OBL2`.`subject` (
`subjectID` INT NOT NULL ,
`subjectName` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`subjectID`) );

Now since the connection is many to many, each item can have many subject and each subject can be related to many items - I'd like to set a connection table. This is my code:

CREATE  TABLE `OBL2`.`itemsubjects` (
`itemID` INT NOT NULL ,
`subjectID` INT NOT NULL ,
PRIMARY KEY (`itemID`, `subjectID`) ,
INDEX `itemID_idx` (`itemID` ASC) ,
INDEX `subjectID_idx` (`subjectID` ASC) ,
CONSTRAINT `itemID`
FOREIGN KEY (`itemID` )
REFERENCES `OBL2`.`item` (`itemID` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `subjectID`
FOREIGN KEY (`subjectID` )
REFERENCES `OBL2`.`subject` (`subjectID` )
ON DELETE CASCADE
ON UPDATE CASCADE);

but for some reason the code of the 3rd table is not being accepted. I get an error message:

ERROR 1005: Can't create table 'obl2.itemsubjects' (errno: 121)

I've read about the error on the internet and it says it's a known issue of MYSQL yet there are no solutions.

Any thoughts?


Solution

  • The MySQL docs say in FOREIGN KEY Constraints (emphasis mine):

    If the CONSTRAINT symbol clause is given, the symbol value must be unique in the database. If the clause is not given, InnoDB creates the name automatically.

    So, the reason that the itemsubject table creation failed, was that you had another (foreign key) constraint, named itemID, or one named subjectID in some other table of the database.

    It's good to have a naming conevntion that is standard across the database. Just as you have ColumnName_idx for indices, you can use ReferencedTable_ReferencingTable_FK for foreign key constraints:

    CREATE  TABLE OBL2.itemsubjects (
      itemID INT NOT NULL ,
      subjectID INT NOT NULL ,
      PRIMARY KEY 
        (itemID, subjectID) ,
      INDEX itemID_idx                           -- I like these 
        (itemID ASC) ,
      INDEX subjectID_idx                        -- two
        (subjectID ASC) ,
      CONSTRAINT item_itemsubject_FK             -- what I propose, here
        FOREIGN KEY (itemID)
        REFERENCES OBL2.item (itemID)
          ON DELETE CASCADE
          ON UPDATE CASCADE,
      CONSTRAINT subject_itemsubject_FK          -- and here 
        FOREIGN KEY (subjectID)
        REFERENCES OBL2.subject (subjectID)
          ON DELETE CASCADE
          ON UPDATE CASCADE
    );