MySQL:ERROR 1215: Cannot add foreign key constraint - mysql

I've been trying to follow a tutorial that I've came across, which is about spring security. In some place, I need to create 2 tables in my database which is user and authorities. While doing this, I am using this script that is suggested like in the tutorial. http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-schema.html
I've already a user table in my db, so I just need to add autohirites table. Since I'm using MySQL, I've changed that query like below:
create table authorities (
username varchar(70) not null,
authority varchar(50) not null,
CONSTRAINT fk_authorities_users foreign key(username) references user(userFirstName));
create unique index ix_auth_username on authorities (username,authority);
Also, here is my user table too:
CREATE TABLE `user` (
`userId` INT(11) NOT NULL AUTO_INCREMENT,
`userFirstName` VARCHAR(70) NOT NULL,
`userLastName` VARCHAR(70) NOT NULL,
`userEmail` VARCHAR(70) NOT NULL,
`userAddress` VARCHAR(500) NULL DEFAULT NULL,
`userPhoneNumber` INT(13) NULL DEFAULT NULL,
`isActive` BINARY(50) NULL DEFAULT '1\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0',
`userPassword` VARCHAR(50) NOT NULL,
`userConfirmPassword` VARCHAR(50) NOT NULL,
PRIMARY KEY (`userId`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2
;
When I try to run my first query which is going to create authorities table, I am getting ERROR 1215: Cannot add foreign key constraint error.
So far, I've been looked into these questions below, but none of them answered my problem + I think they are both the same questions:
MySQL Cannot Add Foreign Key Constraint
MySQL Error 1215: Cannot add foreign key constraint

Try making userFirstName column unique.

You haven't mentioned what the engine is for authorities, your user table does not have a unique index on userFirstName that would mean authoritiest would need to be INNODB. because:
InnoDB allows a foreign key constraint to reference a non-unique key.
This is an InnoDB extension to standard SQL.
But I don't recommend this at all, it's always best to have a foreign key referencing a PRIMARY KEY, where that's not possible another unique key.
What you should really do is change your table as follows:
CREATE TABLE authorities (
userid INT(11) not null,
authority varchar(50) not null,
CONSTRAINT fk_authorities_users foreign key(username) references user(userid));
create unique index ix_auth_username on authorities (username,authority));
By doing so you are referencing a PRIMARY KEY but more importantly reducing a great deal of redundancy from your tables. There is absolutely no point in having the same ~70 character field repeated in both tables.

Related

Unable to create foreign key in database

I am trying to create a table with a varchar column as foreign key but MySQL gives me an error while creating the table. My query is like this:
CREATE TABLE `survey_hesco_subdivision` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`circle_code` VARCHAR(100) DEFAULT NULL,
`name` VARCHAR(100) DEFAULT NULL,
`circle_name` VARCHAR(100) DEFAULT NULL,
`division_code` VARCHAR(100) DEFAULT NULL,
`sub_div_code` VARCHAR(100) NOT NULL,
`division_name` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`,`sub_div_code`),
KEY `id` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=91 DEFAULT CHARSET=latin1;
The above table is already in used
Create table `accurate_mam`.`meter_ping`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`meter_id` int(11) NOT NULL,
`meter_msn` varchar(100),
`sub_div_code` varchar(100) NOT NULL,
`sub_div_name` varchar(100),
primary key (`id`),
constraint `FK_PING_METER_ID` foreign key (`meter_id`) references
`accurate_mam`.`meters`(`id`) on delete Cascade,
constraint `FK_PIN_SUB_DIV` foreign key (`sub_div_code`) references
`accurate_mam`.`survey_hesco_subdivision`(`sub_div_code`) on delete Cascade
) ENGINE=InnoDB charset=latin1 collate=latin1_swedish_ci
The error I am getting is
Error Number : 1005
Error Message: Can't create table accurate_mam.meter_ping (errno: 150 "Foreign key constraint is incorrectly formed")
I have already looked into this question
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order.
InnoDB permits a foreign key to reference any index column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
So, just create a index like this, before creating child table :
CREATE INDEX `idx_survey_hesco_subdivision_sub_div_code` ON survey_hesco_subdivision(sub_div_code);
Although, It is not best practice to use non-unique column as reference columns in relationship. DELETE CASCADE will not behave properly in that case. I will suggest you create a unique key on sub_div_code of primary table as well.
For more details, refere to this
Source : Cannot add foreign key - StackOverflow
Have you already run CREATE TABLE meters? There error is caused by that table being missing. Let's see that CREATE.

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.

Can't link two tables?

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.

Database model for hierarchy Country - Organization - Suborganization - User

Good day, I need to create an organizational structure which should support following hierarchies:
Country - Organization - User
Country - Organization - Suborganization - User
I thought about having three tables. Table Country (column id is three-letter ISO 3166-1 alpha-3):
CREATE TABLE `country` (
`id` CHAR(3) NOT NULL,
`country` VARCHAR(40) NOT NULL,
PRIMARY KEY (`id`)
);
Table Organization:
CREATE TABLE `organization` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`country_id` CHAR(3) NOT NULL,
`parent_id` INT(11) NULL DEFAULT NULL,
`name` VARCHAR(40) NOT NULL,
PRIMARY KEY (`id`),
INDEX `idx_organization_1` (`parent_id` ASC),
CONSTRAINT `fk_customer_country_1`
FOREIGN KEY (`country_id`)
REFERENCES `country` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_organization_organization_1`
FOREIGN KEY (`parent_id`)
REFERENCES `organization` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
);
Table User:
CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`organization_id` INT(11) NULL DEFAULT NULL,
`username` VARCHAR(45) NOT NULL,
`password` CHAR(32) NOT NULL,
PRIMARY KEY (`id`),
INDEX `idx_user_organization_1` (`organization_id` ASC),
CONSTRAINT `fk_user_organization_1`
FOREIGN KEY (`organization_id`)
REFERENCES `organization` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE);
Table Country exists to prevent an organization be assigned an unsupported country code. I don't want to use MySql's enum. Although I'm working with MySql currently I need my schema to be independent on the specific DB.
Is this good design or is there a better one? I doubt because of following questions. I can do it "somehow" but I'd like to know best practice approach.
A suborganization has a country code foreign key but country code is allready specified in the parent organization. I feel it's a kind of duplicity.
If I delete a row in table country will cascade delete fail if the DB attempts to delete suborganization before deleting it's parent organization?
Is null in foreign keys supported by all DBs? Organizations have null parent_id but parent_id is used in the self referencing forign key fk_organization_organization_1.
Country code used in foreign keys is CHAR(3). Would it be faster is it would be INT(3)?
I'd appreciate any ideas. Many thanks. Vojtech
I would make country_id nullable to avoid such duplication. Also
you can implement some application-level control to assure that at
least one of (country_id, parent_id) is not null.
Deletion must
be successfull as long as the both references defined with "ON
DELETE CASCADE" clause
All the DBs I have worked with support
nullable foreign keys: Oracle, DB2, MySQL, SQL Server, Postgre
The difference is most probably negligible

