Mysql Workbench Can't Select Foreign Key - mysql

First of all I've examined a lot of questions and googled it a lot, none of them solved my problem..
I'm creating my tables by using Mysql Workbench 6.3. I've created them by using only gui not a single query. After that I've tried to create some foreign keys for int(11) columns but GUI is not allowing me to do so.
Here's my Show Create Table 'tableName'
CREATE TABLE `item` (
`id` int(11) NOT NULL,
`description` varchar(300) NOT NULL,
`maker` varchar(200) NOT NULL,
`model` varchar(200) NOT NULL,
`condition` varchar(200) NOT NULL,
`locationId` int(11) NOT NULL,
`categoryId` int(11) NOT NULL,
`userId` int(11) NOT NULL,
`lendTermsId` int(11) NOT NULL,
`itemOptionsId` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
And the other one ;
CREATE TABLE `location` (
`id` int(11) NOT NULL,
`type` varchar(200) NOT NULL,
`coordinateLat` varchar(200) NOT NULL,
`coordinateLong` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I'm trying to create a foreign key between location.id and item.locationId.
Workbench GUI is not allowing me to select checkboxes...
As you can see from this image I can't select checkbox or select combobox value..
EDIT: I can manage this with query, but there are a lot of tables in some projects, dont want to do it all with queries... Is there something that I'm missing in workbench ?
Thanks in advance.

As user4115463 said, this is caused by a difference in DataType. Make sure that both keys have the exact same data type:
the Datatype field should contain the exact same string (INT and INT(10) are not the same)
the B (Is binary) checkbox should match
the UN (Unsigned) checkbox should match
When selecting a checkbox, MySQL Workbench attempts to populate the dropdown next to the checkbox with matching columns, and if it can't find any matching columns, it decides to silently ignore the click on the checkbox instead.

It might be a little late to answer this question but,
Recently, I experience this issue in Workbench GUI and it was caused by difference in DataType.
Making sure that both fields have the same DataType seems to resolve the issue.
Hope this helps.

Try the following Alt statement
ALTER TABLE `emp`.`item`
ADD INDEX `location_idx` (`categoryId` ASC);
ALTER TABLE `emp`.`item`
ADD CONSTRAINT `location`
FOREIGN KEY (`categoryId`)
REFERENCES `emp`.`location` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
I have tested through GUI check this screenshot

Related

MySQL (Percona) Error 1452: Cannot add or update a child row for no reason

I have 2 Database Tables "users" and "tasks".
The tasks table contains two foreign keys for the createdBy_user_id and updatedBy_user_id columns both referencing users.id. If I try to insert an entry to tasks (after making sure the user referenced by the foreign keys exists) like this:
INSERT INTO tasks (createdBy_user_id,updatedBy_user_id,noOfYear,createdAt,updatedAt,status,customer_id)
VALUES (1,1,1,NOW(),NOW(),"open",1)
The query fails with Error 1452:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`tasks`, CONSTRAINT `user_id_fk_constr` FOREIGN KEY (`createdBy_user_id`) REFERENCES `users` (`id`))
I don't know why this happens, because everything works fine if I remove the constraint. The same error does not happen for the "updatedBy_user_id" column making this such confusing.
The Tables have the following DDL:
Users table:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`active` tinyint(1) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`email_confirmed_at` datetime DEFAULT NULL,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`first_name` varchar(50) DEFAULT NULL,
`last_name` varchar(50) DEFAULT NULL,
`job` varchar(64) DEFAULT NULL,
`position` varchar(64) DEFAULT NULL,
`specialKnowledge` text,
`tasks` text,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
Tasks table:
CREATE TABLE `tasks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`createdAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`noOfYear` int(11) NOT NULL,
`year` int(11) GENERATED ALWAYS AS (right(year(`createdAt`),2)) VIRTUAL NOT NULL,
`createdBy_user_id` int(11) NOT NULL,
`updatedBy_user_id` int(11) NOT NULL,
`status` enum('open','closed') NOT NULL,
`customer_id` int(11) NOT NULL,
`projectDescription` text,
PRIMARY KEY (`id`),
UNIQUE KEY `tasks_year_unique_constr` (`year`,`noOfYear`),
KEY `user_id_fk_constr` (`createdBy_user_id`),
KEY `customer_id_fk_constr` (`customer_id`),
KEY `user_up_id_fk_constr` (`updatedBy_user_id`),
CONSTRAINT `customer_id_fk_constr` FOREIGN KEY (`customer_id`) REFERENCES `Customer` (`id`),
CONSTRAINT `user_id_fk_constr` FOREIGN KEY (`createdBy_user_id`) REFERENCES `users` (`id`),
CONSTRAINT `user_up_id_fk_constr` FOREIGN KEY (`updatedBy_user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4
As you can see the datatypes match and both tables use the InnoDB Engine.
The users table contains one entry:
select id,username from users;
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
+----+----------+
1 row in set (0.00 sec)
So there is no obvious reason, why the insertion should fail. Have you an idea what's wrong with my tables? Looks like a software bug.
This is a bug. MySQL 5.7 has had some troubles with generated columns and foreign keys, and I assume this is an unfixed variant of Bug #79772 Foreign key not allowed when a virtual index exists.
In your particular case, and probably depending on your exact version, any of the following modifications seems to prevent that bug from occurring:
do not use a virtual column, but make it stored
do not create a foreign key for a column directly following the virtual column, so e.g. change the column order to year, status, createdBy_user_id, updatedBy_user_id.
do not use a unique index on the virtual column, a normal index should be fine (at least in a version where the linked bug is fixed). You want a unique constraint, so this is not an option, but the fact that this fixes your problem emphasized the "bug" nature of the problem.
The second bullet point seems to be the underlying bug: I assume that some iterator doesn't count the virtual column properly, so the foreign key that shall check createdBy_user_id seems to mix up the columns and actually checks the value of year (in this case "20") against the users table. So if you have a user with id "20" in your users table, the foreign key will actually accept this, no matter what value for createdBy_user_id you are trying to insert, see the MySQL 5.7.29 fiddle.
Unless you have a specific reason to use a virtual column, using stored is probably the sane thing to do.

How do I add a foreign key to a table in Sequel Pro?

I am trying to add a foreign key to a table in Sequel Pro (using the UI).
I have two tables: "titles" and "categories" as below:
CREATE TABLE `titles` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` tinytext NOT NULL,
`category` varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `category` (
`key` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (`key`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
I want to create a foreign key, but nothing I try works.
The category table should be a simple lookup table. I want to assign each title a category from about 6 - 8 different choices.
Originally I had the category fields as tinytext, but I would get the error:
"MySQL Error 1170 (42000): BLOB/TEXT Column Used in Key Specification Without a Key Length".
Searched here and discovered you can't use text field that way, so I switched to Varchar and added a length of 256. Now I get:
MySQL said: Can't create table 'lit.#sql-2bf3_2' (errno: 150).
How can I create a foreign key for my table?
In Access this is pretty easily done. Somehow Access associates the unique key in the table with the lookup, but then hides the key and shows you the text field instead. How can I get a similar result with Sequel Pro and MySQL?
EDIT:
So, to clarify this is where I'm at right now. I've added an index on the category field in the titles table (first picture).
I've changed the "key" field in the category table to CategoryID (second picture).
However, I still can't seem to create the relationship between the two tables. I get the same error
As category will be your lookup table off of titles, you'd need to create an index on category which would refer to the foreign key. They would both need to be the same datatype (usually an INT, though sometimes you could use a CHAR(2) variable in some cases, but usually not necessary). Since you only expect 6-8 categories, I'd make it INT(1) (or may be INT(2) to be safe).
In this case, you would need to create something like categoryId which would first need to be indexed, then connect to the foreign key on categorywhich does not appear to exist; I'm not sure you want to use a term like key. Why not just make categoryId the primary key on category? this way when you create the foreign key on titles with the same name, it should link up fine.
Edit:
To clarify a little, after you've created categoryID on category you can do this under titles
ALTER TABLE Orders
ADD CONSTRAINT fk_categoryID
FOREIGN KEY (`categoryId`) REFERENCES `category`(`categoryId`)
Edit:
Here's a modification using your original layout. this should work for you:
CREATE TABLE IF NOT EXISTS `category` (
`key` int(2) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
CREATE TABLE IF NOT EXISTS `titles` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` tinytext NOT NULL,
`categoryID` int(2) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `categoryID` (`categoryID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
ALTER TABLE `titles`
ADD CONSTRAINT `titles_ibfk_1` FOREIGN KEY (`categoryID`) REFERENCES `category` (`key`);

What is wrong with my SQL here? #1089 - Incorrect prefix key

CREATE TABLE `table`.`users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`dir` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`(11))
) ENGINE = MyISAM;
I'm getting the #1089 - Incorrect prefix key error and can't figure out what I'm doing wrong.
In your PRIMARY KEY definition you've used (id(11)), which defines a prefix key - i.e. the first 11 characters only should be used to create an index. Prefix keys are only valid for CHAR, VARCHAR, BINARY and VARBINARY types and your id field is an int, hence the error.
Use PRIMARY KEY (id) instead and you should be fine.
MySQL reference here and read from paragraph 4.
If you are using a GUI and you are still getting the same problem. Just leave the size value empty, the primary key defaults the value to 11, you should be fine with this. Worked with Bitnami phpmyadmin.
This
PRIMARY KEY (id (11))
is generated automatically by phpmyadmin, change to
PRIMARY KEY (id)
.
There is a simple way of doing it. This may not be the expert answer and it may not work for everyone but it did for me.
Uncheck all primary and unique check boxes, jut create a plain simple table.
When phpmyadmin (or other) shows you the table structure, make the column primary by the given button.
Then click on change and edit the settings of that or other colums like 'unique' etc.
CREATE TABLE `table`.`users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`dir` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`(11))
) ENGINE = MyISAM;
Change To
CREATE TABLE `table`.`users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`dir` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MyISAM;
Here the full solution step by step
First of all you have to make the table by inserting all the data. id should AI ticked.
then press go and #1089 error will be pop-up
here is the solution
theres a button near go called preview SQL
click that button and copy the sql code
then click on SQL tab on top of the window
Clear the text filed and paste that copied code there.
you will be see (id (11)) this on bottom of the code
replace (id (11)) into (id)
and click go
boom now you will be fine
In my case, i faced the problem while creating table from phpmyadmin. For id column i choose the primary option from index dropdown and filled the size 10.
If you're using phpmyadmin, to solve this problem change the index dropdown option again, after reselecting the primary option again it'll ask you the size, leave it blank and you're done.
It works for me:
CREATE TABLE `users`(
`user_id` INT(10) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE = MyISAM;
When you give id as a primary key then a pop up is come and those aske you to how many size of this primary key.
So you just leave blank because by default int value is set 11. Click then ok on those pop up without any enter a number.
in this type of error never will you face in future.
Thank you 😊
Problem is the same for me in phpMyAdmin. I just created a table without any const.
Later I modified the ID to a Primary key. Then I changed the ID to Auto-inc.
That solved the issue.
ALTER TABLE `users` CHANGE `ID` `ID` INT(11) NOT NULL AUTO_INCREMENT;
I also had this same problem.
Solution work for me:
CREATE TABLE IF NOT EXISTS `users` (
`sr_no` int(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`dir` VARCHAR(100) NOT NULL,
PRIMARY KEY (`sr_no`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
I paste this code in SQL and run, it works fine.
In PHPMyAdmin, Ignore / leave the size value empty on the pop-up window.
according to the latest version of MySQL (phpMyAdmin), add a correct INDEX while choosing primary key. for example: id[int] INDEX 0 ,if id is your primary key and at the first index.
Or,
For your problem try this one
CREATE TABLE `table`.`users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`dir` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MyISAM;
This worked for me:
CREATE TABLE `table`.`users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`dir` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`(id))
) ENGINE = MyISAM;
No need to put id(11) because, by default, it is equal to 11 so you leave
it as id and in phpmyadmin you leave it empty.
Drop the table.user and just use user
The lenght of the id was alread specified in the
id INT(11) and does not need to be specified in the PRIMART KEY.
CREATE TABLE users
(
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
dir VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MyISAM;

MySQL Create table with reference to non existant table

Using MySQL workbench, I copied the create statement from a few related tables to put into a clean schema. They all reference each other in some way so there is no inherent order I can create them in. How can I just force MySQL to create the tables while ignoring any warning that may occur, just until the rest of the tables are created?
Would I have to group it inside a transaction of some sort?
A very simple example would be:
CREATE TABLE `vehicle` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`gallery_id` int(11) DEFAULT NULL,
`make_id` int(11) NOT NULL,
`model_id` int(11) DEFAULT NULL,
`make` varchar(100) DEFAULT '',
`model` varchar(100) DEFAULT '',
`colour_id` int(11) DEFAULT NULL,
`currency_id` int(11) NOT NULL DEFAULT '1',
`fuel_id` int(11) DEFAULT NULL,
`status_id` int(11) DEFAULT NULL,
`stock_code` varchar(100) DEFAULT NULL,
`registration` varchar(20) DEFAULT NULL,
`title` varchar(100) DEFAULT NULL,
`description` text,
`month` tinyint(4) DEFAULT NULL,
`public` tinyint(4) NOT NULL DEFAULT '0',
`sold` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `vehicle_fk_idx` (`status_id`),
CONSTRAINT `vehicle_fk` FOREIGN KEY (`status_id`) REFERENCES `vehicle_status` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `vehicle_status` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`slug` varchar(100) DEFAULT NULL,
`title` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug_UNIQUE` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
vehicle references vehicle_status which would mean that vehicle_status would have to be created first. How would I create vehicle first and then vehicle_status without adding the reference afterwards?
You do not define foreign keys when creating tables, you would have them in a separate query like this:
ALTER TABLE `vehicle`
ADD CONSTRAINT `vehicle_ibfk_1` FOREIGN KEY (`status_id`)
REFERENCES `vehicle_status` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
So you would first create tables and then create foreign keys.
The way I personally do is I have all CREATE TABLE queries in one file that I know I can simply just import without any errors. I have all CONSTRAINT queries in a separate file that I import after all the tables have been created and I have all INSERT INTO queries in a separate file that adds data after all constraints and tables have been set.
It looks like vehicle_status is a lookup table, while vehicle is a primary transaction table.
In general, lookup tables do not reference other tables, although there can be designs where one lookup table references another lookup table. In your case, it's simple: just create vehicle_status first. If your schema has a hundred tables in it, it's going to involve a little work to order the create commands in the right sequence.
There are designs where the reference chain forms a circle. In such a case, you'll have to do what GGio suggests: add the constraints later. There are other problems with designs involving circular references, and those problems may or may not be present in your schema.
When you go to populate the tables, you'll have to worry about order as well. In general, you'll have to populate the lookup tables first, before you begin to populate the transaction tables. Otherwise you'll get reference violations at load time.

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.