-- Table Project_DB.Product_table
CREATE TABLE IF NOT EXISTS `Project_DB`.`Product_table`
(
`Product_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`User_id_fk` INT UNSIGNED NOT NULL ,
`Product_Category_id` INT UNSIGNED NOT NULL ,
`Product_Name` VARCHAR( 45 ) NOT NULL ,
`Product_Price` INT UNSIGNED NOT NULL ,
`Product_details` MEDIUMTEXT NULL ,
PRIMARY KEY ( `Product_id` ) ,
INDEX `User_id_idx` ( `User_id_fk` ASC ) ,
CONSTRAINT `User_id` FOREIGN KEY ( `User_id_fk` )
REFERENCES `Project_DB`.`Registration_table` ( `User_id` )
ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = INNODB;
MySQL said: Documentation
#1022 - Can't write; duplicate key in table 'product_table'
The Database Schema Cannot have two or more FOREIGN KEY with same name. I change all FOREIGN KEYS to different names in my DB Schema then it works...
I recommend you try removing the line
INDEX `User_id_idx` ( `User_id_fk` ASC ) ,
Either that, or remove the foreign key constraint from the table definition, and add that in a separate ALTER TABLE statement.
InnoDB automatically creates the required index when a foreign key constraint is added, or uses a suitable index if it's already there.
I believe the error is occurring because InnoDB is attempting to create an index for the foreign key, rather than using the index that was defined previously. That is, when the CREATE TABLE statement (as posted by OP) is processed, InnoDB is attempting to create both the index defined on User_id_fk, and the index required for the foreign key.
And those two indexes are "duplicates" of each other.
The workaround is to modify the CREATE TABLE statement, to avoid InnoDB attempting to create "duplicate" indexes.
I had the same problem, MySQLWorkbench was working fine when I forward engineered a build script and then it decided to throw it's toys out of the pram.
I fixed the problem by dropping my database in phpMyAdmin and then ran the script again from MySQLWorkbench and it worked. I suspect I'd changed something that caused a conflict.
I know this is an extreme measure; others have said, to go through the DB schema and find duplicates.
Usually, you already use that constraint in another table that you also use for foreign key.
Related
CREATE TABLE hoofdtoonder
(
id INT NOT NULL,
idondersoorten INT FOREIGN KEY REFERENCES `ondersoort`(`id`) NOT NULL,
)
//making table but the error is with the references its on a mysql database someone please help
It says error at FOREIGN KEY REFERENCES ondersoort(id) NOT NULL. But I don't know what's wrong with the syntax.
There are several things wrong here:
First, for an inline constraint, you don't need to specify foreign key, just references.
The not null clause should come before the references clause.
You have a redundant comma at the end of the last column's specification.
To put it all together:
CREATE TABLE hoofdtoonder (
id INT NOT NULL,
idondersoorten INT NOT NULL REFERENCES `ondersoort`(`id`)
);
MySQL does not support inline foreign key references.
It's true that the SQL language allows for syntax like #Mureinik suggested:
idondersoorten INT NOT NULL REFERENCES `ondersoort`(`id`)
But you will find that MySQL parses this and ignores it. InnoDB does not support inline foreign key syntax. If you now run SHOW CREATE TABLE hoofdtoonder, it'll show this:
CREATE TABLE `hoofdtoonder` (
`id` int(11) NOT NULL,
`idondersoorten` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Where did the REFERENCES go? It was silently discarded. This is actually a beef I have with MySQL, that it recognizes some valid constraint syntax, but ignores it. It doesn't even show you a warning. It just defines the table without the constraint.
In MySQL, you must declare a foreign key as a table-level constraint, like this:
CREATE TABLE hoofdtoonder (
id INT NOT NULL,
idondersoorten INT NOT NULL,
FOREIGN KEY (idondersoorten) REFERENCES `ondersoort`(`id`)
);
Here is the exact SQL I attempt to execute (using SQLYog as a MySQL client on Windows):
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` INT (11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE = INNODB ;
DROP TABLE IF EXISTS `temp`;
CREATE TEMPORARY TABLE `temp` (
dish_id INT (11) NOT NULL,
user_id INT (11) NOT NULL,
UNIQUE KEY (dish_id, user_id),
FOREIGN KEY `test` (dish_id) REFERENCES test (id)
) ENGINE = INNODB ;
Here is the exact error received upon the attempt to create temp:
Error Code: 1215
Cannot add foreign key constraint
It looks to me like everything is in order - the data type and signed-ness of the two related keys is the same; the names appear to be kosher; what is going on?
What am I doing wrong? Why is the foreign key constraint failing to be created?
It's because you're trying to add a foreign key constraint to a temporary table.
From the manual:
Foreign key relationships involve a parent table that holds the
central data values, and a child table with identical values pointing
back to its parent. The FOREIGN KEY clause is specified in the child
table. The parent and child tables must use the same storage engine.
They must not be TEMPORARY tables.
http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html
EDIT:
Try it with a permanent table. It works.
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` INT (11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE = INNODB ;
DROP TABLE IF EXISTS `temp`;
CREATE TABLE `temp` (
dish_id INT (11) NOT NULL,
user_id INT (11) NOT NULL,
UNIQUE KEY (dish_id, user_id),
FOREIGN KEY `test` (dish_id) REFERENCES test (id)
) ENGINE = INNODB ;
I'm creating a few simple tables and I can't get passed this foreign key error and I'm not sure why. Here's the script below.
create TABLE Instructors (
ID varchar(10),
First_Name varchar(50) NOT NULL,
Last_Name varchar(50) NOT NULL,
PRIMARY KEY (ID)
);
create table Courses (
Course_Code varchar(10),
Title varchar(50) NOT NULL,
PRIMARY KEY (Course_Code)
);
create table Sections (
Index_No int,
Course_Code varchar(10),
Instructor_ID varchar(10),
PRIMARY KEY (Index_No),
FOREIGN KEY (Course_Code) REFERENCES Courses(Course_Code)
ON DELETE cascade
ON UPDATE cascade,
FOREIGN KEY (Instructor_ID) REFERENCES Instructors(ID)
ON DELETE set default
);
Error Code: 1005. Can't create table '336_project.sections' (errno: 150)
My data types seem identical and the syntax seems correct. Can anyone point out what I'm not seeing here?
I'm using MySQL Workbench 5.2
This error also occurs if you are relating columns of different types, eg. int in the source table and BigInt in the destination table.
If you're using the InnoDB engine, the ON DELETE SET DEFAULT is your problem. Here's an excerpt from the manual:
While SET DEFAULT is allowed by the MySQL Server, it is rejected as invalid by InnoDB. CREATE TABLE and ALTER TABLE statements using this clause are not allowed for InnoDB tables.
You can use ON DELETE CASCADE or ON DELETE SET NULL, but not ON DELETE SET DEFAULT. There's more information here.
You can run
SHOW ENGINE INNODB STATUS
to read the reason of the failure in a human readable format
e.g.
------------------------
LATEST FOREIGN KEY ERROR
------------------------
150331 15:51:01 Error in foreign key constraint of table foobar/#sql-413_81:
FOREIGN KEY (`user_id`) REFERENCES `foobar`.`users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE:
You have defined a SET NULL condition though some of the columns are defined as NOT NULL.
In order to create a FOREIGN KEY with reference to another table, the keys from both tables should be PRIMARY KEY and with the same datatype.
In your table sections, PRIMARY KEY is of different datatype i.e INT but in another table, it's of type i.e VARCHAR.
It may also be the case if you are not specifying the ON DELETE at all but are trying to reference a MYISAM table from InnoDB table:
CREATE TABLE `table1`(
`id` INT UNSIGNED NOT NULL,
`name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MYISAM CHARACTER SET UTF8;
CREATE TABLE `table2`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`table1_id` INT UNSIGNED NOT NULL,
`some_value` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_table1_id`(`table1_id`),
CONSTRAINT FOREIGN KEY (`table1_id`) REFERENCES `table1`(`id`)
) ENGINE=INNODB CHARACTER SET UTF8;
The above will throw errno 150. One need to change the first table to InnoDB too for this to work.
It is failing on the
ON DELETE set default
I have not come across that before and I am not seeing it in the manuals either ( but then it is late )
Update
just seen this in the manual
While SET DEFAULT is allowed by the MySQL Server, it is rejected as
invalid by InnoDB. CREATE TABLE and ALTER TABLE statements using this
clause are not allowed for InnoDB tables.
I guess you may be using InnoDB tables ?
For completeness sake - you will also get this error if you make a foreign reference to a table that isn't defined at the time;
Here Problem is in database engine ( table1 MYISAM and table2 ENGINE).
To set FOREIGN KEYs,
Both table must be in same ENGINE and same charset.
PK column in parent and FK column must be in same data type and same collation type.
Hope you got an idea.
Make sure that table type is InnoDB, MyISAM does not support foreign key, afaik.
I'm recreating this database (that I had originally made from django modelw) on an Amazon EC2 instance. I used MySQL workbench to translate the database into a mockup, and then had it forward-engineer it to all the CREATE statements in a .sql file. However some of the foreign key stuff is named really strangely, and I'm not sure what parts I can take out or rename and what parts are necessary. Here's a sample of the code that I'm talking about.
CREATE TABLE IF NOT EXISTS `gamelydb`.`quotes` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`game_id` INT(11) NOT NULL ,
`quotetext` VARCHAR(400) NOT NULL ,
`speaker_id` INT(11) NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `quotes_7b333d1e` (`game_id` ASC) ,
INDEX `quotes_7171bad0` (`speaker_id` ASC) ,
CONSTRAINT `game_id_refs_id_274910a8`
FOREIGN KEY (`game_id` )
REFERENCES `gamelydb`.`game` (`id` ),
CONSTRAINT `speaker_id_refs_id`
FOREIGN KEY (`speaker_id` )
REFERENCES `gamelydb`.`person` (`id` ))
ENGINE = InnoDB DEFAULT CHARACTER SET = latin1;
So like where it has "INDEX 'quotes_randomstuff'" or 'speaker_id_refs_id', do I need all the random stuff or what should I rename it to for clarity's/practicality's sake?
According to this you probably need it. It's an ID.
I have two tables. On is a table that contains IP Ranges and their respective country attributions (IPGEO table). The other is a table which simply keeps track of the last country the site was accessed from on a per user basis. The idea is that, if the user suddenly accesses the site from another country, I notify the user about this via email.
Now for the actual tables. I have these two:
The IPGeo table that contains the IP ranges
CREATE TABLE IF NOT EXISTS `politiker_lu`.`IPGeo` (
`IPFrom` INT(11) NOT NULL ,
`IPTo` INT(11) NOT NULL ,
`code2` VARCHAR(2) NOT NULL ,
`code3` VARCHAR(3) NOT NULL ,
`Country` VARCHAR(45) NOT NULL ,
INDEX `index1` (`IPFrom` ASC) ,
INDEX `index2` (`IPTo` ASC) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
Then, there is the user_geo table that tracks the last country from which the user accessed the site.
CREATE TABLE IF NOT EXISTS `politiker_lu`.`user_geo` (
`fi_user` INT(10) UNSIGNED NOT NULL ,
`fi_country` VARCHAR(3) NOT NULL ,
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ,
PRIMARY KEY (`fi_user`) ,
INDEX `fk_user_geo_1` (`fi_user` ASC) ,
CONSTRAINT `fk_user_geo_1`
FOREIGN KEY (`fi_user` )
REFERENCES `politiker_lu`.`user` (`id_user` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
These are the tables as they exist. I now want to reference these two tables as follows:
ALTER TABLE `politiker_lu`.`user_geo`
ADD CONSTRAINT `fk_user_geo_IPGeo1`
FOREIGN KEY (`fi_country` )
REFERENCES `politiker_lu`.`IPGeo` (`code3` )
ON DELETE CASCADE
ON UPDATE CASCADE
, ADD INDEX `fk_user_geo_IPGeo1` (`fi_country` ASC) ;
That Statement however fails with errno 150. Both tables are utf8, both columns have the same data-type. Am I missing something vital here?
Notes
The table user exists and has all the references and is actually irrelevant to the problem. I left it so that I didn't need to edit the statement too much.
You need to add a unique index or a primary key on the IPGeo.code3 column in order to reference it with a foreign key.
You can see the error by running show engine innodb status\G and looking under the LATEST FOREIGN KEY ERROR section. The error probably looks something like this:
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.1/en/innodb-foreign-key-constraints.html
for correct foreign key definition.