Use tuple as a foreign key - mysql

Let's say i have a table named borrows like this one:
CREATE TABLE IF NOT EXISTS `borrows`
( `memberID` int(11) NOT NULL ,
`ISBN` int(11) NOT NULL ,
`CopyNr` int(11) NOT NULL ,
`date_of_borrowing` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`date_of_reminder` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`memberID`,`ISBN`,`CopyNr`,`date_of_borrowing`) )
ENGINE=InnoDB DEFAULT CHARSET=latin1
I want this table to have (ISBN,CopyNr) as a foreign key to an other table named copies.What i tried is this:
ALTER TABLE `borrows` ADD FOREIGN KEY (`ISBN`,`copyNr`)
REFERENCES `copies`(`copyNr`) ON DELETE RESTRICT ON UPDATE RESTRICT;
This however gives me this error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(`ISBN`),(`copyNr`)) REFERENCES `copies`(`copyNr`) ON DELETE RESTRICT ON UPDATE ' at line 1
Should i create another column that would contain tuples of(ISBN,CopyNr) first?If yes,how can this happen?If not,how can i solve this?
UPDATE:This is the code for copies:
CREATE TABLE IF NOT EXISTS `copies`
( `copyNr` int(11) NOT NULL AUTO_INCREMENT,
`shelf` text NOT NULL,
`ISBN` int(11) NOT NULL,
PRIMARY KEY (`copyNr`,`ISBN`) )
ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1

ALTER TABLE `borrows` ADD FOREIGN KEY (`ISBN`,`copyNr`)
REFERENCES `copies`(`ISBN`,`copyNr`) ON DELETE RESTRICT ON UPDATE RESTRICT;
You should have composite index (ISBN, copyNr) on table copies

Related

Error 1215 on adding foreign key. Help me with what I haven't tried

I'm trying to set a foreign key relationship between two existing table but for some reason which I'm missing I keep getting this error 1215.
The relevant fields of the two tables are:
CREATE TABLE `approvals` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_contract` int(11) NOT NULL,
`id_user` int(11) NOT NULL,
`lang` varchar(8) NOT NULL,
`request_ts` datetime NOT NULL,
`version` int(11) NOT NULL,
-- more nullable columns here with no indexing/relationships
PRIMARY KEY (`id`),
KEY `approval_id_user` (`id_user`),
KEY `version` (`version`,`lang`,`id_contract`),
CONSTRAINT `approval_id_user` FOREIGN KEY (`id_user`)
REFERENCES `users` (`iduser`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1079 DEFAULT CHARSET=utf8
CREATE TABLE `version` (
`idversion` int(11) NOT NULL,
`idcontract` int(11) NOT NULL,
`language` varchar(8) NOT NULL,
PRIMARY KEY (`idversion`,`idcontract`,`language`),
KEY `fk_version_contracts_idx` (`idcontract`),
CONSTRAINT `fk_kidversion_contracts` FOREIGN KEY (`idcontract`)
REFERENCES `contracts` (`id_contract`)
ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
What have I tried
First thing I checked is the persistency:
SELECT * FROM approvals a
WHERE NOT EXISTS (
SELECT 1 FROM version v
WHERE v.idcontract = a.id_contract AND v.language = a.lang
AND v.idversion = a.version);
which resulted in 0 rows returned out of 701, ok my db should be good from the data pov.
So I checked the collation and for some reason the version table was latin1 vs utf8_generic_ci, ok so I restored the version table to utf8 with this.
ALTER TABLE `kidversion`
COLLATE = utf8_general_ci;
-- and for good measure
ALTER TABLE `kidversion`
CHANGE COLUMN `language` `language` VARCHAR(8)
CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL;
But at this point I'm still getting an error while trying to create the foreign key:
ALTER TABLE `approvals`
ADD CONSTRAINT `approval_ibfk_1`
FOREIGN KEY (`version` , `lang` , `id_contract`)
REFERENCES `version` (`idversion` , `language` , `idcontract`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
And that results in a 1215 in every step I made. Surely I'm missing something.. can anyone help me out with this?
FOREIGN KEY (version , lang , id_contract) REFERENCES version (idversion , language , idcontract) AND PRIMARY KEY (idversion,idcontract,language) don't match fields have to be in the same order as well as same type.
'In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order.' - https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html

Mysql foreign key

When trying to create a table and alter it with the below query:
CREATE TABLE `sms_codes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`code` varchar(6) NOT NULL,
`status` int(1) NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
)
ALTER TABLE `sms_codes`
ADD CONSTRAINT `sms_codes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
I got the error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ALTER TABLE `sms_codes` ADD CONSTRAINT `sms_codes_ibfk_1` FOREIGN KEY (`user_' at line 11
Each statement need to separate by the delimiter ;. So add the ; in end of the CREATE TABLE in the same way how you added ; in end of the ALTER TABLE statement:
In this line:
KEY `user_id` (`user_id`)
); <-- here

Error #1064 near "REFERENCES" while adding a foreign key

