Can't link two tables? - mysql

I'm sure this is something ridiculously simple, but I can't get my head around it.
Every time I try running this script, I get error number 150. I know that this is a foreign key issue. My other tables are fine and link to the projectregister table with no problems, but for some reason nothing wants to link to the userchar table.
I'm running this on a college server, so I cant try show engine innoDB status.
Any ideas what's wrong here?
Thanks
CREATE TABLE `userchar` (
`userid` int(5) NOT NULL,
`charname` varchar(25) NOT NULL,
`charstats` varchar(255) DEFAULT NULL,
PRIMARY KEY (`userid`,`charname`),
CONSTRAINT `userchar_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `projectregister` (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `notes` (
`userid` int(5) NOT NULL DEFAULT '0',
`charname` varchar(25) NOT NULL,
`usernote` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`userid`,`charname`,`usernote`),
CONSTRAINT `notes_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `projectregister` (`userid`),
foreign key (charname) references userchar(charname)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

A foreign key must reference a unique value - be it a primary key or a plain old unique index.
Here, you are attempting to make notes.userid reference projectregister.userid. However, projectregister.userid is not a unique value - only the combination of projectregister.userid and projectregister.charname is unique.
You should either change the primary key or the foreign key definitions so that their column lists match.

Related

Simple Relation between 2 tables

I have a problem here.
I cannot add this to my db because one table is dependent of another and vice-versa.
So I get
Cannot add foreign key constraint
on the first create table that I put
How can I add this 2 tables if they both have constraints??
-- User Roles
CREATE TABLE IF NOT EXISTS `user_roles` (
`user_role_id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL,
`role` varchar(45) NOT NULL,
PRIMARY KEY (`user_role_id`),
UNIQUE KEY `uni_username_role` (`role`,`username`),
UNIQUE KEY `ix_auth_username` (`username`,`role`),
KEY `fk_username_idx` (`username`),
CONSTRAINT `fk_username` FOREIGN KEY (`username`) REFERENCES `users` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
-- Users
CREATE TABLE IF NOT EXISTS `users` (
`username` varchar(45) NOT NULL,
`name` varchar(45) DEFAULT NULL,
`hashedPassword` varchar(500) NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT '1',
`image` mediumblob,
`team` int(11) DEFAULT NULL,
`userRole` int(11) DEFAULT NULL,
PRIMARY KEY (`username`),
KEY `fkteam_idx` (`team`),
KEY `fkrole_idx` (`userRole`),
CONSTRAINT `fkrole` FOREIGN KEY (`userRole`) REFERENCES `user_roles` (`user_role_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fkteam` FOREIGN KEY (`team`) REFERENCES `team` (`idteam`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
To do this, you'll need to use deferrable constraint checks, but unfortunately MySQL does not implement this standard SQL feature.
As far as I know, only Oracle and PostgreSQL support this feature (deferrable constraints). These constraints are checked at the end of the transaction, and not on every single row insertion. That would solve your problem.
Therefore, you have two options:
Switch to Oracle or PostgreSQL (unlikely, I guess) or,
Change your table definition to allow one of the foreign key constraints to accept null values.
In the second case, you would:
Insert in the table that allow null in the FK, getting the generated ID.
Insert in the other table using the ID. Then, get the second generated ID.
Update the null in first table using the second ID.
Commit.
That's it.

Can't Constrain Both Junction Table Columns

I have a juction table that contains two foreign keys (from Profiles and Districts tables), with both columns as a composite primary key.
`profID` int(11) NOT NULL,
`distID` varchar(8) NOT NULL,
PRIMARY KEY (`profID`,`distID`)
I'd like to constrain both columns, but MySql throws an error:
#1050 - Table './database_name/z#002dprof#002ddist' already exists
In troubleshooting the problem, I've tried creating another duplicate junction table from scratch, but I get the same error. Oddly, MySQL will allow me to constrain one column or the other, but not both columns. I'm stumped, since I have other (non-junction) tables that have constraints on more than one foriegn key column.
By the way, I'm using phpMyAdmin, and all tables are InnoDB with utf-8.
Any help would be appreciated.
ADDED: SHOW CREATE TABLE results
CREATE TABLE `Profiles` (
`profID` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(64) NOT NULL,
`stID` varchar(2) NOT NULL,
`zip` varchar(5) NOT NULL,
PRIMARY KEY (`profID`),
KEY `stID` (`stID`,`zip`),
KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=utf8
CREATE TABLE `Districts` (
`distID` varchar(8) NOT NULL,
`stID` varchar(2) NOT NULL,
`abbrev` varchar(16) NOT NULL,
PRIMARY KEY (`distID`),
KEY `stID` (`stID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `z-prof-dist` (
`profID` int(11) NOT NULL,
`distID` varchar(8) NOT NULL,
PRIMARY KEY (`profID`,`distID`),
KEY `distID` (`distID`),
KEY `profID` (`profID`),
CONSTRAINT `z-prof-dist_ibfk_1` FOREIGN KEY (`distID`) REFERENCES `Districts` (`distID`)
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I think I found a fix. Rather than using the phpMyAdmin function for adding a constraint (where I kept getting the error message), I instead followed marekful's lead by using an SQL ALTER TABLE query (with a new constraint name) as such:
ALTER TABLE `z-prof-dist`
ADD CONSTRAINT `test1`
FOREIGN KEY (`profID`) REFERENCES `Profiles` (`profID`)
ON UPDATE CASCADE
I still don't understand the cause of the original error, but I can see that the newly added foreign key constraint is working perfectly.

MySQL foreign key restrictions are not being saved

I'm using MySQL version 5.5.25 and trying to create a foreign key from id_parent to id on the same table.
CREATE TABLE `acl_roles` (
`id` int(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(60) NOT NULL,
`id_parent` int(20) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_acl_roles` (`id_parent`),
CONSTRAINT `FK_acl_roles` FOREIGN KEY (`id_parent`) REFERENCES `acl_roles` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
When I do
ALTER TABLE `acl_roles` ADD CONSTRAINT `FK_acl_roles` FOREIGN KEY (`id_parent`) REFERENCES `acl_roles` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ;
For some reason the latter executes without error yet when I execute SHOW CREATE TABLE acl_roles I get the exact same schema and the restrictions are not applied no matter how many times I run the query.
ON DELETE RESTRICT ON UPDATE RESTRICT is the default behavior for FK constraints, that is why you see no difference when viewing the schema. It is implied.

MySQL primary key column is not unique?

I have the following table in a MySQL database:
CREATE TABLE `datavalues` (
`ValueID` int(11) NOT NULL AUTO_INCREMENT,
`DataValue` double NOT NULL,
`ValueAccuracy` double DEFAULT NULL,
`LocalDateTime` datetime NOT NULL,
`UTCOffset` double NOT NULL,
`DateTimeUTC` datetime NOT NULL,
`SiteID` int(11) NOT NULL,
`VariableID` int(11) NOT NULL,
`OffsetValue` double DEFAULT NULL,
`OffsetTypeID` int(11) DEFAULT NULL,
`CensorCode` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'nc',
`QualifierID` int(11) DEFAULT NULL,
`MethodID` int(11) NOT NULL DEFAULT '0',
`SourceID` int(11) NOT NULL,
`SampleID` int(11) DEFAULT NULL,
`DerivedFromID` int(11) DEFAULT NULL,
`QualityControlLevelID` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ValueID`),
UNIQUE KEY `DataValues_UNIQUE_DataValues` (`DataValue`,`ValueAccuracy`,`LocalDateTime`,`UTCOffset`,`DateTimeUTC`,`SiteID`,`VariableID`,`OffsetValue`,`OffsetTypeID`,`CensorCode`,`QualifierID`,`MethodID`,`SourceID`,`SampleID`,`DerivedFromID`,`QualityControlLevelID`),
KEY `FK_DataValues_Sites` (`SiteID`),
KEY `FK_DataValues_Sources` (`SourceID`),
KEY `FK_DataValues_QualityControlLevels` (`QualityControlLevelID`),
KEY `FK_DataValues_OffsetTypes` (`OffsetTypeID`),
KEY `FK_DataValues_CensorCodeCV` (`CensorCode`),
KEY `FK_DataValues_Variables` (`VariableID`),
KEY `FK_DataValues_Methods` (`MethodID`),
KEY `FK_DataValues_Qualifiers` (`QualifierID`),
KEY `FK_DataValues_Samples` (`SampleID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
ALTER TABLE `datavalues`
ADD CONSTRAINT `FK_DataValues_Sites` FOREIGN KEY (`SiteID`) REFERENCES `sites` (`SiteID`) ON DELETE NO ACTION ON UPDATE CASCADE,
ADD CONSTRAINT `FK_DataValues_Sources` FOREIGN KEY (`SourceID`) REFERENCES `sources` (`SourceID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_DataValues_QualityControlLevels` FOREIGN KEY (`QualityControlLevelID`) REFERENCES `qualitycontrollevels` (`QualityControlLevelID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_DataValues_OffsetTypes` FOREIGN KEY (`OffsetTypeID`) REFERENCES `offsettypes` (`OffsetTypeID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_DataValues_CensorCodeCV` FOREIGN KEY (`CensorCode`) REFERENCES `censorcodecv` (`Term`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_DataValues_Variables` FOREIGN KEY (`VariableID`) REFERENCES `variables` (`VariableID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_DataValues_Methods` FOREIGN KEY (`MethodID`) REFERENCES `methods` (`MethodID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_DataValues_Qualifiers` FOREIGN KEY (`QualifierID`) REFERENCES `qualifiers` (`QualifierID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_DataValues_Samples` FOREIGN KEY (`SampleID`) REFERENCES `samples` (`SampleID`) ON DELETE NO ACTION ON UPDATE NO ACTION;
When I open my database in PhpMyAdmin 4.0.3 and run a query:
SELECT MAX(DateTimeUTC) from `datavalues`
the query executes but PhpMyAdmin shows a
warning:
This table does not contain a unique column. Grid edit, checkbox,
Edit, Copy and Delete features are not available.
How is it possible? I thought that if I have one column with PRIMARY KEY constraint then the column is UNIQUE. Could this be a bug in PhpMyAdmin? I'm confused.
I found the answer: The warning:
This table does not contain a unique column. Grid edit, checkbox,
Edit, Copy and Delete features are not available.
applies to the current result set and not to the original table.
Álvaro G. Vicario's comment is right.
This appears to be a new thing in PhpMyAdmin 4.0.4 and I find this type of message more confusing than useful.
All you got to do is add a unique column like one called id with a index = PRIMARY like the pic, or if you have one already that is called id that are numbers just make it PRIMARY

What does it change between this two way of declaring a foreign key?

Good morning, I'm studing the SQL, and today I've found two ways of declaring a foreign key (for MySQL). I'd like to know what does it change between that two syntax and why should I need to set a name for the foreign key (Syntax 2).
Syntax 1:
CREATE TABLE `test2` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`idtest` int(10) unsigned NOT NULL,
`desc` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`idtest`) REFERENCES `test` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Syntax 2:
CREATE TABLE `test2` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`idtest` int(10) unsigned NOT NULL,
`desc` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_1` (`idtest`),
CONSTRAINT `FK_1` FOREIGN KEY (`idtest`) REFERENCES `test` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Thank you!
Functionally there is no difference.
The first example does name the Foreign Key, but it's the RDBMS that does the naming.
The second example lets you expressly name the Foreign Key yourself.
The ability to name the Foreign Key yourself allows you to communicate to other developers what the key means, and conform to standard naming conventions, etc.
The second syntax enables you to delete, modify or reuse that constraint at some point in the future.
The first syntax can not be changed as it is in the definition of the table.
The optional CONSTRAINT keyword allows you to specify a name for the foreign key. Without it, a name will be generated automatically.
This name can be seen in the INFORMATION_SCHEMA TABLE_CONSTRAINTS table.