How to restrict inserting duplicate pairs of values in a table? - mysql

I have the following table in MySQL DB (MariaDB):
CREATE TABLE `restrictions_projects` (
`ID` int(11) NOT NULL,
`project_id` int(11) NOT NULL,
`restriction_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `restrictions_projects`
ADD PRIMARY KEY (`ID`),
ADD KEY `project_id` (`project_id`),
ADD KEY `restriction_id` (`restriction_id`);
ALTER TABLE `restrictions_projects`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `restrictions_projects`
ADD CONSTRAINT `restrictions_prfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`ID`),
ADD CONSTRAINT `restrictions_prfk_2` FOREIGN KEY (`restriction_id`) REFERENCES `restrictions` (`ID`);
COMMIT;
How can I restrict inserting duplicate pairs of project_id and restriction_id?
INSERT INTO restrictions_projects (project_id,restriction_id)
VALUES (1,2) // ??? ON DUPLICATE KEY UPDATE project_id=1 AND
restriction_id=2

Add a unique constraint:
ALTER TABLE restrictions_projects
ADD CONSTRAINT unq_restrictions_2 UNIQUE(project_id, restriction_id);
You can also do this using a unique index, which is effectively the same thing.

You need composite unique key on both column
UNIQUE (project_id,restriction_id)
You should alter your table to add unique key
ALTER TABLE restrictions_projects ADD CONSTRAINT restrictions_projects_uniq UNIQUE (project_id,restriction_id)

Related

MySQL alter two column for same foreign key

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;

Making foreign key to unique index column in mysql

Products
CREATE TABLE if NOT EXISTS `PRODUCTS` (
`ID` INT unsigned NOT NULL AUTO_INCREMENT,
`COMPANY_ID` INT(10) unsigned NOT NULL,
`PRODUCT_CODE` VARCHAR(5) NOT NULL,
`PRODUCT_NAME` VARCHAR(15) NOT NULL,
`UNIT_TYPE` VARCHAR(1) NULL,
UNIQUE INDEX UNIQUE_COMAPNY_PRODUCT_CODE (`COMPANY_ID`, `PRODUCT_CODE`),
CONSTRAINT `PRODUCT_COMPANY_ID_FK` FOREIGN KEY (`COMPANY_ID`) REFERENCES `companies` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
)
and i want to make a foreign key to the upper 'PRODUCT_CODE' ......
here is my code
ALTER TABLE services
ADD COLUMN `PRODUCT_CODE` VARCHAR(5),
// ADD foreign `PRODUCT_CODE` that refrences to `PRODUCT_CODE` in PRODUCTS table
So how to do the commented line above in mysql ??
The column referenced in a foreign key may be either a Primary Key or Unique. You need to first add an index on PRODUCT_CODE. I have taken it as UNIQUE
ALTER TABLE PRODUCTS ADD UNIQUE INDEX (PRODUCT_CODE);
Then, you can use ALTER TABLE .. ADD FOREIGN KEY syntax:
ALTER TABLE services
ADD FOREIGN KEY (PRODUCT_CODE) REFERENCES PRODUCTS(PRODUCT_CODE);
Combining this to your existing ALTER TABLE query, a single query would look as follows:
ALTER TABLE services
ADD COLUMN `PRODUCT_CODE` VARCHAR(5),
ADD FOREIGN KEY (PRODUCT_CODE) REFERENCES PRODUCTS(PRODUCT_CODE);
If you already have some data in the services table, which has certain PRODUCT_CODE value, which do not exist in the PRODUCTS table. You will get the following error:
Error Code: 1215. Cannot add foreign key constraint
In that case, you will need to fix the data in the tables. You may check this answer for the tips: https://stackoverflow.com/a/53099922/2469308

Foreign key Integrity constraint violation: 1452

