Recursive Table nullable parent_id - mysql

CREATE TABLE IF NOT EXISTS `db_teamup`.`programming_languages` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '',
`name` VARCHAR(255) NOT NULL COMMENT '',
`count` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '',
`parent_id` INT UNSIGNED NULL COMMENT '',
`icon_path` VARCHAR(255) NOT NULL DEFAULT 'default_icon.svg' COMMENT '',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`, `parent_id`) COMMENT '',
INDEX `fk_programming_languages_programming_language_parent_idx` (`parent_id` ASC) COMMENT '',
CONSTRAINT `fk_programming_languages_programming_language_parent_id`
FOREIGN KEY (`parent_id`)
REFERENCES `db_teamup`.`programming_languages` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
I am trying to make a recursive mysql table, but when i execute the script, on workbench, it sets the parent_id to not null, is there a setting or a command that i am not executing before running my script?
The worst part is that it makes the default value 0.
thank you

PRIMARY KEY ('id')
I don't think 'parent_id' should be part of your primary key. It wouldn't be able to be NULL if it was.

Related

"Foreign key constraint is incorrectly formed" while creating unique index

I was attempted to execute following queries:
CREATE TABLE `lob_sections` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section_name` varchar(600) NOT NULL,
`lob_type` varchar(64) NOT NULL,
`agency_id` varchar(64) NOT NULL,
`display_order` tinyint(2) NOT NULL DEFAULT 1,
`active` tinyint(1) NOT NULL DEFAULT 1,
`created_date` timestamp NOT NULL DEFAULT current_timestamp(),
`last_modified_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `unq_lob_sections` (`agency_id`,`lob_type`,`section_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `lob_custom_fields` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section_id` int(11) NOT NULL,
`field_label` varchar(1400) NOT NULL,
`field_type` varchar(20) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT 1,
`display_order` tinyint(3) NOT NULL DEFAULT 1,
`required` tinyint(1) NOT NULL DEFAULT 0,
`created_date` timestamp NOT NULL DEFAULT current_timestamp(),
`last_modified_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
CONSTRAINT unq_section_field_label UNIQUE (section_id, field_label),
CONSTRAINT `fk_section_id` FOREIGN KEY (`section_id`) REFERENCES `lob_sections` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
lob_sections table is created successfully, but lob_custom_fields is not creating, it is throwing me following error:
#1005 - Can't create table abc_db.lob_custom_fields (errno: 150 "Foreign key constraint is incorrectly formed") (Details…)
When I click on Details, then it shows me reason "Create table abc_db.lob_custom_fieldswith foreign keyfk_section_id constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns.------------".
If I remove the line "CONSTRAINT unq_section_field_label UNIQUE (section_id, field_label)," from create table statement of lob_custom_fields table, then it created successfully.
How to add unique index in lob_custom_fields table? Create-Alter both are showing same error when I attempt to add unique index. Any help will be highly appreciated.
The error message says
Specified key was too long; max key length is 3072 bytes
The InnoDB internal maximum key length is 3500 bytes, but MySQL itself restricts this to 3072 bytes. This limit applies to the length of the combined index key in a multi-column index.
that is for mysql 8
so you must define
field_label varchar(1022)
That fits
CREATE TABLE `lob_sections` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section_name` varchar(600) NOT NULL,
`lob_type` varchar(64) NOT NULL,
`agency_id` varchar(64) NOT NULL,
`display_order` tinyint(2) NOT NULL DEFAULT 1,
`active` tinyint(1) NOT NULL DEFAULT 1,
`created_date` timestamp NOT NULL DEFAULT current_timestamp(),
`last_modified_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `unq_lob_sections` (`agency_id`,`lob_type`,`section_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `lob_custom_fields` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section_id` int(11) NOT NULL,
`field_label` varchar(1022) NOT NULL,
`field_type` varchar(20) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT 1,
`display_order` tinyint(3) NOT NULL DEFAULT 1,
`required` tinyint(1) NOT NULL DEFAULT 0,
`created_date` timestamp NOT NULL DEFAULT current_timestamp(),
`last_modified_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
CONSTRAINT unq_section_field_label UNIQUE (section_id, field_label),
CONSTRAINT `fk_section_id` FOREIGN KEY (`section_id`) REFERENCES `lob_sections` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
db<>fiddle here

How can I avoid in mysql that I have two null values on foreign keys?

I got a table user, a table assignment and a table candidation (with a individual primary, not the natural one) which has foreign keys to both others. They are both 1:nc, means there must not always be a user for a candidation (user deleted) or a assignment (assignment deleted).
Now how can I avoid having NULL in both foreign keys?
USER:
-- Table `Ressource-Management`.`user`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Ressource-Management`.`user` (
`iduser` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '',
`name_first` VARCHAR(50) NOT NULL COMMENT '',
`name_last` VARCHAR(50) NOT NULL COMMENT '',
`attendance` INT UNSIGNED NOT NULL COMMENT '',
`can_own` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`iduser`) COMMENT '')
ENGINE = InnoDB;
ASSIGNMENT:
-- -----------------------------------------------------
-- Table `Ressource-Management`.`assignment`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Ressource-Management`.`assignment` (
`idassignment` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '',
`owner` INT UNSIGNED NOT NULL COMMENT '',
`budget` INT UNSIGNED NOT NULL COMMENT '',
`priority` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '',
`date_to` DATETIME NULL COMMENT '',
PRIMARY KEY (`idassignment`) COMMENT '',
INDEX `fk_assignment_user_idx` (`owner` ASC) COMMENT '',
CONSTRAINT `fk_assignment_user`
FOREIGN KEY (`owner`)
REFERENCES `Ressource-Management`.`user` (`iduser`)
ON DELETE RESTRICT
ON UPDATE CASCADE)
ENGINE = InnoDB;
CANDIDATION:
-- -----------------------------------------------------
-- Table `Ressource-Management`.`candidation`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Ressource-Management`.`candidation` (
`idcandidation` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '',
`user_iduser` INT UNSIGNED NULL COMMENT '',
`assignment_idassignment` INT UNSIGNED NULL COMMENT '',
`date_from` DATETIME NOT NULL COMMENT '',
`date_to` DATETIME NOT NULL COMMENT '',
`status` LONGBLOB NULL DEFAULT offen COMMENT '',
`message` VARCHAR(4096) NULL COMMENT '',
PRIMARY KEY (`idcandidation`) COMMENT '',
INDEX `fk_user_has_assignment_assignment1_idx` (`assignment_idassignment` ASC) COMMENT '',
INDEX `fk_user_has_assignment_user1_idx` (`user_iduser` ASC) COMMENT '',
UNIQUE INDEX `user_assignment_UNIQUE` (`user_iduser` ASC, `assignment_idassignment` ASC) COMMENT '',
CONSTRAINT `fk_user_has_assignment_user1`
FOREIGN KEY (`user_iduser`)
REFERENCES `Ressource-Management`.`user` (`iduser`)
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT `fk_user_has_assignment_assignment1`
FOREIGN KEY (`assignment_idassignment`)
REFERENCES `Ressource-Management`.`assignment` (`idassignment`)
ON DELETE SET NULL
ON UPDATE CASCADE)
ENGINE = InnoDB;
if the only reason that leads to null values is a delete of a record, use logical deletion: add a flag isDeleted to both tables and make the foreign key fields in candidation as NOT NULL.
A posibility is to create a trigger on the deletion, where I discard delete if already the other key is NULL

