FK constraint is incorrectly formed ERROR - mysql

I got the following error message whenever I try to import this sql file to my localhost
(#1005 - Can't create table hostel_management_system.Hostel_Manager (errno: 150 "Foreign key constraint is incorrectly formed"))
Here is the sql:
DROP TABLE IF EXISTS `Hostel_Manager`;
CREATE TABLE `Hostel_Manager` (
`Hostel_man_id` int(10) NOT NULL AUTO_INCREMENT,
`Username` varchar(255) NOT NULL,
`Fname` varchar(255) NOT NULL,
`Lname` varchar(255) NOT NULL,
`Mob_no` varchar(255) NOT NULL,
`Hostel_id` int(10) NOT NULL,
`Pwd` LONGTEXT NOT NULL,
`Isadmin` tinyint(1) DEFAULT '0',
PRIMARY KEY (`Hostel_man_id`),
UNIQUE (`Username`),
KEY `Hostel_id` (`Hostel_id`),
CONSTRAINT `Hostel_Manager_ibfk_1` FOREIGN KEY (`Hostel_id`) REFERENCES `Hostel` (`Hostel_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
LOCK TABLES `Hostel_Manager` WRITE;
UNLOCK TABLES;
Hostel table :
CREATE TABLE `Hostel` (
`Hostel_id` int(10) NOT NULL AUTO_INCREMENT,
`Hostel_name` varchar(255) NOT NULL,
`current_no_of_rooms` varchar(255) DEFAULT NULL,
`No_of_rooms` varchar(255) DEFAULT NULL,
`No_of_students` varchar(255) DEFAULT NULL,
PRIMARY KEY (`Hostel_id`)
)
Why do I get that error and how to fix it?

Both the parent and children column have the same datatype and length, and the parent column is a primary colum, so that's not the issue here.
I suspect that the problem is the charset. Hostel_Manager specifies a default charset, while Hostel does not. If the default charset of your database is something else than latin1, then the foreign is malformed.
I would recommend explictly aligning the charset so it is the same for both tables (either remove both, or declare the same value).
Note that both tables also need to have the same storage engine. InnoDB is the default, so that should not be an issue, but you might want to explictly align that as well (in case the default of your database is MyISAM).

Related

Create a relationship between the tables when the table is first created

I use mysql
in my database
I want to create multiple tables with delete and update relationship
as an example
I want to link the profiles table to the users table
Associate the mm_id_user column from the users table with the mm_id_profile column from the profiles table
What I actually tried to do is this example and it didn't work for me
https://stackoverflow.com/a/260453/10206991
https://stackoverflow.com/a/9796950/10206991
The code used to create the users table and it succeeds in creating the table
CREATE TABLE users (
mm_email VARCHAR(255) NOT NULL,
mm_id_user int NOT NULL AUTO_INCREMENT,
mm_name VARCHAR(25) NOT NULL,
mm_password VARCHAR(255) NOT NULL,
mm_code_reset_pass VARCHAR(100) NOT NULL,
mm_code_check_email VARCHAR(100) NOT NULL,
mm_status CHAR(1) NOT NULL DEFAULT '0',
mm_date_create_account TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
mm_date_last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
mm_is_login CHAR(1) NOT NULL DEFAULT '0',
PRIMARY KEY (mm_id_user, mm_email)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE utf8_unicode_ci;
The code used to create the profiles table. He failed to create the table
CREATE TABLE profiles (
mm_id_profile VARCHAR(255) NOT NULL,
mm_image_user TEXT NOT NULL,
mm_num_stores_all VARCHAR(4) NOT NULL,
mm_num_stores_exist VARCHAR(4) NOT NULL,
mm_name_public VARCHAR(25) NOT NULL,
mm_email_public VARCHAR(255) NOT NULL,
mm_phone_public VARCHAR(20) NOT NULL,
mm_location_public TEXT NOT NULL,
mm_update_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX index_profiles(mm_name_public, mm_email_public),
PRIMARY KEY (mm_id_profile),
FOREIGN KEY (mm_id_profile) REFERENCES users(mm_email) ON DELETE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE utf8_unicode_ci;
But if you remove the following line from the profiles table, it will be created
But there is definitely no relationship between the two tables
FOREIGN KEY (mm_id_profile) REFERENCES users(mm_email) ON DELETE CASCADE
This is the error message that appears when creating a profiles table
#1005 - Can't create table `mustforu_test`.`profiles` (errno: 150 "Foreign key constraint is incorrectly formed") (Details…)
There's no reason to put both mm_id_user and mm_email in the primary key of users. If you want emails to be unique, it should have its own unique index. Your current primary key would allow duplicate emails with different IDs.
CREATE TABLE users (
mm_email VARCHAR(255) NOT NULL,
mm_id_user int NOT NULL AUTO_INCREMENT,
mm_name VARCHAR(25) NOT NULL,
mm_password VARCHAR(255) NOT NULL,
mm_code_reset_pass VARCHAR(100) NOT NULL,
mm_code_check_email VARCHAR(100) NOT NULL,
mm_status CHAR(1) NOT NULL DEFAULT '0',
mm_date_create_account TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
mm_date_last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
mm_is_login CHAR(1) NOT NULL DEFAULT '0',
PRIMARY KEY (mm_id_user),
UNIQUE KEY (mm_email)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE utf8_unicode_ci;
Giving mm_email its own index will allow the foreign key in profiles to work.

MYSQL - foreign key varchar column

I would like to add localization to my database. I created languages table and I would like to add foreign key to user table:
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`name` varchar(30) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(60) DEFAULT NULL,
`registrationDate` datetime DEFAULT current_timestamp(),
`lastLoginDate` datetime DEFAULT NULL,
`isConfirmed` tinyint(1) NOT NULL DEFAULT 0,
`activationKey` varchar(32) NOT NULL,
`resendEmail` tinyint(1) DEFAULT NULL,
`subscribedNews` tinyint(1) NOT NULL DEFAULT 1,
`activated` tinyint(1) DEFAULT 1,
`lang` varchar(5) NOT NULL DEFAULT 'en'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `users`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `email` (`email`);
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
create table languages(
code varchar(5) primary key,
name varchar(255) not null,
dateFormat varchar(255),
dateTimeFormat varchar(255),
currency varchar(255)
);
ALTER TABLE users
ADD lang varchar(5) NOT NULL DEFAULT 'cs';
ALTER TABLE users ADD CONSTRAINT fk_user_lang FOREIGN KEY (lang) REFERENCES languages(code);
I can't add foreign key on lang column:
error code: 150 "Foreign key constraint is incorrectly formed"
Why I can't create varchar foreign key. I would not add int primary key in languages table, because, I would like to get data from database as /api/users/cs instead of /api/users?lang=1.
Thanks
You didn't specify the character set or collation for the languages table.
Whereas users is explicitly utf8, you might be using a MySQL version where the default charset is utf8mb4 or a very old version where the default charset is latin1.
Double-check with:
SHOW CREATE TABLE languages\G
That will display the charset and collation for that table. It must be the same as the charset and collation for the foreign key column in users.
If you change the default character set of the table languages to utf8, which you defined for the table users, then it will work:
ALTER TABLE languages CONVERT TO CHARACTER SET utf8;
See the demo.

Foreign key rejected despite columns having different data types

I'm trying to set up two tables in a database, and add a foreign key between them. They're declared as follows:
CREATE TABLE `clothing` (
`name` varchar(26) COLLATE utf8_bin NOT NULL,
`image` varchar(64) COLLATE utf8_bin NOT NULL,
`localized_name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`localized_name`)),
`main` varchar(18) COLLATE utf8_bin DEFAULT NULL,
`stars` tinyint(3) unsigned NOT NULL,
`id` tinyint(3) unsigned NOT NULL,
`splatnet` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`splatnet`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `abilities` (
`name` varchar(18) COLLATE utf8_bin DEFAULT NULL,
`image` varchar(48) COLLATE utf8_bin NOT NULL,
`id` tinyint(3) unsigned NOT NULL,
`localized_name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`localized_name`))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
I want to create a foreign key on clothing that references abilities with the following command:
ALTER TABLE `abilities` ADD FOREIGN KEY (`name`) REFERENCES `clothing` (`main`);
However, attempting to do this raises this error in return:
Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.
Can't create table `prismarine_rusted`.`abilities` (errno: 150 "Foreign key constraint is incorrectly formed")
I'm not entirely sure what's causing this, and unless I'm overlooking something really obvious, main and name have the same type, and therefore, should be able to be tied together via a foreign key. I'm using MariaDB v10.4.12, with SQL mode set to TRADITIONAL.
Although the foreign and primary key columns involved here are the same type, you are trying to reference clothing.main, which is not a unique or primary key column. From the MariaDB documentation:
The referenced columns must be a PRIMARY KEY or a UNIQUE index.
Note that this differs from InnoDB on MySQL, where a foreign key column can in fact reference a non unique column in another table.
One way to remedy this error would be to make clothing.main a unique column:
ALTER TABLE clothing ADD UNIQUE (main);
Note that doing this might only make logical sense if the values in main are already unique. If not, then perhaps you would have to revisit your data model.
It might be because there is a value in abilities.name that has no match in the referenced table.

How do I solve the MySQL error where I Cannot add foreign key constraint because of ERROR 1215?

This is my first table.
CREATE TABLE `raw_orders` (
`row_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`order_id` VARCHAR(45) COLLATE utf8mb4_unicode_ci NOT NULL,
`order_revenue` FLOAT NOT NULL,
PRIMARY KEY(`row_id`),
KEY(`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
This is my second table
CREATE TABLE `formatted_orders` (
`order_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`client_order_id` VARCHAR(50) COLLATE utf8mb4_general_ci NOT NULL,
`order_revenue` FLOAT NOT NULL,
PRIMARY KEY(`order_id`),
KEY(`client_order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
I am trying to add foreign key in formatted_orders linking it to raw_orders by using this
ALTER TABLE formatted_orders
ADD FOREIGN KEY (client_order_id) REFERENCES raw_orders(order_id);
But I get this error
ERROR (HY000): Cannot add foreign key constraint
You can simply add a foreign key in the table formatted_orders like this:
CREATE TABLE `formatted_orders` (
`order_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`client_order_id` VARCHAR(50) COLLATE utf8mb4_general_ci NOT NULL,
`order_revenue` FLOAT NOT NULL,
PRIMARY KEY(`order_id`),
FOREIGN KEY (`client_order`) REFERENCES raw_orders(`order_id`)
)
The reason you cannot add the constraint is because you specify different collations for the columns in the two tables. Also, the columns should be the same size, although MySQL will let you create the constraint even if they're not.
Change to the same collation (COLLATE utf8mb4_unicode_ci for instance) for both columns and it will work.
See this SQL Fiddle for an example.
The MySQL documentation states that:
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.

MySQL 5.5 add foreign key fails with errors [HY000][150] and [HY000][1005]

I have tried adding a foreign key like this...
ALTER TABLE OrderLineItem
ADD CONSTRAINT
FK_OrderLineItem_ShippingType_name FOREIGN KEY
(shippingType)
REFERENCES ShippingType(name);
Or like this in Mysql 5.5...
alter table OrderLineItem add foreign key
FK_OrderLineItem_ShippingType (shippingType) references ShippingType(name);
Every time I see the following error.
[2011-11-18 15:07:04] [HY000][150] Create table
'realtorprint_dev_dev/#sql-7d0_80' with foreign key constraint failed.
There is no index in the referenced table where the referenced columns
appear as the first columns.
[2011-11-18 15:07:04] [HY000][1005] Can't create table
'realtorprint_dev_dev.#sql-7d0_80' (errno: 150)
Both OrderLineItem.shippingType and ShippingType.name have a type of varchar(50) not null. ShippingType.name is the primaryKey of ShippingType.
Here is the result of show create table on ShippingType as well as OrderLineItem...
CREATE TABLE `shippingtype` (
`name` varchar(50) CHARACTER SET latin1 NOT NULL DEFAULT '',
`description` varchar(255) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `orderlineitem` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`description` varchar(255) CHARACTER SET latin1 NOT NULL,
`lineNumber` int(11) NOT NULL,
`quantity` int(11) NOT NULL,
`quantityMultiplier` int(11) NOT NULL,
`unitPrice` decimal(10,2) NOT NULL,
`order_id` bigint(20) NOT NULL,
`productDefinition_id` bigint(20) NOT NULL,
`mlsId` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`printProviderUnitCost` decimal(10,2) NOT NULL,
`shippingType` varchar(50) NOT NULL,
`address` varchar(255) DEFAULT NULL,
`zipPostal` varchar(255) NOT NULL,
`city` varchar(255) NOT NULL,
`stateProvince` varchar(255) NOT NULL,
`country` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_OrderLineItem_productDefinition_id` (`productDefinition_id`),
KEY `idx_OrderLineItem_order_id` (`order_id`),
CONSTRAINT `FK_OrderLineItem_order_id` FOREIGN KEY (`order_id`) REFERENCES `userorder` (`id`),
CONSTRAINT `FK_OrderLineItem_productDefinition_id` FOREIGN KEY (`productDefinition_id`) REFERENCES `productdefinition` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10029 DEFAULT CHARSET=utf8;
It is possible is that Mysql gives this bad error when the column types do not match exactly - check collation / size etc.
orderLineItem.shippingType has character set utf8, but ShippingType.name has character set latin1. These are not compatible for the purposes of foreign key references.
Data type mismatches or PK not declared properly on referenced based tables.