I keep getting error 1064 while trying to create a foreign key:
ALTER TABLE `zajimavost`
ADD CONSTRAINT FK_zaj_bod
FOREIGN KEY def_bod
REFERENCES `bod`(`gid`)
ON UPDATE CASCADE ON DELETE CASCADE;
It complains:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'REFERENCES `bod`(`gid`)
ON UPDATE CASCADE ON DELETE CASCADE' at line 4
I tried it with or without the backticks, the problem is always the same.
My tables:
CREATE TABLE `zajimavost` (
`zaj_id` int(11) NOT NULL,
`lok_id` int(11) NOT NULL,
`nazev` varchar(255) COLLATE utf8_czech_ci NOT NULL,
`kategorie` int(11) NOT NULL DEFAULT '1',
`datace_od` int(11) NOT NULL DEFAULT '31',
`datace_do` int(11) NOT NULL DEFAULT '60',
`def_bod` int(11) DEFAULT NULL,
PRIMARY KEY (`zaj_id`),
KEY `ck_zaj_lok` (`lok_id`),
KEY `zaj_id` (`zaj_id`),
KEY `FK_zaj_kat` (`kategorie`),
KEY `FK_zaj_bod` (`def_bod`),
CONSTRAINT `FK_zaj_kat` FOREIGN KEY (`kategorie`) REFERENCES `kategorie` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_zaj_lok` FOREIGN KEY (`lok_id`) REFERENCES `lokalita` (`lok_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci
CREATE TABLE `bod` (
`gid` int(11) NOT NULL AUTO_INCREMENT,
`geom` point DEFAULT NULL,
`radius` int(4) NOT NULL DEFAULT '50',
PRIMARY KEY (`gid`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci
There are data in the tables.
So how to solve it?
You need to use () in child table column name while adding foreign key, Try this one
ALTER TABLE zajimavost
ADD CONSTRAINT FK_zaj_bod
FOREIGN KEY (def_bod) REFERENCES `bod`(`gid`)
ON UPDATE CASCADE ON DELETE CASCADE;

unable to create constraint in mysql table

I've got following tables:
node_sharing | CREATE TABLE `node_sharing` (
`user_id` int(11) NOT NULL,
`node_id` int(11) NOT NULL,
PRIMARY KEY (`user_id`,`node_id`),
KEY `fk_user_id_idx` (`user_id`),
KEY `fk_node_id_idx` (`node_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
and
users | CREATE TABLE `users` (
`id` int(11) NOT NULL,
`has_ard_access` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I would like to create following foreign key with a constraint:
ALTER TABLE `node_sharing`
ADD CONSTRAINT `fk_user_id`
FOREIGN KEY (`user_id` )
REFERENCES `users` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION;
and MySQL returns the following error:
ERROR 1005 (HY000): Can't create table 'MY_TABLE_NAME.#sql-4d0_218' (errno: 121)
What is wrong here?
PS node_sharing has been truncated, so there are no existing records that could disable putting the constraint on.
It is a duplicate key error. Did you have a table with same name before? If so, check InnoDB internal data dictionary. If not, check if you have another constraint with same name. Constraint names should be unique.

mysql alter table FOREIGN KEY!

(I using workbench) i have table questions with id, user_id, text and table users with fields id, name
I need to relate this 2 tables!
I write following:
ALTER TABLE `mydb_development`.`questions`
ADD CONSTRAINT fk_QueUsers_1
FOREIGN KEY (`user_id`)
REFERENCES `mydb_development`.`users`(`id`);
but i get:
ERROR 1046: No database selected
SQL Statement:
ALTER TABLE `questions`
ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
ERROR: Error when running failback script. Details follow.
ERROR 1046: No database selected
SQL Statement:
CREATE TABLE `questions` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL,
`text` text NOT NULL,
`security_token` varchar(40) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=373 DEFAULT CHARSET=utf8
ERROR 1046: No database selected
SQL Statement:
ALTER TABLE `questions`
ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
ERROR: Error when running failback script. Details follow.
.....................
EDIT:
I tried to do:
USE `mydb_development`;
ALTER TABLE `mydb_development`.`questions`
ADD CONSTRAINT `fk_QueUsers_1`
FOREIGN KEY (`user_id`)
REFERENCES `mydb_development`.`users`(`id`);
and i get error:
Error Code: 1005
Can't create table 'survey_development.#sql-4ad_45' (errno: 150)
DOnt understand:S
EDIT:
my user table:
DROP TABLE IF EXISTS `mydb_development`.`users`;
CREATE TABLE `mydb_development`.`users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
This seems to be mysql bug:
Read http://forums.mysql.com/read.php?22,19755,19755
Try to index the 'user_id' and run the script again.
Try selecting your database to see if it makes any difference
USE `mydb_development`;
First of all you want to get rid of the ERROR 1046: No database selected errors.
To do this make sure that you either:
Select a database with USE mydb_development;
Modify the ALTER/CREATE statements to include the db. E.g. ALTER TABLE mydb_development.questions
enter:
use `mydb_development`;
change the constraint name 'user_id' to something else like 'fk_user_id'