I have 2 tables users and iom.
Primary key of users is iomid and of course in iom the foreign key is iomid that references users.iomid.
If i create a new user in users, I want it automatically inserted into iom aswell without making a second statement.
How can I do it?
iom:
CREATE TABLE IF NOT EXISTS `iom` (
`id` int(11) NOT NULL,
`iomid` varchar(50) NOT NULL,
`subscribed` int(11) DEFAULT NULL,
`workoutcounter` int(11) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
ALTER TABLE `iom`
ADD UNIQUE KEY `id` (`id`), ADD KEY `iom_ibfk_1` (`iomid`);
ALTER TABLE `iom`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `iom`
ADD CONSTRAINT `iom_ibfk_1` FOREIGN KEY (`iomid`) REFERENCES `users` (`iomid`) ON DELETE CASCADE ON UPDATE CASCADE;
user:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL,
`iomid` varchar(50) NOT NULL,
`name` varchar(50) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
ALTER TABLE `users`
ADD PRIMARY KEY (`iomid`), ADD UNIQUE KEY `id` (`id`);
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
Thanks and greetings!
Now that I look at your question again, the issues with your foreign key conventions are fairly irrelevant. Even with more typical relations, foreign key constraints cannot create rows; at most, they can "cascade" updates and deletes of referenced values to referencing tables.
What you need is an "AFTER INSERT ON users" trigger. (Documentation here.)
Related
Suppose I have a table items
with columns id (PRIMARY), name(VARCHAR), section_id (BIGINT), updated_at (DATETIME),
and a table sections with id (PRIMARY).
Naturally, items.section_id is a foreign key that refers to sections.id.
Suppose there is an index on items of the columns (section_id, name). I believe that if you tried to drop this index, you would get an error that it is needed in a foreign key constraint. I can accept this.
Now, I want to create a new index, like create index ix_section_id_id_updated_at on items (section_id, id, updated_at). MySQL lets me do this, but if I go to drop this table, I get that same error: it fails, because it is needed in a foreign key constraint.
Why should this be? It already has one index that can be used for this foreign key check. Further, the error does NOT go away with set FOREIGN_KEY_CHECKS=0;. Is there a way to force MySQL to not associate the new index with the foreign key, so that it is quick to drop? This is necessary because I will be running the migration on a production server with temporary downtime, and need to be able to quickly revert the migration in case of anything going wrong afterwards.
I can reproduce your issue if I don't create an index on section_id and allow mysql to do so on the creation of a foreign key(as described in the manual). Adding a new index drops the auto generated key and if you then drop the new index an error is generated because of the requirement to have a key , and mysql does not auto generate one on a drop.. . If you manually generate a key on section_id this problem does not happen..and the newly created compound index drops successfully.
drop table if exists items;
drop table if exists sections;
create table items(id int PRIMARY key, name varchar(3), section_id BIGINT, updated_at DATETIME);
create table sections(id bigint primary key);
alter table items
add foreign key fk1(section_id) references sections(id);
show create table items;
CREATE TABLE `items` ( `id` int(11) NOT NULL,
`name` varchar(3) DEFAULT NULL,
`section_id` bigint(20) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk1` (`section_id`),
CONSTRAINT `fk1` FOREIGN KEY (`section_id`) REFERENCES `sections` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
alter table items
add key key1(section_id, name);
show create table items;
CREATE TABLE `items` (
`id` int(11) NOT NULL,
`name` varchar(3) DEFAULT NULL,
`section_id` bigint(20) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `key1` (`section_id`,`name`),
CONSTRAINT `fk1` FOREIGN KEY (`section_id`) REFERENCES `sections` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
and with manually generated key
drop table if exists items;
drop table if exists sections;
create table items(id int PRIMARY key, name varchar(3), section_id BIGINT, updated_at DATETIME);
create table sections(id bigint primary key);
alter table items
add key sid(section_id);
alter table items
add foreign key fk1(section_id) references sections(id);
show create table items;
CREATE TABLE `items` (
`id` int(11) NOT NULL,
`name` varchar(3) DEFAULT NULL,
`section_id` bigint(20) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `sid` (`section_id`),
CONSTRAINT `fk1` FOREIGN KEY (`section_id`) REFERENCES `sections` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
alter table items
add key key1(section_id, name);
show create table items;
CREATE TABLE `items` (
`id` int(11) NOT NULL,
`name` varchar(3) DEFAULT NULL,
`section_id` bigint(20) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `sid` (`section_id`),
KEY `key1` (`section_id`,`name`),
CONSTRAINT `fk1` FOREIGN KEY (`section_id`) REFERENCES `sections` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I have a table called user and the primary key is user_id.
I have another table called follows. This table is for storing which user follow which user(it is something like twitter follow function).
This is my follow table.
CREATE TABLE `follows` (
`id` int(11) NOT NULL,
`orginal_user_id` int(11) NOT NULL,
`follow_user_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `follows`
ADD PRIMARY KEY (`id`);
So, how can I alter this table to set both orginal_user_id and follow_user_id as a foreign key of user_id of user table...
If a user is deleted from the user table, I want to automatically delete rows in follows table either that user id appears on an orginal_user_id column or follow_user_id column.
You may use cascading delete constraints in your table:
CREATE TABLE follows (
id int(11) NOT NULL PRIMARY KEY,
orginal_user_id int(11) NOT NULL,
follow_user_id int(11) NOT NULL,
CONSTRAINT fk_original_user FOREIGN KEY (orginal_user_id)
REFERENCES user(id) ON DELETE CASCADE,
CONSTRAINT fk_follow_user FOREIGN KEY (follow_user_id)
REFERENCES user(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Trying to create a simple relation between two fields in two tables - 'Task' table with the field 'USER_TOKEN' and the 'USER' table with the field 'TOKEN'. The two fields are the same structure. As you can see the error and other things that may assist you to help me understand the problem and fix it.
System: MacOS 10.12.3 | DB : MySQL 5.7.17 | DBM : Sequel Pro
Error : MySQL said: Cannot add foreign key constraint
CREATE TABLE `TASK` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`USER_TOKEN` int(11) unsigned NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `USER` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`TOKEN` int(11) unsigned NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE USER
ADD CONSTRAINT TOKENS
FOREIGN KEY (`TOKEN`) REFERENCES `category`(`USER_TOKEN`)
Thanks.
If you really want to create a foreign key to a non-primary key, it MUST be a column that has a unique constraint on it.
A FOREIGN KEY constraint does not have to be linked only to a PRIMARY KEY constraint in another table; it can also be defined to reference the columns of a UNIQUE constraint in another table.
So your USER_TOKEN column of table TASK and TOKEN column of USER table must be UNIQUE. So run the following query:
CREATE TABLE `TASK` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`USER_TOKEN` int(11) unsigned NOT NULL UNIQUE,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `USER` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`TOKEN` int(11) unsigned NOT NULL UNIQUE,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `USER`
ADD CONSTRAINT `TOKENS`
FOREIGN KEY (`TOKEN`) REFERENCES `TASK`(`USER_TOKEN`);
Check Demo here
I have two tables I have created and I'm adding the foreign key constraint after the fact.
The two tables are defined as such:
CREATE TABLE `user` (
`user_id` int(11) NOT NULL auto_increment,
`user_ad_id` varchar(500) default NULL,
`user_name` varchar(100) NOT NULL,
`login_id` varchar(100) default NULL,
`email` varchar(256) NOT NULL,
`personal_config` int(10) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and
CREATE TABLE IF NOT EXISTS personal_config (
config_id INT(10) NOT NULL AUTO_INCREMENT,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
configuration TEXT(25600) NOT NULL,
PRIMARY KEY (config_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE personal_config ADD CONSTRAINT personal_config_fk_user FOREIGN KEY
(config_id) REFERENCES user(personal_config);
And I keep getting the same error but can't figure it out. I've searched all the related threads to this.
Your FK config_id can't be an autoincrement field, that doesn't make much sense right? That field reflects a value in the foreign table, it cannot be set arbitrarily in the local table.
I think this is what you want:
ALTER TABLE user ADD CONSTRAINT personal_config_fk_user FOREIGN KEY (personal_config) REFERENCES personal_config(config_id);
Your ALTER TABLE statement is backward. Since personal_config.config_id is an auto_increment primary key, the foreign key should be defined in the users table against personal_config, not in personal_config against the users table.
ALTER TABLE users ADD CONSTRAINT user_fk_personal_config
FOREIGN KEY (personal_config)
REFERENCES personal_config(config_id);
if you set your user table field personal_config is primary key then it is possible to execute
CREATE TABLE IF NOT EXISTS personal_config (
config_id INT(10) NOT NULL AUTO_INCREMENT,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
configuration TEXT(25600) NOT NULL,
PRIMARY KEY (config_id), FOREIGN KEY
(config_id) REFERENCES user(personal_config)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
here are my two tables
CREATE TABLE IF NOT EXISTS `carslibrary` (
`CarID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`CarName` varchar(255) NOT NULL,
`colorslibrary_ID` int(11) unsigned NOT NULL,
PRIMARY KEY (`CarID`),
KEY `colorslibrary_ID` (`colorslibrary_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
CREATE TABLE IF NOT EXISTS `colorslibrary` (
`ColorID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ColorName` varchar(255) NOT NULL,
PRIMARY KEY (`ColorID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
I get an error on the following query:
ALTER TABLE `carslibrary` ADD FOREIGN KEY ( `colorslibrary_ID` )
REFERENCES `cars2`.`colorslibrary` (`ColorID` );
MySQL says:
#1452 - Cannot add or update a child row: a foreign key constraint
fails (`cars2`.<result 2 when explaining filename
'#sql-cf8_41a'>, CONSTRAINT `#sql-cf8_41a_ibfk_1` FOREIGN KEY
(`colorslibrary_ID`) REFERENCES `colorslibrary` (`ColorID`))
Your tables aren't empty, therefore a constraint fails (reference not found) when you create it.
Use SET FOREIGN_KEY_CHECKS = 0; and re-run your alter table.
I would firstly identify orphaned rows in the carslibrary table:
select * from carslibrary where colorslibrary_ID not in (select ColorID from cars2.colorslibrary);
Then decide what you want to do with these orphaned rows. Want to DELETE them from the carslibrary table? UPDATE them to an existing parent ColorID in the colorslibrary? INSERT a new ColorID in the colorslibrary table to cater for the orphaned rows?
Once you've tidied up your data you should be able to run the ALTER TABLE with no errors.