CREATE TABLE Friends_Relations(
buddy_id VARCHAR(255) NOT NULL,
mate_id VARCHAR(255) NOT NULL,
PRIMARY KEY (buddy_id, mate_id),
FOREIGN KEY (buddy_id) REFERENCES Users(id) ON DELETE CASCADE,
FOREIGN KEY (mate_id) REFERENCES Users(id) ON DELETE CASCADE
);
There's this mutual friendship relation where (friend_A, friend_B) is the same as (friend_B, friend_A).
I've tried adding a unique key, but it was to no avail:
ALTER TABLE Friends_Relation ADD UNIQUE KEY (mate_id, buddy_id);
Is there a way to avoid these permutations ?
You can do:
create table friends_relations (
buddy_id varchar(255) not null,
mate_id varchar(255) not null,
constraint uq1 unique (
(least(buddy_id, mate_id)), (greatest(buddy_id, mate_id))
),
primary key (buddy_id, mate_id)
);
Then if it won't accept symmetric rows:
insert into friends_relations (buddy_id, mate_id) values (456, 123);
insert into friends_relations (buddy_id, mate_id) values (123, 456); -- fails
See running example at db<>fiddle.
There's also another trick. What you can alternatively do is to enforce buddy_id < mate_id. This, however, will restrict the way you insert data. For example you can do:
CREATE TABLE Friends_Relations (
buddy_id VARCHAR(255) NOT NULL,
mate_id VARCHAR(255) NOT NULL,
PRIMARY KEY (buddy_id, mate_id),
FOREIGN KEY (buddy_id) REFERENCES Users(id) ON DELETE CASCADE,
FOREIGN KEY (mate_id) REFERENCES Users(id) ON DELETE CASCADE,
constraint ck1 CHECK (buddy_id < mate_id) -- added constraint
);
Then, when you insert:
insert into Friends_Relations (buddy_id, mate_id) values (123, 456); -- succeeds
insert into Friends_Relations (buddy_id, mate_id) values (456, 123); -- fails
from this dba exchange question
ALTER TABLE Friends_Relation ADD UNIQUE KEY
((least(buddy_id,mate_id)), (greatest(buddy_id,mate_id)))
This allows the pair in either order, but still only once.
Related
I need to create a table with this following relational schema.
The relational schema for this the new table is as follows:
The foreign keys for this new table are as follows:
Transit.{package, departDistributionCentre, departTimestamp}
references Depart.{package, distributionCentre, timestamp}
Transit.{package, arriveDistributionCentre, arriveTimestamp}
references Arrive.{package, distributionCentre, timestamp}
The table that i want to create is named Transit, with a particular column value must be one of this {“Plane”, “Car”, “Truck”}.
This is the code that i create, but apparently, the requirement to answer this question is not allowing me to insert values into table.
CREATE TABLE DeliveryMethod (
MethodCode INT NOT NULL,
Description VARCHAR(50),
PRIMARY KEY (MethodCode)
);
INSERT INTO DeliveryMethod (MethodCode, Description) VALUES (1, "Plane"), (2, "Car"), (3, "Truck");
CREATE TABLE Transit (
package VARCHAR(10) NOT NULL,
departDistributionCentre VARCHAR(100) NOT NULL,
departTimestamp TIMESTAMP NOT NULL,
arriveDistributionCentre VARCHAR(100) NOT NULL,
arriveTimestamp TIMESTAMP NOT NULL,
method INT NOT NULL,
cost INT,
PRIMARY KEY (package, departDistributionCentre, departTimestamp, arriveDistributionCentre, arriveTimestamp),
CONSTRAINT method_fk FOREIGN KEY (method) REFERENCES DeliveryMethod(MethodCode) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT depart_fk FOREIGN KEY (package, departDistributionCentre, departTimestamp) REFERENCES Depart(package, distributionCentre, timestamp) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT arrive_fk FOREIGN KEY (package, arriveDistributionCentre, arriveTimestamp) REFERENCES Arrive(package, distributionCentre, timestamp) ON DELETE RESTRICT ON UPDATE CASCADE
);
any of you good people have a lead to solve this without inserting values to a table as reference?
Thanks
Below is the simplified picture of the relationships I have in my DB:
create table attribute (id int auto_increment, primary key (id));
create table state_sample (id int auto_increment, primary key(id));
create table state_sample_attribute (
state_sample_id int,
attribute_id int,
primary key(state_sample_id, attribute_id),
foreign key (state_sample_id) references state_sample(id) on update cascade,
foreign key (attribute_id) references attribute(id) on update cascade
);
create table note (
id int auto_increment,
state_sample_id int,
attribute_id int,
primary key(id),
foreign key (state_sample_id) references state_sample(id) on update cascade,
foreign key (state_sample_id, attribute_id)
references state_sample_attribute(state_sample_id, attribute_id) on update cascade
);
insert into attribute values (1);
insert into state_sample values (1);
insert into state_sample_attribute values (1, 1);
insert into note values (1, 1, 1);
Whenever I try to update the ss table, it fails:
update state_sample set id = 2;
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`demotemplate`.`note`, CONSTRAINT `note_ibfk_1` FOREIGN KEY (`ss_id`) REFERENCES `ss` (`id`) ON UPDATE CASCADE)
As far as I understand, this is what happens:
It tries to set state_sample.id = 2.
It sees the cascade to note and tries to update note.state_sample_id.
However, note.state_sample_id is also involved in the foreign key to to state_sample_attribute(state_sample_id, attribute_id), so it goes to check whether that's still valid.
As state_sample_attribute.state_sample_id has not yet been updated, the constraint fails.
Is my assumption correct? And if so, is there a way to work this around?
Give the ssa table its own id primary key, and use that in the foreign key in notes, rather than referencing the ss_id and a_id columns.
create table ssa (
id int auto_increment,
ss_id int,
a_id int,
primary key (id),
unique key (ss_id, a_id),
foreign key (ss_id) references ss(id) on update cascade,
foreign key (a_id) references a(id) on update cascade);
create table note (
id int auto_increment,
ss_id int,
ssa_id int,
primary key(id),
foreign key (ss_id) references ss(id) on update cascade,
foreign key (ssa_id) references ssa(id) on update cascade);
Now you don't have the redundant dependency.
It's also not clear that note needs ss_id at all, since it's redundant with the related ssa row.
Try
DISABLE KEYS
or
SET FOREIGN_KEY_CHECKS=0;
make sure to turn it on
SET FOREIGN_KEY_CHECKS=1;
after.
What solved it in the end is dropping the extra FK:
alter table note drop foreign key (state_sample_id) references state_sample(id);
I am getting this error code and have no idea why any help would be appreciated. Thanks
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (#USER.meter, CONSTRAINT meter_FK FOREIGN KEY (location_code) REFERENCES location (code) ON DELETE CASCADE ON UPDATE CASCADE)
CREATE TABLE meter (
`code` CHAR(5) NOT NULL,
`type` VARCHAR(30) NOT NULL,
description VARCHAR(30) NULL,
location_code CHAR(3) NOT NULL,
CONSTRAINT pri_meter
PRIMARY KEY (`code`),
CONSTRAINT meter_FK
FOREIGN KEY (location_code)
REFERENCES location (`code`) ON UPDATE CASCADE ON DELETE CASCADE );
INSERT INTO meter VALUES ('G1','Gas','Testing Unit','NULL');
INSERT INTO meter VALUES ('G2','Gas','NULL','U1');
INSERT INTO meter VALUES ('E1','Electric','NULL','U1');
INSERT INTO meter VALUES ('G3','Gas','NULL','U2');
INSERT INTO meter VALUES ('G4','Gas','NULL','U2');
INSERT INTO meter VALUES ('E2','Electric','NULL','U2');
INSERT INTO meter VALUES ('E3','Electric','NULL','C1');
Your foreign key (FK) in this instance is "location_code". The first row of data you're trying to insert has a null "location_code".
FKs require you to have a matching primary key in the related table. (location)
It's very unlikely "location" "code" has null as a value - and without a matching value for your FK, you cannot insert data into your "meter" table.
Easiest solution - replace the null in your first insert:
INSERT INTO meter VALUES ('G1','Gas','Testing Unit','U1');
I created table with FOREIGN KEY and can't insert anything.
CREATE TABLE menus (
id int(10),
parent_id int(10),
label varchar(255),
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES menus (id)
);
I need FOREIGN KEY to automatically delete children when parent was deleted. This table was successfully created but I can't insert anything.
INSERT INTO `menus` (`parent_id`, `label`)
VALUES ('1', 'label1');
or
INSERT INTO `menus` (`label`)
VALUES ( 'label1');
#1452 - Cannot add or update a child row: a foreign key constraint fails
I really don't want look for any children in php code so I need somehow create simple table with 3 columns and automatically drop all children and they children too.
For all your needs you should take this structure
CREATE TABLE `menus` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(11) unsigned DEFAULT NULL,
`label` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `fk_parent_menu` (`parent_id`),
CONSTRAINT `fk_parent_menu` FOREIGN KEY (`parent_id`)
REFERENCES `menus` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);
SQL Fiddle DEMO
Demo shows inserting and deleting of a parent node
The magic drop part for all children is done by ON DELETE CASCADE
Typically, you will need to allow the 'root' record to have a null parent - i.e. menus.parent_id should be nullable, and the 'root' menu item will have a null parent_id.
i.e.
Change your DDL to:
parent_id int(10) NULL
And then you add your root element with NULL as the parent_id
insert into `menus` (id, `label`, parent_id)
VALUES (1, 'label1', null);
Then you are good to go with child elements:
insert into `menus` (id, `label`, parent_id)
VALUES (2, 'subitem1', 1);
etc.
SQL Fiddle here
I am working on a PHP application that uses a database extensively. My coworker who set up the database, set up the tables to use foreign keys. Here is the statement I am using:
INSERT INTO patients (ethnicity, gender)
VALUES (1, 1);
INSERT INTO sessions (patient_id, submitted, age_in_years, video, annotated)
VALUES (LAST_INSERT_ID(), NOW(), 0, '', FALSE);
The first statement works. However, I get the following error with the second statement.
#1452 - Cannot add or update a child row: a foreign key constraint fails (`<database name>/sessions`, CONSTRAINT `fk_sessions_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
I have confirmed that LAST_INSERT_ID() returns the expected value.
How can I fix this?
Below is how we set up the sessions table
CREATE TABLE IF NOT EXISTS `sessions` (
`id` int(11) NOT NULL auto_increment,
`patient_id` int(11) NOT NULL,
`severity` enum('Minimal Symptoms of Autism Spectrum Disorder','Mild-to-Moderate Symptoms of Autism Spectrum Disorder','Severe Symtoms of Autism Spectrum Disorder') default NULL,
`submitted` datetime default NULL,
`age_in_years` int(11) NOT NULL,
`video` text NOT NULL,
`annotated` tinyint(1) default '0',
PRIMARY KEY (`id`),
KEY `fk_sessions_1` (`patient_id`),
KEY `age_in_years` (`age_in_years`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
ALTER TABLE `sessions`
ADD CONSTRAINT `fk_sessions_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
EDIT: Removed unnecessary details. If you feel you need more, feel free to look at the first version of this post.
It turns out that when my coworker added the foreign key, he had a typo in the table name that the foreign key references.
ALTER TABLE `sessions`
ADD CONSTRAINT `fk_sessions_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
should be
ALTER TABLE `sessions`
ADD CONSTRAINT `fk_sessions_1` FOREIGN KEY (`patient_id`) REFERENCES `patients` (`id`) ON DELETE CASCADE;
The error is telling you exactly what's wrong.
You're attempting to insert a value in sessons.patient_id that does not exist in patients.id. This is how foreign key constraints work by design. Regardless of whether or not the value of LAST_UPDATE_ID() is what you expect, you need to confirm that the value is valid in patients.id.
Example:
patients
---------------
id | name
---------------
1 | john
2 | jane
If you try to insert "3" into sessions.patient_id, you will get the error you see because that id doesn't exist in patients.