On delete cascade not deleting the associates entries - mysql

I have a marks table which holds the foreign key to an associates message. I used ON DELETE with the expectation that deleting an entry in the marks table would also delete the associated message. It is not working as expected though. I checked out all the other post and can't find any relevant to this one.
I can insert into the database successfully
DELETE FROM marks WHERE x = 37.7836
but when I delete a mark the message that is associated with it is not deleted. Any insights as to what I am doing wrong here?
Edit:
Here is an image of me demonstrating my deletion process:
schema
DROP DATABASE uncovery;
CREATE DATABASE uncovery;
SET foreign_key_checks=0;
USE uncovery;
CREATE TABLE marks (
id int(5) AUTO_INCREMENT,
x float(10, 6),
y float(10, 6),
z float(10, 6),
timestamp timestamp DEFAULT CURRENT_TIMESTAMP,
messageId int(5),
FOREIGN KEY (messageId)
REFERENCES messages(id)
ON DELETE CASCADE,
PRIMARY KEY (id)
);
CREATE TABLE messages (
id int(5) AUTO_INCREMENT,
messageString text,
PRIMARY KEY (id)
);
EDIT 2: Schema Refactor
Here is my newly updated schema:
As you can see I am getting an error that this is invalid when I try to run it:

The foreign key as you've created it won't work the way you expect. Under your schema, if an entry is deleted from messages, it will delete all corresponding entries from the marks table, not the other way around.
Also, you must ensure that you are using the InnoDB storage engine for your tables, or your foreign keys won't work at all. They are not supported in the MyISAM engine type.
To get your schema working such that deleting a mark will cause a message to be deleted, you need to have a markId as a foreign key in the messages table, like so:
CREATE TABLE `messages` (
`id` int(5) NOT NULL auto_increment,
`messageString` text,
`markId` int(5) default NULL,
PRIMARY KEY (`id`),
KEY `markId` (`markId`),
CONSTRAINT `messages_ibfk_1` FOREIGN KEY (`markId`) REFERENCES `marks` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE `marks` (
`id` int(5) NOT NULL auto_increment,
`x` float(10,6) default NULL,
`y` float(10,6) default NULL,
`z` float(10,6) default NULL,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;

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.

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)

MySQL Error 1005 errno. 150 with Primary Keys

I'm adding a functionality to a database I have previously created. I have a table named "Test" which holds data about a series of questions. This data can include a number of dynamic fields added by the user, so I have a table named Test_Header_Values which will hold data about which header field is being fulfilled and the test it is part of.
So far so good, I have created both tables but have an Error 1215 when creating a Foreign Key. I had an error 1005 previously, but I tried on another database and it throws the 1215. I have checked infinite times the typing, the relationship, the indexes, and it should work, but I can't get it done.
Here you have the tables:
CREATE TABLE `test` (
`fk_id_checklist` int(10) unsigned NOT NULL,
`sent_date` date NOT NULL,
`fk_id_user` int(10) unsigned NOT NULL,
`fk_id_user_company` int(10) unsigned NOT NULL,
`start_date` date DEFAULT NULL,
PRIMARY KEY (`fk_id_checklist`,`sent_date`,`fk_id_user`,`fk_id_user_company`),
KEY `fk_user_test_idx` (`fk_id_user`,`fk_id_user_company`),
CONSTRAINT `fk_test_user` FOREIGN KEY (`fk_id_user`, `fk_id_user_company`)
REFERENCES `user` (`id_user`, `fk_id_company`)
ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_test_checklist` FOREIGN KEY (`fk_id_checklist`)
REFERENCES `checklist` (`id_checklist`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `test_header_values` (
`fk_id_checklist` int(10) unsigned NOT NULL,
`fk_sent_date` date NOT NULL,
`fk_id_field` int(10) unsigned NOT NULL,
`fk_id_user` int(10) unsigned NOT NULL,
`fk_id_user_company` int(10) unsigned NOT NULL,
`value` varchar(64) NOT NULL,
PRIMARY KEY (`fk_id_checklist`,`fk_id_field`,`fk_id_user`,`fk_id_user_company`,`fk_sent_date`),
KEY `fk_field_idx` (`fk_id_field`),
KEY `fk_values_test_idx` (`fk_id_checklist`,`fk_sent_date`,`fk_id_user`,`fk_id_user_company`),
CONSTRAINT `fk_values_field` FOREIGN KEY (`fk_id_field`) REFERENCES `fields` (`id_field`)
ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_values_test` FOREIGN KEY (`fk_id_checklist` , `fk_id_user` , `fk_id_user_company` , `fk_sent_date`)
REFERENCES `test` (`fk_id_checklist` , `fk_id_user` , `fk_id_user_company` , `sent_date`)
ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
If I remove the constraint fk_values_test it works perfectly. With this line, it returns the aforementioned error.
I have followed this guide and all the questions I found on SO but I have been unable to find the error.
I have been able to solve the problem.
Seemingly, the index for the foreign key must have the same column order that the constraint, which is something that I didn't find specified.
Changing the constraint to `fk_id_checklist` , `fk_id_user` , `fk_id_user_company` , `fk_sent_date` solves this error.

Alter primary key column that is also a foreign key of another table - Mysql

I have the below 2 tables. They both have data in them. I would like to modify charge_date from a date into a datetime. Mysql is not allowing me to do this. I would like to do this without dropping and recreating the existing table.
CREATE TABLE `cmpny_charges` (
`company_id` int(10) unsigned NOT NULL,
`charge_id` varchar(45) NOT NULL,
`charge_date` date NOT NULL,
`charge_amt` double NOT NULL,
`chargeholder_id` varchar(20) NOT NULL,
`filing_no` int(10) unsigned DEFAULT NULL,
`registration_date` date DEFAULT NULL,
`srn` varchar(10) DEFAULT NULL,
`charge_type` char(1) NOT NULL,
`updated_ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_ts` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`doc_no` varchar(45) DEFAULT NULL,
PRIMARY KEY (`company_id`,`charge_id`,`charge_date`),
KEY `cmpny_charges_FK_2` (`chargeholder_id`),
KEY `cmpny_charges_FK_1` (`filing_no`),
CONSTRAINT `cmpny_charges_FK_2` FOREIGN KEY (`chargeholder_id`) REFERENCES `chargeholder_dtls` (`chargeholder_id`),
CONSTRAINT `cmpny_charges_FK_3` FOREIGN KEY (`company_id`) REFERENCES `company` (`company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `cmpny_charge_dtls` (
`company_id` int(10) unsigned NOT NULL,
`charge_id` varchar(45) NOT NULL,
`charge_date` date NOT NULL,
`modification_part` text,
`part_property_charged` text,
`filing_date` datetime DEFAULT NULL,
`srn` varchar(9) DEFAULT NULL,
`rate_of_interest` text,
`repayment_terms` text,
`margin` text,
`nature_instrument` text,
PRIMARY KEY (`company_id`,`charge_id`,`charge_date`),
CONSTRAINT `FK_cmpny_charge_dtls_1` FOREIGN KEY (`company_id`, `charge_id`, `charge_date`) REFERENCES `cmpny_charges` (`company_id`, `charge_id`, `charge_date`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
This is the alter script I would like to execute
set foreign_key_checks=0;
lock tables cmpny_charges write, cmpny_charge_dtls write;
ALTER TABLE `cmpny_charge_dtls` CHANGE `charge_date` `charge_date` datetime not null;
ALTER TABLE `cmpny_charges` CHANGE `charge_date` `charge_date` datetime not null;
unlock tables ;
set foreign_key_checks =1;
I get an error as below when I execute show engine innodb status
LATEST FOREIGN KEY ERROR
140313 19:54:03 Error in foreign key constraint of table
csmart/cmpny_charge_dtls: there is no index in referenced table which
would contain the columns as the first columns, or the data types in
the referenced table do not match the ones in table. Constraint: ,
CONSTRAINT "FK_cmpny_charge_dtls_1" FOREIGN KEY ("company_id",
"charge_id", "charge_date") REFERENCES "cmpny_charges" ("company_id",
"charge_id", "charge_date") The index in the foreign key in table is
"PRIMARY" See
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition. InnoDB: Renaming table
csmart. to
csmart.cmpny_charges failed!
These are the caveats
I don't know the name of the constraints for me to drop them temporarily. The same constraints can be present with different names. (I need to update more than one copy of this database)
I would like to do this without creating a temp table, copying the data there and then renaming them to the original one. This caused issues when multiple sessions logged into the same database tried to do the same thing at the same time leaving it in an inconsistent state.
Add a new column, copy data into it. Then modify the foreign key to point to the new column, and the drop the old column.
alter table cmpny_charges add charge_date2 datetime;
update cmpny_charges set charge_date2= charge_date;
-- (I am used to do this via GUI, sorry...)
-- drop foreing key
---modify the primary key
-- recreate the foreing key
alter table cmpny_charges drop charge_date;

MySQL Not allowing delete even though FK relationship ON DELETE CASCADE set

I am working on a project that makes use of a MySQL Database to store snippets of code for use on multiple websites. For each content snippet I also keep an edit history table, to which I add a record every time a snippet is updated. Occasionally it will be desirable to delete a snippet completely, and any associated edit history. When setting up the DB, I set up the foreign key relationship to ON DELETE CASCADE so that deleting the snippet will automatically delete the history. However, I am getting the following error:
Error in query: delete from SNIPPET where id = 1. Cannot delete or update a parent row: a foreign key constraint fails (universal_content_repository/SNIPPET_EDIT_HISTORY, CONSTRAINT fk_SNIPPET_EDIT_HISTORYRelationship13 FOREIGN KEY (snippet_id) REFERENCES SNIPPET (id))
Here is the code I use to create the DB as well as the relationships:
/*Schema universal_content_repository*/
CREATE SCHEMA IF NOT EXISTS `universal_content_repository`
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `universal_content_repository`;
CREATE TABLE `universal_content_repository`.`USER` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Stores the ID for the User.',
`username` VARCHAR(20) NOT NULL,
`first_name` VARCHAR(32) NOT NULL,
`last_name` VARCHAR(32) NOT NULL,
`is_active` VARCHAR(5) NOT NULL DEFAULT true,
`password` VARCHAR(32) NOT NULL,
`is_admin` BIT NOT NULL DEFAULT 0,
`prefers_wysiwyg` BIT DEFAULT 0,
PRIMARY KEY (`id`)
) COMMENT 'Stores information about all Users for the Universal Content Repository.' ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`SNIPPET` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL,
`content` TEXT NOT NULL,
`created_by` INT UNSIGNED,
`wysiwyg_editable` VARCHAR(6) NOT NULL DEFAULT true,
`is_enabled` BIT NOT NULL DEFAULT 1,
PRIMARY KEY (`id`)
) COMMENT 'Guarantees that no two snippets may have the same name or ID.' ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`IMAGE` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`url` TEXT NOT NULL,
`alt` VARCHAR(32),
PRIMARY KEY (`id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`IMAGE_IN_SNIPPET` (
`rel_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`snippet_id` INT UNSIGNED,
`image_id` INT UNSIGNED,
`position` INT COMMENT 'Stores the position of the image within the snippet, as notated in the snippet as [index]',
PRIMARY KEY (`rel_id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`SNIPPET_EDIT_HISTORY` (
`revision_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`editing_user` INT UNSIGNED,
`snippet_id` INT UNSIGNED,
`old_contents` TEXT NOT NULL COMMENT 'Stores the old contents of the snippet.',
`edit_date` DATETIME NOT NULL COMMENT 'Stores the DateTime of the edit.',
PRIMARY KEY (`revision_id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`SESSION` (
`id` VARCHAR(32) NOT NULL COMMENT 'Stores the Session ID',
`access` INT(10) UNSIGNED NOT NULL,
`data` TEXT,
PRIMARY KEY (`id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;
ALTER TABLE `universal_content_repository`.`USER` ADD UNIQUE `Identifiers` (`id`,`username`);
ALTER TABLE `universal_content_repository`.`SNIPPET` ADD UNIQUE `identifiers` (`title`,`id`);
ALTER TABLE `universal_content_repository`.`SNIPPET` ADD CONSTRAINT `fk_SNIPPETRelationship8` FOREIGN KEY (`created_by`) REFERENCES `universal_content_repository`.`USER`(`id`) MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;
ALTER TABLE `universal_content_repository`.`IMAGE_IN_SNIPPET` ADD CONSTRAINT `fk_IMAGE_IN_SNIPPETRelationship10` FOREIGN KEY (`snippet_id`) REFERENCES `universal_content_repository`.`SNIPPET`(`id`) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE `universal_content_repository`.`IMAGE_IN_SNIPPET` ADD CONSTRAINT `fk_IMAGE_IN_SNIPPETRelationship11` FOREIGN KEY (`image_id`) REFERENCES `universal_content_repository`.`IMAGE`(`id`) MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;
ALTER TABLE `universal_content_repository`.`SNIPPET_EDIT_HISTORY` ADD CONSTRAINT `fk_SNIPPET_EDIT_HISTORYRelationship12` FOREIGN KEY (`editing_user`) REFERENCES `universal_content_repository`.`USER`(`id`) MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;
ALTER TABLE `universal_content_repository`.`SNIPPET_EDIT_HISTORY` ADD CONSTRAINT `fk_SNIPPET_EDIT_HISTORYRelationship13` FOREIGN KEY (`snippet_id`) REFERENCES `universal_content_repository`.`SNIPPET`(`id`) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;
If you want to see a graphical representation of the DB, you can see it at SchemaBank.
For those without a SchemaBank account, here is the ER:
Any ideas?
Looks like your code is right.
If it's practical, dump that database and restore it onto a different server as a test. If INNODB and MySQL internal states have gotten out of sync, that should give you a well-behaved database on the server you restore to.