#1005 - Can't create table errno: 150 Magento

I am trying to create a new table for magento and I am trying to reference existing magento tables. From what I googled, the problem that I am getting can be 1 of the 2 issues.
The FK must have a index
The PK must exist before the FK can reference
In both cases, I believe I did both of these correctly. Below is existing table schemas
ALREADY EXISTING TABLES BEING REFERENCED
CREATE TABLE IF NOT EXISTS `core_store` (
`store_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`code` varchar(32) NOT NULL DEFAULT '',
`website_id` smallint(5) unsigned DEFAULT '0',
`group_id` smallint(5) unsigned NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`sort_order` smallint(5) unsigned NOT NULL DEFAULT '0',
`is_active` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`store_id`),
UNIQUE KEY `code` (`code`),
KEY `FK_STORE_WEBSITE` (`website_id`),
KEY `is_active` (`is_active`,`sort_order`),
KEY `FK_STORE_GROUP` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Stores' AUTO_INCREMENT=9 ;
CREATE TABLE IF NOT EXISTS `admin_user` (
`user_id` mediumint(9) unsigned NOT NULL AUTO_INCREMENT,
`firstname` varchar(32) NOT NULL DEFAULT '',
`lastname` varchar(32) NOT NULL DEFAULT '',
`email` varchar(128) NOT NULL DEFAULT '',
`username` varchar(40) NOT NULL DEFAULT '',
`password` varchar(100) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime DEFAULT NULL,
`logdate` datetime DEFAULT NULL,
`lognum` smallint(5) unsigned NOT NULL DEFAULT '0',
`reload_acl_flag` tinyint(1) NOT NULL DEFAULT '0',
`is_active` tinyint(1) NOT NULL DEFAULT '1',
`extra` text,
`failures_num` smallint(6) NOT NULL DEFAULT '0',
`first_failure` datetime DEFAULT NULL,
`lock_expires` datetime DEFAULT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `UNQ_ADMIN_USER_USERNAME` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Users' AUTO_INCREMENT=25 ;
Table I am trying to create
CREATE TABLE `oro_dashboard`
( `id` int unsigned NOT NULL,
`name` varchar(255) NOT NULL default '',
`description` varchar(64) NOT NULL default '',
`created_by` int unsigned NOT NULL default '0',
`created_at` date,
`layout` varchar(255) NOT NULL default '',
`default_store_id` int,
PRIMARY KEY (`id`),
KEY `IDX_ORO_DASHBOARD_CREATED_BY` (`created_by`),
CONSTRAINT `FK_ORO_DASHBOARD_CREATED_BY_ADMIN_USER_USER_ID` FOREIGN KEY (`created_by`) REFERENCES `admin_user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_ORO_DASHBOARD_DEFAULT_STORE_ID_CORE_STORE_STORE_ID` FOREIGN KEY (`default_store_id`) REFERENCES `core_store` (`store_id`) ON DELETE SET NULL ON UPDATE CASCADE )
ENGINE=INNODB charset=utf8 COLLATE=utf8_unicode_ci
In magento, I found there is in deed a table called admin_user that does have a column called user_id. There is a core_store table that does have a column called store_id. and both my columns have INDEXES made.
Does anyone have any clue what the issue maybe ? Below is my error message
#1005 - Can't create table 'db.oro_dashboard' (errno: 150)
It is necessary to have data type to be same for the foreign key and its corresponding parent key. The data type is different of the foreign key and its referencing parent key in your table that is why it is giving an error.
created by is int unsigned while userid is medium int in parent table
same is problem in the second foreign key
reference http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
When defining foreign keys, the data type must be the same.
You are defining core_store.store_id as smallint(5) unsigned and so the referencing column must be the same: oro_dashboard.default_store_id.
Do also with oro_dashboard.created_by
Final oro_dashboard CREATE TABLE query,
CREATE TABLE `oro_dashboard`
( `id` int unsigned NOT NULL,
`name` varchar(255) NOT NULL default '',
`description` varchar(64) NOT NULL default '',
`created_by` mediumint(9) unsigned NOT NULL default '0',
`created_at` date,
`layout` varchar(255) NOT NULL default '',
`default_store_id` smallint(5) unsigned,
PRIMARY KEY (`id`),
KEY `IDX_ORO_DASHBOARD_CREATED_BY` (`created_by`) ,
CONSTRAINT `FK_ORO_DASHBOARD_CREATED_BY_ADMIN_USER_USER_ID`
FOREIGN KEY (`created_by`)
REFERENCES `admin_user` (`user_id`)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_ORO_DASHBOARD_DEFAULT_STORE_ID_CORE_STORE_STORE_ID`
FOREIGN KEY (`default_store_id`)
REFERENCES `core_store` (`store_id`)
ON DELETE SET NULL ON UPDATE CASCADE
)
SQLFIddle Demo
It appears that the column definition for default_store_id does not match core_store.store_id. it should be smallint(5) unsigned in your table. created_by has the same problem, although it did not prevent the table from being created