I've recently started trying to use foreign keys to make database management easier on myself. I'm having a terrible time trying to figure out how they actually work, and most of the time I can get it working between tables without issue. But I'm currently having an issue with 2 of my tables, and I can't figure it out.
I'm getting an error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(REDACTED.rc_logs, CONSTRAINT rc_logs_ibfk_1 FOREIGN
KEY (user_id) REFERENCES rc_teammates (uid) ON DELETE CASCADE ON
UPDATE CASCADE)
[/home5/redacted/public_html/redacted/rc/public/assets/php/connection.php:25]
but my tables seem to be set up properly, and I'm really confused about why it's not working. Here is my table structures:
rc_teammates
CREATE TABLE `rc_teammates` (
`uid` int(11) NOT NULL,
`name` text NOT NULL,
`primary_line` int(11) NOT NULL,
`hireStatus` text NOT NULL,
`created_on` date NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `rc_teammates`
ADD PRIMARY KEY (`uid`), ADD UNIQUE KEY `uid` (`uid`), ADD KEY `primary_line` (`primary_line`), ADD KEY `primary_line_2` (`primary_line`);
ALTER TABLE `rc_teammates`
MODIFY `uid` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `rc_teammates`
ADD CONSTRAINT `rc_teammates_ibfk_1` FOREIGN KEY (`primary_line`) REFERENCES `rc_lines` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE;
rc_logs
CREATE TABLE IF NOT EXISTS `rc_logs` (
`uid` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`line` int(11) NOT NULL,
`date` date NOT NULL,
`type` varchar(15) NOT NULL,
`timein` time NOT NULL,
`timeout` time NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=latin1;
ALTER TABLE `rc_logs`
ADD PRIMARY KEY (`uid`), ADD KEY `user_id` (`user_id`), ADD KEY `line` (`line`), ADD KEY `user_id_2` (`user_id`);
ALTER TABLE `rc_logs`
MODIFY `uid` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=53;
ALTER TABLE `rc_logs`
ADD CONSTRAINT `rc_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `rc_teammates` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `rc_logs_ibfk_2` FOREIGN KEY (`line`) REFERENCES `rc_lines` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE;
I've tried to look up the error, and I've had this issue before but I do not remember how I solved it. What's worse is, this was working earlier, until I emptied the rc_teammates table to start fresh.
I really cannot figure this out, and would love any pointers. Thanks!
As you said you have "emptied" (TRUNCATE?) the table rc_teammates.
And you try to insert a record in rc_logs, and this record has a user_id that doesn't exists in rc_teammates, thus violation of the following constraint:
ADD CONSTRAINT `rc_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `rc_teammates` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
Just add a record in rc_teammates, having a uid equal to the user_id of the record you are trying to insert in rc_logs, and retry.
Also, about this :
ALTER TABLE `rc_teammates`
ADD PRIMARY KEY (`uid`), ADD UNIQUE KEY `uid` (`uid`),
ALTER TABLE `rc_teammates`
MODIFY `uid` int(11) NOT NULL AUTO_INCREMENT;
When you set a column as PRIMARY KEY, it is de facto : UNIQUE, NOT NULL and INDEXED. You don't need to specify all this, PRIMARY KEY is enough. This is valid for your other table as well.

MySQL Error Number: 1452 (unusual case)

I tried adding a Foreign Key using this query:
ALTER TABLE `StripeBilling`
ADD CONSTRAINT `StripeBillingPatientRef`
FOREIGN KEY (PatientRef)
REFERENCES `Patient`(`PatientId`)
ON DELETE SET NULL;
My tables mysql_dump is:
CREATE TABLE IF NOT EXISTS `StripeBilling` (
...
`PatientRef` int(10) unsigned DEFAULT NULL,
...
) ENGINE=InnoDB AUTO_INCREMENT=10000000 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `StripeBilling`
ADD PRIMARY KEY (`StripeBillingId`), ADD KEY `StripeBillingAgentRef` (`AgentRef`), ADD KEY `PatientRef` (`PatientRef`);
ALTER TABLE `StripeBilling`
MODIFY `StripeBillingId` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=10000000;
ALTER TABLE `StripeBilling`
ADD CONSTRAINT `StripeBillingAgentRef` FOREIGN KEY (`AgentRef`) REFERENCES `Agent` (`AgentId`) ON DELETE SET NULL;
And patient's table is:
CREATE TABLE IF NOT EXISTS `Patient` (
`PatientId` int(10) unsigned NOT NULL,
...
) ENGINE=InnoDB AUTO_INCREMENT=10000000 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `Patient`
ADD PRIMARY KEY (`PatientId`), ADD UNIQUE KEY `PatientSerial` (`PatientSerial`);
ALTER TABLE `Patient`
MODIFY `PatientId` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=10000000;
But MySQL returns an error:
Cannot add or update a child row: a foreign key constraint fails
(newportal_enc.#sql-3863_9f, CONSTRAINT StripeBillingPatientRef
FOREIGN KEY (PatientRef) REFERENCES Patient (PatientId) ON
DELETE SET NULL)
I'm confused because table newportal_enc.#sql-3863_9f does not exist in my database.
This is not due to the presence of the PatientRef index, becouse after removing of this index my issue still exists.
Why am I getting this error and how can I solve it?

mysql - not able to add foreign key constraint after changing column name

I was changing column name of a column having foreign key constraint, i have done this by
ALTER TABLE `city_details` DROP FOREIGN KEY `tb_city_details_ibfk_1`;
ALTER TABLE `city_details` CHANGE `city_state_id` `city_district_id` int(8) NOT NULL AFTER `city_name`;
now while adding constraint back i'm getting error
1452 - Cannot add or update a child row: a foreign key constraint fails (testdb.#sql-39a8_23, CONSTRAINT city_details_ibfk_1 FOREIGN KEY (city_district_id) REFERENCES district_details (district_id) ON DELETE CASCADE ON UPDATE CASCADE)
i have used this query to add constraint
ALTER TABLE `city_details` ADD CONSTRAINT `city_details_ibfk_1` FOREIGN KEY (`city_district_id`) REFERENCES `district_details`(`district_id`) ON UPDATE CASCADE ON DELETE CASCADE;
SHOW CREATE TABLE city_details
CREATE TABLE `city_details` (
`city_id` int(8) NOT NULL AUTO_INCREMENT,
`city_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`city_district_id` int(8) NOT NULL,
PRIMARY KEY (`city_id`),
KEY `city_state_id` (`city_district_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Got the issue district_details table was empty but city_details table had few values, after adding values to district_details it is working fine