configure so that no records can be the same - mysql

I remember in my work in past projects I have ran across a MySQL error message that stated that no records can be the same ( all columns ) because then they cannot be individually selected. Unfortunately my MySQL doesn't give me this error and I have a problem.
I have a table to store a user's favorite topics ( or articles if you will ) which is fairly simple
CREATE TABLE `ad_favorites` (
`ad_id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
KEY `ad_id` (`ad_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `ad_favorites_ibfk_1` FOREIGN KEY (`ad_id`) REFERENCES `ad` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `ad_favorites_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I need to not be able to insert two same records and get an error in case there is such an attempt so that in my php my affected_rows property will show 0.
Long story short if I have a record and I try to insert it again I must get a MySQL error, is it possible?

make the two columns a composite primary key,
PRIMARY KEY (ad_id, user_id)

Related

Prevent Duplicate Entries Composite Index

I have a Relationships table that I am trying to add a composite index to:
CREATE UNIQUE INDEX idx_relationship_userid_friend_id on Relationships(user_id, friend_id);
I would like to prevent duplicate entries for user_id and friend_id columns. i.e. Second entry of user_id = 26 and friend_id = 46 should give an error.
I ran the command above. When I run the command again, I get the following error:
Duplicate entry '36-50' for key 'idx_relationship_userid_friend_id'
When I look at the structure in for INDEXES I see the following table:
Under table info next to Create syntax, I have the following code:
CREATE TABLE `Relationships` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`friend_id` int(11) DEFAULT NULL,
`status` int(11) DEFAULT '1',
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
`user_id` int(11) DEFAULT NULL,
`app_common` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `owner_id` (`user_id`),
KEY `app_common` (`app_common`),
CONSTRAINT `Relationships_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `Users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `Relationships_ibfk_2` FOREIGN KEY (`app_common`) REFERENCES `AppCommon` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=79 DEFAULT CHARSET=latin1;
However, I am able to insert duplicate records in the database.
Question: How can I avoid duplicate entries?
Since your table already has duplicates, it gets an error trying to create the index, so it doesn't add it.
See How to delete duplicates on a MySQL table? for how to remove duplicates. Once you've done that you can add the unique index to prevent new duplicates from being added.
Use the Unique constraint to handle your issue, something like:
CONSTRAINT UC_user_friend UNIQUE (user_id, friend_id)

Inconsistent honoring of foreign key constraint

We have the following schema (simplified for readability):
CREATE TABLE `group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `device` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `group_id` (`group_id`),
CONSTRAINT `device_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Our automated tests create a device referencing an existing group and then attempt to delete the group, which fails due to the default ON DELETE RESTRICT clause:
Error 1451: Cannot delete or update a parent row: a foreign key constraint fails
(`device`, CONSTRAINT `device_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `group`
(`id`))
However, around 25% of the time, the deletion of the group succeeds, despite the foreign key constraint. This leads to data inconsistency, where we have a device row referencing a group_id which does not exist.
MySQL version is 5.7.10, running the official Docker image
Tables are InnoDB
FOREIGN_KEY_CHECKS is set to 1
Any ideas why the enforcement of the foreign key constraint could be inconsistent?
This was caused by a test fixture library (https://github.com/go-testfixtures/testfixtures) which disabled foreign key checks

Attempting to add a foreign key to a table fails?

I have two tables -
CREATE TABLE `FOO` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
/*Nothing to see here*/
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=380 DEFAULT CHARSET=latin1;
CREATE TABLE `BAR` (
`ID` int(11) unsigned NOT NULL,
`UserID` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `VSK_UserID_Index` (`UserID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I am attempting create a foreign key constraint on BAR.UserID referencing users.user_id -
ALTER TABLE `FOO`.`BAR`
ADD CONSTRAINT `BAR_UserID_FKey`
FOREIGN KEY (`UserID`)
REFERENCES `FOO`.`users` (`user_id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
I keep getting this error -
Operation failed: There was an error while applying the SQL script to the database.
Error 1452: Cannot add or update a child row: a foreign key constraint fails
Both of these tables have data in them - could this be the reason why this is happening, or is there something wrong with how the tables are being created?
Is there something I need to alter on one of these tables to make this work?
The data already in one of the tables (in particular, `FOO`.`BAR`, since that is the one you're adding a constraint to) is not consistent with the data in `FOO`.`users` (`user_id`).
You must ensure that the values un the `FOO`.`BAR`.`UserID` column all exist in `FOO`.`users` (`user_id`). There may be null values or other values that do not exist in the other column.

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.

Foreign key doesn't keep data consistency

Many days ago I made a database which had two tables:
member(member_id(PK),name)
account(account_id(PK),member_id(FK),amount).
So Normally I cant DELETE any member if member have balance in account table . Before it was work well.
But today I import same script and I can delete a member even member have balance in account table.
I don't know what happends? I don't remember previous server version of mysql. Now I am running mysql 5.5.16 and MySQL client version is mysqlnd 5.0.8-dev - 20102224 - Revision: 310735 in localhost.
my code is
//account table
CREATE TABLE IF NOT EXISTS `account` (
`account_id` int(11) NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL,
`dates` date NOT NULL,
`amount` float NOT NULL,
PRIMARY KEY (`account_id`),
KEY `FK_account_1` (`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
//member table
CREATE TABLE IF NOT EXISTS `member` (
`member_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`account_num` int(11) NOT NULL,
PRIMARY KEY (`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=34 ;
//and this code
ALTER TABLE `account`
ADD CONSTRAINT `FK_account_1`
FOREIGN KEY (`member_id`)
REFERENCES `member`(`member_id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
I'm not sure if I understand this well but:
The constraint you have means that every time you delete a member, the member will be deleted together with any balance it has in the account table. (ON DELETE CASCADE)
If this is not your desired behavior, and you want mysql to raise an exception when deleting a member that has a balance; then just remove the ON DELETE CASCADE line from your constraint definition.
ALTER TABLE account
ADD CONSTRAINT `fk_account_member`
FOREIGN KEY (`member_id`)
REFERENCES `member` (`member_id`)
ON DELETE CASCADE
ON UPDATE CASCADE;