How to create a table with composite foreign key

I created the master table with the composite primary key.
parent table structure is as follows:
CREATE TABLE `taskcategory` (
`SiteID` int(10) unsigned NOT NULL DEFAULT 1,
`TaskID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`TaskName` varchar(45) DEFAULT '',
`TaskDescription` varchar(45) DEFAULT '',
`IsInbuild` int(11) DEFAULT '1',
PRIMARY KEY (`TaskID`,`SiteID`)
);
when i am trying to create the table with foreign key with the above parent table reference i am getting 'can't create table error no 150' error . help me to do that.
child table structure as follows:
CREATE TABLE taskdetails (`SiteID` int(10) unsigned NOT NULL DEFAULT '1',
`TaskID` int(10) unsigned NOT NULL DEFAULT '0',
`SubtaskID` int(10) unsigned NOT NULL,
`ScriptName` varchar(255) DEFAULT '',
`FunctionName` varchar(255) DEFAULT '',
`ButtonName` varchar(255) DEFAULT '',
`IsInbuild` int(10) unsigned DEFAULT '1',
`Description` varchar(255) DEFAULT '',
PRIMARY KEY (`SubtaskID`,`TaskID`,`SiteID`),
INDEX (siteid, taskid),
FOREIGN KEY (siteid, taskid)
REFERENCES taskcategory(siteid, taskid)
ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=INNODB;
help me to resolve it.
From the manual:
InnoDB requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
So when you add an index in the parent table it works (yes, I tested it):
CREATE TABLE `taskcategory` (
`SiteID` int(10) unsigned NOT NULL DEFAULT 1,
`TaskID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`TaskName` varchar(45) DEFAULT '',
`TaskDescription` varchar(45) DEFAULT '',
`IsInbuild` int(11) DEFAULT '1',
PRIMARY KEY (`TaskID`,`SiteID`)
, INDEX (SiteID, TaskID)
) ENGINE=INNODB;
CREATE TABLE taskdetails (`SiteID` int(10) unsigned NOT NULL DEFAULT '1',
`TaskID` int(10) unsigned NOT NULL DEFAULT '0',
`SubtaskID` int(10) unsigned NOT NULL,
`ScriptName` varchar(255) DEFAULT '',
`FunctionName` varchar(255) DEFAULT '',
`ButtonName` varchar(255) DEFAULT '',
`IsInbuild` int(10) unsigned DEFAULT '1',
`Description` varchar(255) DEFAULT '',
PRIMARY KEY (`SubtaskID`,`TaskID`,`SiteID`)
,INDEX (SiteID, TaskID)
,FOREIGN KEY (SiteID, TaskID)
REFERENCES taskcategory(SiteID, TaskID)
ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=INNODB;
You have a primary key on those columns already (which means there's an implicit index), but the order of the columns is important!
Your table definition of taskcategory lacks the ENGINE=InnoDB clause, and probably this is not your system's default. Foreign key relations can only be set up between InnoDB tables.

insert trigger not working

I have the following table and trigger but the trigger isn't setting the create_dt value to now() on the insert event:
CREATE TABLE `user` (
`user_id` int(10) NOT NULL auto_increment,
`user_name` varchar(255) NOT NULL default '',
`password` varchar(255) NOT NULL default '',
`first_name` varchar(255) NOT NULL default '',
`last_name` varchar(255) NOT NULL default '',
`email` varchar(255) NOT NULL default '',
`modify_by` int(10) NOT NULL default '1',
`modify_dt` timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`create_by` int(10) NOT NULL default '1',
`create_dt` datetime NOT NULL default '0000-00-00 00:00:00',
`active` enum('Yes','No') NOT NULL default 'No',
PRIMARY KEY (`user_id`),
UNIQUE KEY `user_name` (`user_name`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (`modify_by`) REFERENCES `user`(`user_id`),
FOREIGN KEY (`create_by`) REFERENCES `user`(`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
CREATE TRIGGER ins_user BEFORE INSERT ON `user` FOR EACH ROW SET #create_dt = NOW();
I've tried both BEFORE and AFTER trigger action time but no change. Does anyone have any suggestions?
The goal is to have the create_dt value set with a date_time NOW() value on insert.
Setting #create_dt sets a variable. You want to SET NEW.create_dt = NOW(). This will change the value of the incoming record.