Is it possible (and how can I achieve it) to get some kind of inheritance with database tables?
I intend to have a parent table X
CREATE TABLE `X` (
`xId` int(11) NOT NULL AUTO_INCREMENT,
`addressId` int(11) NOT NULL,
`poiType` enum('ParkingPOI','ChargingPOI') NOT NULL,
`status` enum('AVAILABLE','NOT_AVAILABLE') NOT NULL
PRIMARY KEY (`aId`),
KEY `fk_x_address_idx` (`addressId`),
CONSTRAINT `fk_address` FOREIGN KEY (`addressId`) REFERENCES `addresses` (`addressId`)
ON DELETE NO ACTION ON UPDATE CASCADE) ENGINE=InnoDB AUTO_INCREMENT=217 DEFAULT CHARSET=utf8;
and a child table B
CREATE TABLE `B` (
`bId` int(11) NOT NULL AUTO_INCREMENT,
`xId` int(11) NOT NULL',
`status` enum('AVAILABLE','NOT_AVAILABLE','PARTLY_AVAILABLE') NOT NULL
PRIMARY KEY (`bId`),
KEY `aId` (`xId`),
CONSTRAINT `fk_a` FOREIGN KEY (`xId`) REFERENCES `X` (`xId`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
In table X I want to have something like an ENUM with values being inherited from the child table, for instance: AVAILABLE, NOT_AVAILABLE. In this table/column of the parent table (X) only these values shall be allowed.
In the child table, however, this ENUM should be extendend so that the values AVAILABE, NOT_AVAILABLE, PARTLY_AVAILABLE shall be possible.
How can I achieve this?
Related
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.
CREATE TABLE `class` (
`class_id` int(11) NOT NULL AUTO_INCREMENT,
`section_name` varchar(50) NOT NULL,
`class_alias` varchar(200) NOT NULL,
`grading_scheme` int(11) NOT NULL DEFAULT '0',
`year` year(4) NOT NULL,
`grade_calc_method_id` varchar(20) DEFAULT NULL,
PRIMARY KEY (`class_id`)
) ENGINE=InnoDB AUTO_INCREMENT=48819 DEFAULT CHARSET=latin1;
CREATE TABLE `teachers` (
`teacher_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`teacher_subject` varchar(20) NOT NULL DEFAULT 'None',
PRIMARY KEY (`teacher_id`),
KEY `user_id` (`user_id`,`school_id`)
) ENGINE=InnoDB AUTO_INCREMENT=48606 DEFAULT CHARSET=latin1;
CREATE TABLE `teacher_classes` (
`teacher_class_id` int(11) NOT NULL AUTO_INCREMENT,
`teacher_id` int(11) NOT NULL,
`class_id` int(11) NOT NULL,
PRIMARY KEY (`teacher_class_id`),
UNIQUE KEY `teacher_id_class_id` (`teacher_id`,`class_id`),
KEY `teacher_id` (`teacher_id`,`class_id`)
) ENGINE=InnoDB AUTO_INCREMENT=46707 DEFAULT CHARSET=latin1;
Trying to insure data consistency between the tables by using foreign key so that the DBMS can check for errors.I have another junction table teacher_classes
Here is my query to add foreign keys constraint
ALTER TABLE teacher_classes
ADD CONSTRAINT `tc_fk_class_id` FOREIGN KEY (`class_id`)
REFERENCES class (`class_id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
ADD CONSTRAINT `tc_fk_teacher_id` FOREIGN KEY (`teacher_id`)
REFERENCES teachers (`teacher_id`) ON UPDATE NO ACTION ON DELETE NO ACTION;
've seen the other posts on this topic, but no luck, getting following error.
Cannot add or update a child row: a foreign key constraint fails
(DB_NAME.#sql-403_12, CONSTRAINT
tc_fk_teacher_id FOREIGN KEY (teacher_id) REFERENCES teachers
(teacher_id) ON DELETE NO ACTION ON UPDATE NO ACTION)
Too late to Answer. I just had the same problem the solution is easy.
You're getting this error because you're trying to or UPDATE a row to teacher_classes doesn't match the id in table teachers.
A simple solution is disable foreign key checks before performing any operation on the table.
SET FOREIGN_KEY_CHECKS = 0;
After you are done with the table enable it again.
SET FOREIGN_KEY_CHECKS = 1;
Or you can remove not null constraint and insert a NULL value in it.
That's most probably the column definition doesn't match properly. For table teachers the PK column definition is as below.
`teacher_id` int(11) NOT NULL AUTO_INCREMENT
Make sure you have the same definition in your child table teacher_classes
I don't know what I am doing wrong as I've been looking at previous answers on this site concerning ON CASCADE DELETE.
Basically this is my table:
CREATE TABLE `directorycolumntags` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`directorycolumn_id` INT(11) NOT NULL,
`tag_id` INT(11) NOT NULL,
`description` TEXT,
`created` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`directorycolumn_id`) REFERENCES directorycolumn(id),
CONSTRAINT FOREIGN KEY (`tag_id`) REFERENCES tag(id)
ON DELETE CASCADE
) ENGINE=MYISAM AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
The Foreign key references the id of the tag table:
CREATE TABLE `tag` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(200) DEFAULT NULL,
`description` TEXT,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
Now, If I perform this query to INSERT some data into the directorycolumntags table it works:
INSERT INTO directorycolumntags (directorycolumn_id, tag_id) VALUES (178,32);
However, when I DELETE the entry from the tag table with the id of 32 it does not remove the row from the directorycolumntags table. Can anyone point out where I am going wrong?
It's because your table directorycolumntags is MYISAM, not INNODB. MyISAM doesn't support foreign keys. You can write your foreign key statements, but MySQL silently ignores them.
Try this:
ALTER TABLE `directorycolumntags` ENGINE = 'InnoDB';
I want to create a database and connect it with two database. But I don't know when i create the Foreign Key to the second database (time_shift table) it always result error 150;
Here is the structure of table outlet:
And this is structure of table time_shift:
And this the query to create new table tide_cart:
create table `tide_chart` (
`id` int(10) not null auto_increment primary key,
`date` date null,
`outletId` int(11) not null,
`timeShiftId` int(11) not null,
`value` varchar(255) not null,
unique (`date`, `outletId`, `timeShiftId`),
foreign key (`outletId`) references `outlet`(`id`)
ON update cascade ON delete cascade,
foreign key (`timeShiftId`) references `time_shift`(`id`)
ON update cascade ON delete cascade
) engine=innoDB;
Please explain to me, why i get error when try to make foreign key connect to table time_shift?
Update: add dump export structure table for outlet and time_shift:
CREATE TABLE `outlet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
CREATE TABLE `time_shift` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time_start` time NOT NULL,
`time_end` time NOT NULL,
`is_active` tinyint(4) NOT NULL DEFAULT '1',
`ref_area` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `ref_area` (`ref_area`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
You need to use the InnoDB engine for your tables. time_shift is using MyISAM.
You must define indexes for outletId and timeShiftId (either UNIQUE or KEY as needed) in order to be able to create a foreign key using that field.
All I need is to create 2 tabeles with next structure:
The SQL:
CREATE TABLE IF NOT EXISTS `ds_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `module_news_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) NOT NULL,
`cat_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_module_news_cats_module_news_cats` (`parent`),
KEY `fk_module_news_cats_ds_cats1` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
ALTER TABLE `module_news_cats`
ADD CONSTRAINT `fk_module_news_cats_ds_cats1` FOREIGN KEY (`cat_id`) REFERENCES `ds_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_module_news_cats_module_news_cats` FOREIGN KEY (`parent`) REFERENCES `module_news_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
But when I try to insert first row to my table "module_news_cats", I recive next error:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`empty`.`module_news_cats`, CONSTRAINT `fk_module_news_cats_module_news_cats` FOREIGN KEY (`parent`) REFERENCES `module_news_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Question:
How I can create table which will have an index with non-identifying relationship to the anther index in the same table? Some rows will have parents, and some not.
I think you just need to allow NULLs in module_news_cats.parent:
CREATE TABLE IF NOT EXISTS `module_news_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) NULL, -- Change this
`cat_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_module_news_cats_module_news_cats` (`parent`),
KEY `fk_module_news_cats_ds_cats1` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
and then if there isn't a parent, create the row with a NULL in parent.
Your 'parent' field cannot be empty (NULL) if you insert a record, which means that every record you insert should refer to a parent ID (which is impossible if there are no entries in your table yet).
If you make the 'parent' field in the module_news_cats table nullable:
ALTER TABLE `module_news_cats` CHANGE `parent` `parent` INT( 11 ) NULL DEFAULT NULL
you should be able to insert records that have no parent ID associated (just supply NULL instead of a value).
You could make the parent column in the module_news_cats table nullable.
Then for rows that have no parents populate the parent column with null.