I am trying to import a file *.sql from MySQL database on my server backup to new webhosting. I try to import via phpMyAdmin. I tried running XAMPP on local machine and import and am still getting the same error. Here is the create table statement:
CREATE TABLE `yv3nd_rokgallery_file_loves` (
`file_id` int(10) unsigned NOT NULL DEFAULT '0',
`kount` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`file_id`),
UNIQUE KEY `file_id` (`file_id`),
CONSTRAINT `yv3nd_file_loves_file_id_files_id` FOREIGN KEY (`file_id`)
REFERENCES `yv3nd_rokgallery_files` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I got: #1005 - Can't create table 'test.yv3nd_rokgallery_file_loves' (errno: 150)
I'm pretty new to this so any help to fix this error would be appreciated.
Here is more code:
CREATE TABLE yv3nd_rokgallery_files(
id int(10) unsigned NOT NULL AUTO_INCREMENT,
filename varchar(255) NOT NULL,
guid char(36) NOT NULL,
md5 char(32) NOT NULL,
title varchar(200) NOT NULL,
description text,
license varchar(255) DEFAULT NULL,
xsize int(10) unsigned NOT NULL,
ysize int(10) unsigned NOT NULL,
filesize int(10) unsigned NOT NULL,
type char(20) NOT NULL,
published tinyint(1) NOT NULL DEFAULT '0',
created_at datetime NOT NULL,
updated_at datetime NOT NULL,
slug varchar(255) DEFAULT NULL,
PRIMARY KEY (id), UNIQUE KEY id (id),
UNIQUE KEY guid (guid),
UNIQUE KEY yv3nd_files_sluggable_idx (slug),
KEY yv3nd_rokgallery_files_published_idx (published),
KEY yv3nd_rokgallery_files_md5_idx (md5),
KEY yv3nd_rokgallery_files_guid_idx (guid))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
The errno 150 usually means that the foreign key constraint can't be created. Without seeing the rest of the file it is hard to say for sure, but I would guess that it is one of two things:
Your yv3nd_file_loves_file_id_files_id constraint may have been defined in another table as well. You can't create two constraints with the same name, that could potentially throw an error.
Another possibility is that you are creating a constraint on incorrect types. In this table your field_id is int(10). If in the yv3nd_rokgallery_files table your id variable is anything but that this will fail. For example: if in the other table it's int(9) this won't work.
If neither of these are correct, can you post the code for the yv3nd_rokgallery_files table?
EDIT
A third possibility is that the id field in the other table is not set as the primary key. This will also cause an error, because the foreign key of one table should match the primary key of another.
EDIT 2
Another possibility could be that you are creating the file_loves table before the files table. That would cause an error because you'd be creating a reference to a table that does not exist yet.
Errno 150 is what is reported if the FOREIGN KEY couldn't work.
The most common reason is that the data type of the foreign key column is different from the data type of the primary key column it references.
Your foreign key column is file_id int unsigned. The argument 10 for int(10) doesn't matter in this case. It's still an int unsigned.
Your primary key column is in table yv3nd_rokgallery_files, column id. You should double-check that that column is int unsigned. If it isn't, for example if it's a bigint or other size of int, or if it's not unsigned like file_id is, then the you'll get errno 150.
You must change one of the columns, either yv3nd_rokgallery_file_loves.file_id or yv3nd_rokgallery_files.id, so they use the same data type.
The errno 150 can also happen if the foreign key fails for other reasons. For example, table yv3nd_rokgallery_files must be an InnoDB table. Is it MyISAM?
Related
I have the following tables and I am trying to run them in MySQL but I keep getting an errno 150. Just not sure why, but MySQL cannot seem to create the foreign key constraint. I have already looked at the rules for setting FKs for InnoDB and everything seems ok. Could someone please lend me another set of eyes and expertise?
-- Table publication_type (parent table)
CREATE TABLE publication_type (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
publication_type varchar(55) NOT NULL,
tstamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT publication_type_pk PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
-- Table publication (child table)
CREATE TABLE publication (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
authors varchar(255) NOT NULL,
publication_title varchar(100) NOT NULL,
publication_type_id int(11) UNSIGNED NOT NULL,
user_id int(11) UNSIGNED NOT NULL,
CONSTRAINT publication_pk PRIMARY KEY (id),
CONSTRAINT publication_type_fk FOREIGN KEY (publication_type_id) REFERENCES publication_type(id) ON DELETE SET NULL ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
The types do not match:
publication_type.id is of type int UNSIGNED
publication.publication_type_id is of type int
See also the docs: http://dev.mysql.com/doc/refman/5.1/en/create-table-foreign-keys.html, specifically:
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.
emphasis mine.
I have defined the following 2 tables:
record_status
SHOW CREATE TABLE record_status
CREATE TABLE `record_status` (
`record_status_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status` char(6) NOT NULL,
`status_description` varchar(15) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`record_status_id`,`status`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
user
SHOW CREATE TABLE user
CREATE TABLE `user` (
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`handle` varchar(45) NOT NULL,
`email` varchar(255) NOT NULL,
`password` char(64) DEFAULT NULL,
`password_salt` binary(1) DEFAULT NULL,
`first_name` varchar(50) NOT NULL,
`last_name` varchar(50) NOT NULL,
`gender` char(1) DEFAULT NULL,
`birthday` date NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_status` char(6) DEFAULT NULL,
PRIMARY KEY (`user_id`),
KEY `usr_status_idx` (`user_status`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
and I tried adding the foreign key user_status of type CHAR using mysql Workbench as follows:
ALTER TABLE `mydatabase`.`user`
ADD CONSTRAINT `usr_status`
FOREIGN KEY (`user_status`)
REFERENCES `mydatabase`.`record_status` (`status`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
but I am getting the following error:
Error:
Executing SQL script in server
ERROR: Error 1005: Can't create table 'mydatabase.#sql-420_1b0' (errno: 150)
ALTER TABLE 'mydatabase'.'user'
ADD CONSTRAINT 'usr_status'
FOREIGN KEY ('user_status')
REFERENCES 'mydatabase'.'record_status'('status')
ON DELETE NO ACTION
ON UPDATE NO ACTION
SQL script execution finished: statements: 4 succeeded, 1 failed.
Question
My intention is to have the status column clearly show the current status for each user (ACTIVE, INACTV, DELETD) while still having the flexibility to join the record_status table with the user table using the record_status_id to find any rows with a given status for better performance.
I found a similar post here
Adding foreign key of type char in mysql
which suggests to change my primary key's collation but, how would that affect my user table?
Will I have to change the collation to the user_status field in my user table as well? The user table will be queried every time a user logs in and I am concerned about performance or any constraints this may cause.
I also intend to add a foreign key for the status to a few other tables as well. I would just like to know how this affects performance, or does it add any constraints?
Any input regarding my design will also be appreciated. Thank you for your help!
The issue you're facing isn't actually related to collation (though collation can be a cause of the error you're experiencing under different circumstances).
Your FOREIGN KEY constraint is failing because you don't have an index individually on record_status.status. You have that column as part of the composite PRIMARY KEY (record_status_id, status), but for successful foreign key constraint creation, both the referencing table and the referenced table must have indexes on exactly the columns used in the key relationship (in addition to the same data types).
Adding the FOREIGN KEY constraint implicitly creates the necessary index on the referencing table, but you must still ensure you have the corresponding index on the referenced table.
So given what you have now, if you added a single index on record_status.status, the constraint would correctly be created.
CREATE TABLE `record_status` (
`record_status_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status` char(6) NOT NULL,
`status_description` varchar(15) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`record_status_id`,`status`),
-- This would make your relationship work...
KEY (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
However, I don't think that's the best course of action. I don't see a need for the composite primary key on (record_status_id, status), chiefly because the record_status_id is itself AUTO_INCREMENT and guaranteed to be unique. That column alone could be the PRIMARY KEY, while still adding an additional UNIQUE KEY on status to satisfy the foreign key constraint's indexing requirement. After all, it is not the combination of record_status_id and status which uniquely identifies each row (making a primary key)
CREATE TABLE `record_status` (
`record_status_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status` char(6) NOT NULL,
`status_description` varchar(15) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- Primary only on record_status_id
PRIMARY KEY (`record_status_id`),
-- Additional UNIQUE index on status
UNIQUE KEY (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
About the design -- eliminating record_status_id...
Without knowing how the rest of your application currently uses record_status_id, I can't say for sure if it required by your application code. But, if you wish to make the actual status value easily available to other tables, and it is merely CHAR(6), it is possible that you actually have no need for record_status_id as an integer value. After all, if the status string is intended to be unique, then it is perfectly capable of serving as the PRIMARY KEY on its own, without any auto-increment integer key.
In that case, your record_status table would look like below, and your FOREIGN KEY constraint would correctly be added to users.
CREATE TABLE `record_status` (
-- Remove the auto_increment column!!
`status` char(6) NOT NULL,
`status_description` varchar(15) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- Status is unique, and therefore can be the PK on its own
PRIMARY KEY (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
Given this setup, here's a sample showing the successful creation of the tables and addition of the FK constraint.
You asked about performance implications of adding a status FK to other tables as well. It's tough to speculate on that without knowing the purpose, but if other tables share the same status values, then it makes sense to create their FK constraints to link to it in the same say you're doing with users. And if that's the case, I would recommend doing it the same way, wherein the status column is CHAR(6) (or consider changing all of them to VARCHAR(6)). The value of record_status.status still makes sense as the true primary key, and can be used as the FK in as many related tables as necessary.
In all but the most gigantic scale, there should be no appreciable performance difference between using an INT value and a CHAR(6)/VARCHAR(6) value as the foreign key. And the storage size difference between them is equally tiny. It isn't worth worrying about unless you must scale this to positively enormous proportions.
I am sure I am missing something simple.
RequestLog table:
CREATE TABLE `requestlog` (
`RequestID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`RequestName` varchar(30) NOT NULL,
`RequestData` varchar(150) NOT NULL,
`RequestDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`Version` varchar(15) NOT NULL,
PRIMARY KEY (`RequestID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
ResponseLog table:
CREATE TABLE `responselog` (
`ResponseID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`FK_RequestID` int(10) NOT NULL,
`ResponseText` text NOT NULL,
PRIMARY KEY (`ResponseID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Trying to add a foreign key on ResponseLog.FK_RequestID with
ALTER TABLE ResponseLog
ADD FOREIGN KEY (FK_RequestID) REFERENCES RequestLog(RequestID)
Don't shoot me, what am I missing?
ALTER TABLE references tables ResponseLog and RequestLog. Your CREATE TABLE statements create tables named requestlog and responselog. Try changing your ALTER TABLE statement so that it uses table identifiers with the same case.
Also, and it is probably the main problem, the referenced fields have different data types. One is an int, the other an unsigned int. Data types have to match, otherwise the fields could become inconsistent. MySQL knows this and prevents you from creating a broken foreign key.
I've two InnoDB tables in a MySQL database. Now I like to link one table to the other with a FOREIGN KEY. But it aborts with the error code 1005 - Can't create table.
I've found plenty of information about this error. For example this post and answer here on SO. Although even this answer did not help in my case. I think every point which is mentioned to be checked is not true in my case.
I've created a MySQLFiddle you can checkout with the schema which fails: http://sqlfiddle.com/#!2/b9dc43
(Please note that the failing ALTER TABLE for adding the FOREIGN KEY is not included. See the schema below for the FOREIGN KEY query.)
There's also a FK for cms_element_instance.page_IDFK which references column page.ID but I removed this FK for posting my problem here on SO.
What can be the problem here?
Here the schema in plain text:
CREATE TABLE `cms_element_instance` (
`ID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`page_IDFK` mediumint(8) unsigned DEFAULT NULL,
`revision` varchar(16) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `page_IDFK` (`page_IDFK`)
) ENGINE=InnoDB AUTO_INCREMENT=1692 DEFAULT CHARSET=utf8;
CREATE TABLE `element_faq_list` (
`element_instance_IDFK` mediumint(8) unsigned NOT NULL,
`page_IDFK` mediumint(8) unsigned NOT NULL,
`mod_faq_collection_IDFK` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`element_instance_IDFK`,`page_IDFK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Create FK: This throws error 1005
ALTER TABLE element_faq_list
ADD CONSTRAINT element_instance_fk
FOREIGN KEY (element_instance_IDFK, page_IDFK)
REFERENCES cms_element_instance( ID , page_IDFK);
You are adding (element_instance_IDFK, page_IDFK) as a foreign key constraints which refers to ID , page_IDFK columns from cms_element_instance so for this case you need a primary key based on ID , page_IDFK columns
ALTER TABLE `cms_element_instance` CHANGE `page_IDFK` `page_IDFK`
MEDIUMINT(8) UNSIGNED NOT NULL, DROP PRIMARY KEY,
ADD PRIMARY KEY (`ID`, `page_IDFK`);
Demo
I like to add foreign keys, this table, but not work! If I try new tables not work, but other, old tables it works. What's the problem?
CREATE TABLE `tanora` (
`idtanora` int(11) NOT NULL,
`tema` varchar(250) NULL,
`megjegyzes` varchar(255) DEFAULT NULL,
`datum` date NOT NULL,
`osztaly` varchar(20) NOT NULL,
`megtartott` int(11) NOT NULL,
`targy` varchar(45) NOT NULL,
`kezdete` time NOT NULL,
`vege` time NOT NULL,
PRIMARY KEY (`idtanora`),
UNIQUE KEY `idtanora_UNIQUE` (`idtanora`),
KEY `osztazon_idx` (`osztaly`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_hungarian_ci;
CREATE TABLE `osztaly` (
`osztalyazon` varchar(20) NOT NULL,
`osztalyfonokazon` varchar(11) NOT NULL,
`osztalynev` varchar(45) NOT NULL,
`indul` year(4) NOT NULL,
PRIMARY KEY (`osztalyazon`),
UNIQUE KEY `osztalyazon_UNIQUE` (`osztalyazon`),
KEY `ofazon_idx` (`osztalyfonokazon`),
CONSTRAINT `tanarazon01` FOREIGN KEY (`osztalyfonokazon`) REFERENCES `tanar` (`szemelyiszam`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_hungarian_ci;
ERROR 1215: Cannot add foreign key constraint
SQL Statement:
ALTER TABLE `enaplo`.`tanora`
ADD CONSTRAINT `osztalyra`
FOREIGN KEY (`osztaly`)
REFERENCES `enaplo`.`osztaly` (`osztalyazon`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
ERROR: Error when running failback script. Details follow.
ERROR 1050: Table 'tanora' already exists
SQL Statement:
CREATE TABLE `tanora` (
`idtanora` int(11) NOT NULL,
`tema` varchar(250) NOT NULL,
`megjegyzes` varchar(255) DEFAULT NULL,
`datum` date NOT NULL,
`osztaly` varchar(20) NOT NULL,
`megtartott` int(11) NOT NULL,
`targy` varchar(45) NOT NULL,
`kezdete` time NOT NULL,
`vege` time NOT NULL,
PRIMARY KEY (`idtanora`),
UNIQUE KEY `idtanora_UNIQUE` (`idtanora`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_hungarian_ci
foreign key (osztaly)
references enaplo.osztaly (osztalyazon)
on delete no action
on update no action:
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.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Make sure that you have consistent column definitions:
In your referencing table osztaly the foreign key column osztalyfonokazon needs to be defined with the exact same characteristics as applied to the referenced field in the tanar table.
Currently, osztalyfonokazon in osztaly is defined as follows:
`osztalyfonokazon` VARCHAR(11) NOT NULL
So, then in the tanar table the szemelyiszam definition should look like either
`szemelyiszam` VARCHAR(11) PRIMARY KEY
or
`szemelyiszam` VARCHAR(11) UNIQUE KEY NOT NULL
Depends on your needs.
Either way, ensure that szemelyiszam is a PRIMARY KEY or at least a UNIQUE KEY that is declared NOT NULL in the referenced tanar table.
Additionally, MySQL requires that the referenced columns be indexed
for performance reasons. However, the system does not enforce a
requirement that the referenced columns be UNIQUE or be declared NOT
NULL. The handling of foreign key references to nonunique keys or keys
that contain NULL values is not well defined for operations such as
UPDATE or DELETE CASCADE. You are advised to use foreign keys that
reference only UNIQUE (including PRIMARY) and NOT NULL keys.
Source