MySQL Error 1215: Cannot add foreign key constraint, innodb, new tables

I like to add foreign keys, this table, but not work! If I try new tables not work, but other, old tables it works. What's the problem?
CREATE TABLE `tanora` (
`idtanora` int(11) NOT NULL,
`tema` varchar(250) NULL,
`megjegyzes` varchar(255) DEFAULT NULL,
`datum` date NOT NULL,
`osztaly` varchar(20) NOT NULL,
`megtartott` int(11) NOT NULL,
`targy` varchar(45) NOT NULL,
`kezdete` time NOT NULL,
`vege` time NOT NULL,
PRIMARY KEY (`idtanora`),
UNIQUE KEY `idtanora_UNIQUE` (`idtanora`),
KEY `osztazon_idx` (`osztaly`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_hungarian_ci;
CREATE TABLE `osztaly` (
`osztalyazon` varchar(20) NOT NULL,
`osztalyfonokazon` varchar(11) NOT NULL,
`osztalynev` varchar(45) NOT NULL,
`indul` year(4) NOT NULL,
PRIMARY KEY (`osztalyazon`),
UNIQUE KEY `osztalyazon_UNIQUE` (`osztalyazon`),
KEY `ofazon_idx` (`osztalyfonokazon`),
CONSTRAINT `tanarazon01` FOREIGN KEY (`osztalyfonokazon`) REFERENCES `tanar` (`szemelyiszam`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_hungarian_ci;
ERROR 1215: Cannot add foreign key constraint
SQL Statement:
ALTER TABLE `enaplo`.`tanora`
ADD CONSTRAINT `osztalyra`
FOREIGN KEY (`osztaly`)
REFERENCES `enaplo`.`osztaly` (`osztalyazon`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
ERROR: Error when running failback script. Details follow.
ERROR 1050: Table 'tanora' already exists
SQL Statement:
CREATE TABLE `tanora` (
`idtanora` int(11) NOT NULL,
`tema` varchar(250) NOT NULL,
`megjegyzes` varchar(255) DEFAULT NULL,
`datum` date NOT NULL,
`osztaly` varchar(20) NOT NULL,
`megtartott` int(11) NOT NULL,
`targy` varchar(45) NOT NULL,
`kezdete` time NOT NULL,
`vege` time NOT NULL,
PRIMARY KEY (`idtanora`),
UNIQUE KEY `idtanora_UNIQUE` (`idtanora`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_hungarian_ci
foreign key (osztaly)
references enaplo.osztaly (osztalyazon)
on delete no action
on update no action:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables. See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Make sure that you have consistent column definitions:
In your referencing table osztaly the foreign key column osztalyfonokazon needs to be defined with the exact same characteristics as applied to the referenced field in the tanar table.
Currently, osztalyfonokazon in osztaly is defined as follows:
`osztalyfonokazon` VARCHAR(11) NOT NULL
So, then in the tanar table the szemelyiszam definition should look like either
`szemelyiszam` VARCHAR(11) PRIMARY KEY
or
`szemelyiszam` VARCHAR(11) UNIQUE KEY NOT NULL
Depends on your needs.
Either way, ensure that szemelyiszam is a PRIMARY KEY or at least a UNIQUE KEY that is declared NOT NULL in the referenced tanar table.
Additionally, MySQL requires that the referenced columns be indexed
for performance reasons. However, the system does not enforce a
requirement that the referenced columns be UNIQUE or be declared NOT
NULL. The handling of foreign key references to nonunique keys or keys
that contain NULL values is not well defined for operations such as
UPDATE or DELETE CASCADE. You are advised to use foreign keys that
reference only UNIQUE (including PRIMARY) and NOT NULL keys.
Source