I am trying to move my database model from mysql workbench to mysql server. I am using the reverse engineer sql create script but when importing it gives me an error. I have tried to google the problem but no luck to my situation.
-- -----------------------------------------------------
-- Table `MapLibrary`.`Books`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `MapLibrary`.`Books` ;
CREATE TABLE IF NOT EXISTS `MapLibrary`.`Books` (
`ISBN` VARCHAR(13) NOT NULL,
`date_of_publication` INT NULL,
`book_title` VARCHAR(45) NULL,
PRIMARY KEY (`ISBN`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `MapLibrary`.`Genre`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `MapLibrary`.`Genre` ;
CREATE TABLE IF NOT EXISTS `MapLibrary`.`Genre` (
`genre_code` INT NOT NULL,
`genre_name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`genre_code`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `MapLibrary`.`Books_By_Genre`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `MapLibrary`.`Books_By_Genre` ;
CREATE TABLE IF NOT EXISTS `MapLibrary`.`Books_By_Genre` (
`genre_code` INT NOT NULL,
`ISBN` VARCHAR(13) NOT NULL,
PRIMARY KEY (`genre_code`, `ISBN`),
INDEX `Books_idx` (`ISBN` ASC),
CONSTRAINT `Books`
FOREIGN KEY (`ISBN`)
REFERENCES `MapLibrary`.`Books` (`ISBN`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `Genre`
FOREIGN KEY (`genre_code`)
REFERENCES `MapLibrary`.`Genre` (`genre_code`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
ERROR:
ERROR 1022 (23000) at line 89: Can't write; duplicate key in table 'books_by_genre'
Operation failed with exitcode 1
The problem is that the ISBN is NOT a unique identifier on its own in the referenced tables.
I assume, that the Books table is your base table and the three referenced tables are M:N link tables. If this is true, then your foreign keys are pointing in the wrong direction. (Try to drag the connection in the other direction?)
Related
So this is my code, I cannot proceed because I am always getting that foreign key constraint error. I have checked the data type they are consistent. Where am I going wrong?. All the problem persists where foreign keys are required. i have just posted two tables here.
-- -----------------------------------------------------
-- Table `44376936`.`AccountType`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `44376936`.`AccountType` ;
CREATE TABLE IF NOT EXISTS `44376936`.`AccountType` (
`AccountTypeID` float NOT NULL,
`AccountTypeName` VARCHAR(45) NULL,
`AccountTypeDesc` VARCHAR(45) NULL,
`AccountTypeInterestRate` FLOAT NULL,
`AccountTypeServiceFee` FLOAT NULL,
PRIMARY KEY (`AccountTypeID`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `44376936`.`Account`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `44376936`.`Account` ;
CREATE TABLE IF NOT EXISTS `44376936`.`Account` (
`AccountBSB` INT NOT NULL,
`AccountNumber` INT NOT NULL,
`AccountCurrentBalance` FLOAT NULL,
`AccountType_AccountTypeID` Float NOT NULL,
PRIMARY KEY (`AccountBSB`, `AccountNumber`, `AccountType_AccountTypeID`),
INDEX `fk_Account_AccountType_idx` (`AccountType_AccountTypeID` ASC),
CONSTRAINT `fk_Account_AccountType`
FOREIGN KEY (`AccountType_AccountTypeID`)
REFERENCES `44376936`.`AccountType` (`AccountTypeID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
I can reproduce
It comes from this instruction :
REFERENCES `44376936`.`AccountType` (`AccountTypeID`)
and the problem is the database name, probably because it begins with a number and not a letter.
This works :
REFERENCES `AccountType` (`AccountTypeID`)
So get rid of the database name. If you are running this without being on the 44376936 database, execute this instruction at the beginning of your script :
USE `44376936`;
Rextester example
I have an entity which has NOT NULL requirements based on the group it belongs to. For instance...
There are three types of churches: Buddhist, Muslim, and Christian.
All churches have some common required properties, however, each type of church has additional required properties.
All people have some common required properties, however, they have additional required properties based on the church type they belong to.
People must belong to one and only one church, however, may change their church to any other one of any religion provided that the above rules are met. The "type" of person they are is based on the church type they belong to.
How should entities who's required properties are based on the group which the entity belongs to be modeled? Or given my scenario, how should churches and people be modeled?
This is currently what I am doing, but it does not seem right. For instance, a person can be added before they become a Buddhist, Muslim, or Christian which breaks the rules. Also, a person or church can be more than one type which also breaks the rules.
-- 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;
One idiom declaratively enforcing disjoint subtypes:
add type discriminator/tag column religion_type to parent and child tables
add superkey UNIQUE NOT NULL (id, religion_type)to parent tables
add FOREIGN (super) KEY (id, religion_type) to child tables, referencing parents
add constraint CHECK( religion_type = 'religion' ) or constant computed column with value religion to child tables
This still doesn't enforce that every parent is a child. From this answer:
One needs triggers to reasonably constrain SQL databases. One uses idioms to get what declarative constraints one can.
Just find the straightforward predicate for each relevant application relationship and give it a table. Here, that's parent and child tables. The constraints follow from the predicates and possible situtations. Declare them to prevent impossible updates. Whenever values in some columns must appear in other columns we declare a FK. You don't have to think about a special case for subtyped entity ids. Certain ids will end up in certain tables because certain things are true of them. It is ultimately their satisfying different predicates that makes things of different "types", rather than vice versa.
I was just about to create my database as I realized that I'm not sure how to map one-to-many or one-to-one relations. Therefore I took MySQL Workbench and created this simple example:
MySQL Workbench shows here the one-to-one relation between A and C as well as the one-to-many relation between A and B.
But exporting these tables as .sql file gives me this:
-- -----------------------------------------------------
-- Table `reveng_me`.`A`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `reveng_me`.`A` (
`id` INT NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `reveng_me`.`B`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `reveng_me`.`B` (
`id` INT NOT NULL,
`A_id` INT NOT NULL,
PRIMARY KEY (`id`),
INDEX `fk_B_A1_idx` (`A_id` ASC),
CONSTRAINT `fk_B_A1`
FOREIGN KEY (`A_id`)
REFERENCES `reveng_me`.`A` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `reveng_me`.`C`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `reveng_me`.`C` (
`id` INT NOT NULL,
`A_id` INT NOT NULL,
PRIMARY KEY (`id`),
INDEX `fk_C_A1_idx` (`A_id` ASC),
CONSTRAINT `fk_C_A1`
FOREIGN KEY (`A_id`)
REFERENCES `reveng_me`.`A` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
I can't see a difference between B and C. Shouldn't there be a UNIQUE constraint on FOREIGN KEY ('A_id') or something else that hinders me from adding more A IDs to C?
There is actually no such thing in MySQL. A 1-1 relation isn't different from a 1-n relation in the database scheme. Some RDBMS' allow for CHECK constrains to do this, but in MySQL the CHECK is merely implemented to complete the SQL standard. You can however create an unique index that's being referenced by the other table. This is probably what you want.
Is there anything different between the two? All I see is the additional index which I don't believe fundamentally changes anything.
I would expect the first allows each t1_1 entity to be joined to multiple t1_2 entities, and the opposite as well.
For the second, I would expect each t2_1 entity to be joined to a maximum of one t2_2 entity.
But the resulting schema's generated by MySQL Workbench appear to be basically the same.
PS. Why I am doing this? Learning about super/sub tables, and went off on a tangent.
-- MySQL Script generated by MySQL Workbench
-- 08/05/15 08:12:21
-- 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`.`t1_1`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t1_1` (
`id` INT NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`t1_2`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t1_2` (
`id` INT NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`t1_1_has_t1_2`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t1_1_has_t1_2` (
`t1_1_id` INT NOT NULL,
`t1_2_id` INT NOT NULL,
PRIMARY KEY (`t1_1_id`, `t1_2_id`),
INDEX `fk_t1_1_has_t1_2_t1_21_idx` (`t1_2_id` ASC),
INDEX `fk_t1_1_has_t1_2_t1_1_idx` (`t1_1_id` ASC),
CONSTRAINT `fk_t1_1_has_t1_2_t1_1`
FOREIGN KEY (`t1_1_id`)
REFERENCES `mydb`.`t1_1` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_t1_1_has_t1_2_t1_21`
FOREIGN KEY (`t1_2_id`)
REFERENCES `mydb`.`t1_2` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`t2_1`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t2_1` (
`id` INT NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`t2_2`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t2_2` (
`id` INT NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`t2_1_hs_t2_2`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t2_1_hs_t2_2` (
`t2_1_id` INT NOT NULL,
`t2_2_id` INT NOT NULL,
PRIMARY KEY (`t2_1_id`, `t2_2_id`),
INDEX `fk_t2_1_hs_t2_2_t2_21_idx` (`t2_2_id` ASC),
CONSTRAINT `fk_t2_1_hs_t2_2_t2_11`
FOREIGN KEY (`t2_1_id`)
REFERENCES `mydb`.`t2_1` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_t2_1_hs_t2_2_t2_21`
FOREIGN KEY (`t2_2_id`)
REFERENCES `mydb`.`t2_2` (`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;
IMO, talking in perspective of database design (not mysql workbench)
When using 1-n relation, we mean a not null foreign key inside cross table.
When using 1-1 relation, we mean a not null foreign key inside cross table that is the or part of a unique key of cross table.
Consider tables having these records:
T1_1(A1, B1, C1)
T2_1(A2, B2, C2)
In 1-n relation, we can have (A1, A2) multiple times in T1_has_T2 table
In 1-1 relation, we can not have (A1, A2) multiple times in T1_has_T2 table.
So Achieving 1-1 could be possible by putting foreign keys inside primary key or defining a unique key(index) on combination the foreign key columns.
So, I've recreated the issue I'm having with more readable code. I run this sql file in my mysql prompt:
CREATE SCHEMA IF NOT EXISTS test_schema
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE test_schema ;
-- -----------------------------------------------------
-- Table test_schema.table_one
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS table_one (
table_one_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
table_one_name VARCHAR(45) NOT NULL,
PRIMARY KEY (table_one_id, table_one_name)
)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table test_schema.table_two
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS table_two (
table_two_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
table_two_name VARCHAR(45) NOT NULL,
table_one_name VARCHAR(45) NOT NULL,
PRIMARY KEY (table_two_id)
)
ENGINE = InnoDB;
ALTER TABLE table_two ADD FOREIGN KEY (table_one_name) REFERENCES table_one(table_one_name);
The output I get from the prompt is:
mysql> source test-database.sql;
Query OK, 1 row affected (0.00 sec)
Database changed
Query OK, 0 rows affected (0.07 sec)
Query OK, 0 rows affected (0.08 sec)
ERROR 1005 (HY000): Can't create table 'test_schema.#sql-44c_2a' (errno: 150)
If I run 'SHOW ENGINE INNODB STATUS;' I get the following details
------------------------
LATEST FOREIGN KEY ERROR
------------------------
150603 9:22:25 Error in foreign key constraint of table test_schema/#sql-44c_2a:
FOREIGN KEY (table_one_name) REFERENCES table_one(table_one_name):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
I've searched for this issue and almost every one say that it's about:
1) Not having the same type
- They're both "VARCHAR(45) NOT NULL" (tried letting the one in table_two be null, didn't alter the error-message)
2) The foreign key not being a primary key
- table_one_name is a primary key in table_one together with table_one_id
3) Make sure that the Charset and Collate options are the same both at the table level
- What does this mean? I suppose they are since I don't change them?
Please help
// Finbel
In order to add a Foreign Key the two fields must be INDEXed.
Try this:
-- -----------------------------------------------------
-- Table test_schema.table_one
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS table_one (
table_one_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
table_one_name VARCHAR(45) NOT NULL,
PRIMARY KEY (table_one_id, table_one_name),
KEY `one_name` (`table_one_name`)
)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table test_schema.table_two
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS table_two (
table_two_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
table_two_name VARCHAR(45) NOT NULL,
table_one_name VARCHAR(45) NOT NULL,
PRIMARY KEY (table_two_id),
KEY `two_name` (`table_two_name`)
)
ENGINE = InnoDB;
ALTER TABLE table_two ADD FOREIGN KEY (table_one_name) REFERENCES table_one(table_one_name);