Can't add Foreign Key in MySQL with identical columns - mysql

I have two tables, each with a provider column:
CREATE TABLE `title` (
`provider` varchar(40) CHARACTER SET latin1 NOT NULL,
CREATE TABLE `notification` (
`provider` varchar(40) CHARACTER SET latin1 NOT NULL,
However, when I try and add a foreign key
ALTER TABLE notification ADD FOREIGN KEY (provider) REFERENCES title (provider)
I get the following obscure error:
Can't create table 'metadata.#sql-c91_345b' (errno: 150)
Both of the tables are empty. Why is this occurring and what do I need to do to fix this?

http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html says:
InnoDB requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan.
In the referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order.
Such an index is created on the referencing table automatically if it
does not exist.
(This is in contrast to some older versions, in which indexes had to
be created explicitly or the creation of foreign key constraints would
fail.) index_name, if given, is used as described previously.
I think you should create any (unique, primary, or plain) index for title.provider before creating a foreign key pointing to it.

Run SHOW ENGINE INNODB STATUS\G and look at the "LATEST FOREIGN KEY ERROR" to see more details on the error.

Related

Error "Cannot add foreign key constraint" without trying to create a foreign key

I have this Query:
CREATE TABLE `team` (
`id` int(11) NOT NULL
);
/* SQL Error (1215): Cannot add foreign key constraint */
which clearly does not contain a foreign key declaration. So all answers I am finding online are not for me. The reason this error occurs must have been related to a MySQL caching issue. Because the table existed previously and I deleted it. Thus, renaming the table name in the create table command to teams creates the table just fine.
My question is, where does mysql store this cache and how can I delete it. In information_schema I cannot find it. in information_schema.INNODB_TABLES the table is no longer listed.
Update 1
Before deleting the table team it was created with foreign keys, with:
CREATE TABLE `team` (
`id` int(11) NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`is_verified` tinyint(1) NOT NULL,
`uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '(DC2Type:guid)',
`foreign_uuid` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `team`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `UNIQ_C4E0A61FD17F50A6` (`uuid`);
But now the error occurs with just the first (very simple) query.
Update 2
I tried
mysql> FLUSH LOGS;
mysql> RESET MASTER;
to no avail.
Update 3
After restarting the mysql service the error changed more concrete to:
CREATE TABLE `team` (
`id` int(11) NOT NULL
);
/* SQL Error (1822): Failed to add the foreign key constraint. Missing index for constraint 'FK_6C66F57B296CD8AE' in the referenced table 'team' */
When you are disabling foreign_key_checks, it allows you to all kind of things, especially
Setting foreign_key_checks to 0 also affects data definition statements: [...] DROP TABLE drops tables that have foreign keys that are referred to by other tables.
That's what you (or someone you can blame) did.
When you recreate the table, you need to make sure that the referenced constraints are technically valid (even if you keep foreign_key_checks disabled):
When re-creating a table that was dropped, an error is returned if the table definition does not conform to the foreign key constraints referencing the table.
The exact error you get depends a bit on what version you are using, for MySQL 5.5 it would be Error Code: 1005. Can't create table 'tablename' (errno: 150), since MySQL 5.6, the error message is
SQL Error (1215): Cannot add foreign key constraint
So the problem here is that another table is referencing your table with a foreign key constraint, but the new table definition doesn't fit.
A fairly easy way to find the culprit is to use show engine innodb status, it will contain, amongst other things, useful details in the LATEST FOREIGN KEY ERROR section, including the foreign key definition and the name of table. Alternatively, and especially if you suspect to have more than one foreign key problem, have a look at How do I see all foreign keys to a table or column? (which is where MySQL stores that information, although it's not a cache that you can clear).
While you can include the referenced column into your new table, it doesn't look as if you intend to honor that constraint anymore, so you probably need to drop the referencing foreign key (or table).

SQL Error (1215): Cannot add foreign key constraint

CREATE TABLE `profilePic` (
`ClientID` VARCHAR(255) NOT NULL,
PRIMARY KEY (`ClientID`),
CONSTRAINT `FK__user_details` FOREIGN KEY (`ClientID`) REFERENCES `user_details` (`ClientID`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;
I am trying to add table with foreign key and I got this error, why that happend ?
trying doing new table.
i am trying to put same details on user_details->ClientID and profilePic->ClientID
3.i have already one table call`d userdb and in this table i have ClientID and its foreign key and its work.
The below will fail because the collation is different. Why do I show this? Because the OP didn't.
Note I shrunk the size due to error 1071 on sizing for varchar 255 with that collation and then auto chosen charset.
The point being, if collation is different, it won't work.
CREATE TABLE `user_details` (
`ClientID` VARCHAR(100) NOT NULL,
PRIMARY KEY (`ClientID`)
)ENGINE=InnoDB;
CREATE TABLE `profilePic` (
`ClientID` VARCHAR(100) NOT NULL,
PRIMARY KEY (`ClientID`),
CONSTRAINT `FK__user_details` FOREIGN KEY (`ClientID`) REFERENCES `user_details` (`ClientID`) ON UPDATE CASCADE ON DELETE CASCADE
)COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;
The above failure is at the table level. A trickier one causing a 1215 error due to column-level collation mismatches can be seen in This answer.
Pulling the discussion up to more general cases ...
whether you are trying to establish a Foreign Key constraint on table creation or with ALTER TABLE
| ADD [CONSTRAINT [symbol]]
FOREIGN KEY [index_name] (index_col_name,...)
reference_definition
such as
ALTER TABLE `facility` ADD CONSTRAINT `fkZipcode`
FOREIGN KEY (`zipcode`) REFERENCES `allzips`(`zipcode`);
the following will apply.
From the MySQL manual page entitled Using FOREIGN KEY Constraints:
Corresponding columns in the foreign key and the referenced key must
have similar data types. The size and sign of integer types must be
the same. The length of string types need not be the same. For
nonbinary (character) string columns, the character set and collation
must be the same.
In addition, the referenced (parent) table must have a left-most key available for fast lookup (verification). That parent key does not need to be PRIMARY or even UNIQUE. This concept is described in the 2nd chunk below. The first chunk alludes to a Helper index that will be created if necessary in the referencing (child) table if so necessary.
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
InnoDB permits a foreign key to reference any column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
When trying to create a foreign key via HeidiSQL, you get a warning as soon as the selected column data types don't match. I added this warning to HeidiSQL's table designer due to the non-intuitive message from the server ("Cannot add foreign key constraint")
The selected foreign column do not match the source columns data type and unsigned flag. This will give you an error message when trying to save this change. Please compare yourself:

Unable to add two foreign keys to a table

I have two tables as follow:
1st Table:
CREATE TABLE User (
User_ID VARCHAR(8)NOT NULL PRIMARY KEY,
User_Name VARCHAR (25) NOT NULL,
User_Gender CHAR (1) NOT NULL,
User_Position VARCHAR (10) NOT NULL,
);
2nd table:
CREATE TABLE Training (
Training_Code VARCHAR(8) NOT NULL Primary Key,
Training_Title VARCHAR(30) NOT NULL,
);
I am trying to create a table which has two foreign keys to join both of the previous tables:
CREATE TABLE Request (
User_ID VARCHAR(8) NOT NULL,
Training_Code VARCHAR(8) NOT NULL,
Request_Status INT(1) NOT NULL
);
When I am trying to set the foreign keys in the new table, the User_ID can be done successfully but the Training_Code cannot be set to foreign key due to the error:
ERROR 1215 (HY000): Cannot add foreign key constraint
As I searched for this problem, the reason for it, is that data type is not the same, or name is not the same.. but in my situation both are correct so could you tell me what is wrong here ?
You need an index for this column in table Request too:
Issue first
CREATE INDEX idx_training_code ON Request (Training_Code);
Then you should be successful creating the foreign key constraint with
ALTER TABLE Request
ADD CONSTRAINT FOREIGN KEY idx_training_code (Training_Code)
REFERENCES Training(Training_Code);
It worked for me. But I've got to say that it worked without create index too, as the documentation of Using FOREIGN KEY Constraints states:
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
Emphasis by me. I don't know what's the issue in your case.
Demo
Explanation of the issue
The behavior mentioned in the question can be reproduced if the table Training is using the MyISAM storage engine. Then creating a foreign key referencing the table Training will produce the mentioned error.
If there's data in the table, then simple dropping of the table would not be the best solution. You can change the storage engine to InnoDB with
ALTER TABLE Training Engine=InnoDB;
Now you can successfully add the foreign key constraint.

Supports transactions, row-level locking, and foreign keys

For some reason I cannot create this table:
CREATE TABLE user_role (
user_id VARCHAR(20) NOT NULL,
role_id INTEGER UNSIGNED NOT NULL,
FOREIGN KEY (user_id)
REFERENCES users(user_id),
FOREIGN KEY (role_id)
REFERENCES roles(role_id)
);
The following similar table has no problems:
CREATE TABLE role_perm (
role_id INTEGER UNSIGNED NOT NULL,
perm_id INTEGER UNSIGNED NOT NULL,
FOREIGN KEY (role_id)
REFERENCES roles(role_id),
FOREIGN KEY (perm_id)
REFERENCES permissions(perm_id)
);
The error message I'm getting is:
#1005 - Can't create table 'test.user_role' (errno: 150) (Details...)
Supports transactions, row-level locking, and foreign keys
Any ideas?
See http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
If you re-create a table that was dropped, it must have a definition that conforms to the foreign key constraints referencing it. It must have the correct column names and types, and it must have indexes on the referenced keys, as stated earlier. If these are not satisfied, MySQL returns Error 1005 and refers to Error 150 in the error message, which means that a foreign key constraint was not correctly formed.
If is rather difficult to guess as you didn't provide the definitions for the roles and permissions tables but to paraphrase the doc...
...in order to have a foreign key on a column, you must have an index on the "target" column.
...in order to have a foreign key on a column, both "source" and "target" columns must have the same type (incl. the same size if applicable).
...in order to have a foreign key on a column, both tables must use InnoDB engine.
For my case, I handle several databases, when I try to create the table it returned this error "transactions, row-level locking, and foreign keys", the error occurred because the relationship table did not exist,
casually it recognized it from another database where the table did exist, but i have only creating the relationship table to solve the problem.
I took into account the recommendations of relations given in this forum because it also has to do with the version of MySql.

Failure in using alter table to add partition

I have a table having structure as below:
CREATE TABLE `child_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`value` int,
`ref_id` int,
PRIMARY KEY (`id`),
KEY `ref_id` (`ref_id`),
CONSTRAINT `FK4E9BF08E940F8C98` FOREIGN KEY (`ref_id`) REFERENCES `parent_table` (`id`) ON DELETE CASCADE
)
When running statement to add partition, it fails and show the error:
ERROR 1217: Cannot delete or update a parent row: a foreign key constraint fails
SQL Statement:
ALTER TABLE `learning`.`child_table` PARTITION BY HASH(ref_id) PARTITIONS 10
So I remove the foreign constraint with parent_table, then run again. It still fails and show the same error.
Did I do anything wrong?
I know this is an old question, but for people that fall here from looking for this problem, since its the first Google result:
MySQL does not support foreign keys on partitioned tables.
From the manual
Foreign keys not supported for partitioned InnoDB tables. Partitioned tables using the InnoDB storage engine do not support foreign keys. More specifically, this means that the following two statements are true:
No definition of an InnoDB table employing user-defined partitioning may contain foreign key references; no InnoDB table whose definition contains foreign key references may be partitioned.
No InnoDB table definition may contain a foreign key reference to a user-partitioned table; no InnoDB table with user-defined partitioning may contain columns referenced by foreign keys.
The error is referring to a foreign key on another table that references child_table. You need to find and remove the foreign key from that table, not necessarily child_table. You could also try running SET foreign_key_checks = 0 first.