Error while creating a table in mysql cluster - mysql

I'm trying to create a table in MySQL Cluster . but getting a error while executing below query.
CREATE TABLE `tbl_anal_results` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tbl_bill_bill_id` int(10) unsigned NOT NULL,
`item` varchar(256) NOT NULL,
`bill_value` decimal(10,2) NOT NULL,
`calc_value` decimal(10,2) NOT NULL,
`err` tinyint(1) NOT NULL,
`error_code` varchar(256) DEFAULT NULL,
`tbl_bill_info_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_tbl_anal_results_tbl_bill1_idx` (`tbl_bill_bill_id`),
CONSTRAINT `fk_tbl_anal_results_tbl_bill1` FOREIGN KEY (`tbl_bill_bill_id`) REFERENCES `tbl_bill` (`bill_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=ndbcluster AUTO_INCREMENT=16570225 DEFAULT CHARSET=latin1;
ERROR 1215 (HY000): Cannot add foreign key constraint
I have used same query which I used to create same table in old mysql setup.
and I have changed ENGINE as ENGINE=ndbcluster instead of ENGINE=InnoDB
also noticed UPDATE CASCADE not working in mysql cluster.

Cut from docs:
ON UPDATE CASCADE is not supported when the reference is to the parent table's primary key.
This is because an update of a primary key is implemented as a delete of the old row (containing the old primary key) plus an insert of the new row (with a new primary key). This is not visible to the NDB kernel, which views these two rows as being the same, and thus has no way of knowing that this update should be cascaded.

Related

MySQL (Percona) Error 1452: Cannot add or update a child row for no reason

I have 2 Database Tables "users" and "tasks".
The tasks table contains two foreign keys for the createdBy_user_id and updatedBy_user_id columns both referencing users.id. If I try to insert an entry to tasks (after making sure the user referenced by the foreign keys exists) like this:
INSERT INTO tasks (createdBy_user_id,updatedBy_user_id,noOfYear,createdAt,updatedAt,status,customer_id)
VALUES (1,1,1,NOW(),NOW(),"open",1)
The query fails with Error 1452:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`tasks`, CONSTRAINT `user_id_fk_constr` FOREIGN KEY (`createdBy_user_id`) REFERENCES `users` (`id`))
I don't know why this happens, because everything works fine if I remove the constraint. The same error does not happen for the "updatedBy_user_id" column making this such confusing.
The Tables have the following DDL:
Users table:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`active` tinyint(1) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`email_confirmed_at` datetime DEFAULT NULL,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`first_name` varchar(50) DEFAULT NULL,
`last_name` varchar(50) DEFAULT NULL,
`job` varchar(64) DEFAULT NULL,
`position` varchar(64) DEFAULT NULL,
`specialKnowledge` text,
`tasks` text,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
Tasks table:
CREATE TABLE `tasks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`createdAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`noOfYear` int(11) NOT NULL,
`year` int(11) GENERATED ALWAYS AS (right(year(`createdAt`),2)) VIRTUAL NOT NULL,
`createdBy_user_id` int(11) NOT NULL,
`updatedBy_user_id` int(11) NOT NULL,
`status` enum('open','closed') NOT NULL,
`customer_id` int(11) NOT NULL,
`projectDescription` text,
PRIMARY KEY (`id`),
UNIQUE KEY `tasks_year_unique_constr` (`year`,`noOfYear`),
KEY `user_id_fk_constr` (`createdBy_user_id`),
KEY `customer_id_fk_constr` (`customer_id`),
KEY `user_up_id_fk_constr` (`updatedBy_user_id`),
CONSTRAINT `customer_id_fk_constr` FOREIGN KEY (`customer_id`) REFERENCES `Customer` (`id`),
CONSTRAINT `user_id_fk_constr` FOREIGN KEY (`createdBy_user_id`) REFERENCES `users` (`id`),
CONSTRAINT `user_up_id_fk_constr` FOREIGN KEY (`updatedBy_user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4
As you can see the datatypes match and both tables use the InnoDB Engine.
The users table contains one entry:
select id,username from users;
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
+----+----------+
1 row in set (0.00 sec)
So there is no obvious reason, why the insertion should fail. Have you an idea what's wrong with my tables? Looks like a software bug.
This is a bug. MySQL 5.7 has had some troubles with generated columns and foreign keys, and I assume this is an unfixed variant of Bug #79772 Foreign key not allowed when a virtual index exists.
In your particular case, and probably depending on your exact version, any of the following modifications seems to prevent that bug from occurring:
do not use a virtual column, but make it stored
do not create a foreign key for a column directly following the virtual column, so e.g. change the column order to year, status, createdBy_user_id, updatedBy_user_id.
do not use a unique index on the virtual column, a normal index should be fine (at least in a version where the linked bug is fixed). You want a unique constraint, so this is not an option, but the fact that this fixes your problem emphasized the "bug" nature of the problem.
The second bullet point seems to be the underlying bug: I assume that some iterator doesn't count the virtual column properly, so the foreign key that shall check createdBy_user_id seems to mix up the columns and actually checks the value of year (in this case "20") against the users table. So if you have a user with id "20" in your users table, the foreign key will actually accept this, no matter what value for createdBy_user_id you are trying to insert, see the MySQL 5.7.29 fiddle.
Unless you have a specific reason to use a virtual column, using stored is probably the sane thing to do.

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.

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.

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;

Cannot make foreign key field nullable with Sequel Pro

I'm having a defined relation to my user table as foreign key, but they don't necessarily need to be set. I.e. there must not be a related record.
In my MySQL editor (Sequel Pro) I cannot make the addressId "allow null". It ignores the input. Im using newest version.
When I create a new entry in the User table without an addressId, it says "Cannot add or update a child row: a foreign key constraint fails...". But I want to be able to add a User without an Address! Is that possible?
Or should I simply remove the foreign keys? What is the drawback of that?
CREATE TABLE `User1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`password` char(32) DEFAULT NULL,
`addressId` int(11) NULL DEFAULT '0',
`created` datetime DEFAULT NULL,
`activated` datetime DEFAULT NULL,
`lastLogin` datetime DEFAULT NULL,
PRIMARY KEY (`id`,`addressId`),
KEY `FK_User_Locale` (`localeId`),
KEY `FK_User_Address` (`addressId`),
CONSTRAINT `FK_User_Address` FOREIGN KEY (`addressId`) REFERENCES `Address` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Why don't you disable foreign_key_checks by setting to foreign_key_checks=0?
Else you may DROP the constraint if it does't suit your requirements!
If set to 1 (the default), foreign key constraints for InnoDB tables
are checked. If set to 0, they are ignored. Disabling foreign key
checking can be useful for reloading InnoDB tables in an order
different from that required by their parent/child relationships.