What is the cause for MySQL: Errorno 150 - mysql

Can someone please explain the cause for the following error, 'Can't create table 'Activities' (errno: 150)'
I'm under the understading that the data types and lengths have to be the same, does is have anything to do with the auto increment?
Create Table `LinkMemberActivity` (
`LinkID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`MID` int(11) unsigned NOT NULL,
`AID` int(11) unsigned NOT NULL,
PRIMARY KEY (`LinkID`),
FOREIGN KEY (`MID`) REFERENCES Members(`MID`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
)
CREATE TABLE `Activities` (
`AID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(25) DEFAULT NULL,
`MaxCapacity` int(25) DEFAULT NULL,
`StartTime` time DEFAULT NULL,
`EndTime` time DEFAULT NULL,
PRIMARY KEY (`AID`),
FOREIGN KEY (`AID`) REFERENCES LinkMemberActivity(`AID`))
ENGINE=InnoDB DEFAULT CHARSET=latin1 );

You are trying to make a primary key column a foreign key dependent field. This is not only unusual but makes no sense in a datamodel, unless it is part of a composite key. Common practice has a column foreign key dependent on another tables primary key. Not sure what reasons you have for the way you designed your datamodel this way, but you can fix this problem by creating a not null autoincrement column named ID and make this column the primary key. Next remove autoincrement from aid.

Related

Interpretation of model diagram for allocation of foreign/primary keys

https://imgur.com/a/HAlSO7z
I am totally confused as to what I should identify as the primary key for the flatpack components table. For the flatpack components, there is a multiplicty relationship with both of the other tables, although intuitively I am leaning toward the component table because that seems more relevant, and the multiplicity is 0 to Many to 1, as opposed to the Many to 1 associated with flatpack components.
I have tried a composite key of both flatpackID and componentNo, but have ran into errors whilst trying to populate the table with sample data.
At present, I have the following tables:
CREATE TABLE `flatpack_apn` (
`flatpackid` INT(11) NOT NULL AUTO_INCREMENT,
`name` TINYTEXT NOT NULL,
`colour` TEXT NULL DEFAULT NULL,
`flatpacktype` ENUM('Office','Kitchen','Bedroom','General') NOT NULL,
`unitprice` DECIMAL(5,2) NULL DEFAULT NULL,
PRIMARY KEY (`flatpackid`)
)
COLLATE='hp8_english_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2217
;
CREATE TABLE `component_apn` (
`componentno` INT(11) NOT NULL AUTO_INCREMENT,
`description` VARCHAR(30) NOT NULL,
PRIMARY KEY (`componentno`)
)
COLLATE='hp8_english_ci'
ENGINE=InnoDB
AUTO_INCREMENT=20
;
For the flatpackcomponents_apn table (the table in contention) I have tentatively put the following code:
CREATE TABLE `flatpackcomponents_apn` (
`flatpackid` INT(11) NOT NULL DEFAULT '12',
`componentno` INT(11) NOT NULL DEFAULT '23',
`quantity` INT(10) NOT NULL,
PRIMARY KEY (`componentno`, `flatpackid`),
INDEX `flatpackid` (`flatpackid`),
INDEX `componentno` (`componentno`),
CONSTRAINT `flatpackcomponents_apn_ibfk_1` FOREIGN KEY (`flatpackid`) REFERENCES `flatpack_apn` (`flatpackid`),
CONSTRAINT `flatpackcomponents_apn_ibfk_2` FOREIGN KEY (`componentno`) REFERENCES `component_apn` (`componentno`)
)
COLLATE='hp8_english_ci'
ENGINE=InnoDB
;

How MySQL one to many and one to one relationships are defined?

I was referring these to Hibernate tuts: 1, 2.
I was not able to understand how one to one and one to many relationships are defined in MySQL tables.
This is SQL for one to many relationship:
CREATE TABLE `Cart` (
`cart_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`total` decimal(10,0) NOT NULL,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`cart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
CREATE TABLE `Items` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`cart_id` int(11) unsigned NOT NULL,
`item_id` varchar(10) NOT NULL,
`item_total` decimal(10,0) NOT NULL,
`quantity` int(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `cart_id` (`cart_id`),
CONSTRAINT `items_ibfk_1` FOREIGN KEY (`cart_id`) REFERENCES `Cart` (`cart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
This is SQL for one to one relationship:
-- Create Transaction Table
CREATE TABLE `Transaction` (
`txn_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`txn_date` date NOT NULL,
`txn_total` decimal(10,0) NOT NULL,
PRIMARY KEY (`txn_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
-- Create Customer table
CREATE TABLE `Customer` (
`txn_id` int(11) unsigned NOT NULL,
`cust_name` varchar(20) NOT NULL DEFAULT '',
`cust_email` varchar(20) DEFAULT NULL,
`cust_address` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`txn_id`),
CONSTRAINT `customer_ibfk_1` FOREIGN KEY (`txn_id`) REFERENCES `Transaction` (`txn_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
If eyes are ok, I dont see any difference between two. Is it like this relationship cardinality constraints are implemented only at hibernate level and are not enforced by database? Or my eyes are missing something?
It's actually possible to define 1:1 relationships in SQL. There are two ways:
The child table has the same PK as the parent table, with the same values. This column is also an FK to the parent table.
The child table has a different PK. It also has a FK that points to the parent table, and this FK has a UNIQUE constraint.
If you noticed, in both cases the FK is UNIQUE (it's the PK, or has a UNIQUE constraint), and that's the key aspect. It's not possible the create a second row in the child table that has the same parent.
The case you included in your question opted for strategy #1.

Simple add foreign key returns #1215 cannot add foreign key constraint

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.

mysql won't allow foreign key

Many people had this problem already, but there was no fitting solution in other posts.
I have two tables, one named "sales", the other named "host_flags". I would like to have a foreign key for host_flags.sales_id to sales.id, but mysql won't let me! I have primary indexes defined in each table, so I wonder why...
The host_flags table already has a foreign key on the column host_id, but even when I tried and created the foreign key for the sales id first, it wouldn't let me.
The tables look like:
CREATE TABLE `sales` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`creation` datetime DEFAULT NULL,
`lastupdate` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
CREATE TABLE `host_flags` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`host_id` int(11) DEFAULT NULL,
`sales_id` int(11) DEFAULT NULL,
`creation` datetime DEFAULT NULL,
`lastupdate` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `host_id6` (`host_id`),
CONSTRAINT `host_id6` FOREIGN KEY (`host_id`) REFERENCES `hosts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `hosts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`creation` datetime NOT NULL,
`lastupdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32225 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
I get this error message:
MySQL said: Can't create table 'primarydata.#sql-191_1' (errno: 150)
Thanks!
Charles
SOLUTION FOUND
All ints of the primary indexes have to be either signed or unsigned - not mixed.
Typically:
I like to declare the FK constraints outside of the table definition after all tables have been constructed.
ALTER TABLE `tbl`
ADD CONSTRAINT `constr`
FOREIGN KEY `fk_id` REFERENCES `ftbl`(`id`)
ON UPDATE CASCADE
ON DELETE CASCADE;
This way I can make sure the problem isn't something like the datatype of tbl.fk_id not being the same as the one of ftbl.id (including UNSIGNED as #Devart said). Or not having declared ftbl.id as unique. Regardless of the order of declaration of the tables.
After i do this i can integrate the constraint back into the table definition and take into account the order in which the tables need to be created to allow the constraint to be added.
You problem:
-- creating the sales table
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
-- creating the host_flags table
`sales_id` int(11) DEFAULT NULL,
-- the sales.id is declared as unsigned
-- the host_flags.sales_id is declared signed
Additonally to Recursed's answer:
There is a requirement that foreign keys contstraints' names must be unique in database scope. Maybe changing the name will work?
There is also a huge thread on MySQL community forums about the problem containing several solutions for some specific situations.
Possible two errors:
Reference and referenced columns must have the same type - int(11) unsigned
Unknown referenced table hosts.

Foreign key constraint is incorrectly formed?

I got this error when create table: Foreign key constraint is incorrectly formed?
create table comment(
Comment_ID int UNSIGNED AUTO_INCREMENT not null,
User_1 varchar(50) not null,
Note_ID int(11) UNSIGNED not null,
PRIMARY key(Comment_ID),
CONSTRAINT `fk_1` FOREIGN KEY (`User_1`) REFERENCES `user` (`Dev_ID`),
CONSTRAINT `fk_2` FOREIGN KEY (`User_2`) REFERENCES `user` (`Dev_ID`),
CONSTRAINT `fk_3` FOREIGN KEY (`Note_ID`) REFERENCES `note`(`Note_ID`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
it's OK when I remove fk_3.
This my note table
CREATE TABLE `note` (
`Dev_ID` varchar(50) NOT NULL,
`Note_ID` int(11) UNSIGNED NOT NULL,
`Title` varchar(200) NOT NULL,
`Time` datetime NOT NULL,
`Mood` int(11) NOT NULL,
`Body` varchar(3000) NOT NULL,
`Visible` tinyint(1) NOT NULL DEFAULT '1',
`Share` tinyint(1) NOT NULL DEFAULT '0',
`Update` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`Dev_ID`,`Note_ID`),
CONSTRAINT `fk_note_user` FOREIGN KEY (`Dev_ID`)
REFERENCES `user` (`Dev_ID`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Thanks for help!
That's because the primary key of the note table is (Dev_ID,Note_ID) but you are only referencing one of those columns (Note_ID) in your constraint.
A FK constraint must always consist of all PK columns.
Also make sure that both tables are innoDB.
In addition to the answers that have been given, you would also get this error if the field types did not match. For example, if you tried to create a foreign key constraint between a varchar field and an int field.
This problem occur because the column
`Note_ID` int(11) UNSIGNED NOT NULL
Is neither primary nor unique.
Just make it
`Note_ID` int(11) UNSIGNED NOT NULL UNIQUE
And it will work.
One more addition: charsets of the fields must match.
In the referenced table I had ascii as a default charset: DEFAULT CHARSET=ascii was reported by show create table. I tried to create the referencing table with DEFAULT CHARSET=utf and I got 'Foreign key constraint is incorrectly formed'.
After I changed this to DEFAULT CHARSET=ascii on the new table (the referencing one), it was created successfully.
Ensure the collation is the same on both fields. I had the same problem when one was latin-general-ci and the other was utf8_unicode_ci. Not sure why the collation changed on the one table but fixing this resolved the issue.