Constraints wrong according to mySQL - mysql

Not sure what I'm overseeing here, according to mySQL my constrains are malformed (the remarked part).
Didn't figure out yet what I did wrong using the allmighty internet search engine with G.
Advice greatly appreciated.
CREATE TABLE `documentsCustomers` (
`id` INT(12) NOT NULL AUTO_INCREMENT,
`document` INT(12) NOT NULL DEFAULT '0',
`customer` INT(12) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
INDEX `document` (`document`),
INDEX `customer` (`customer`)
/*,
CONSTRAINT `fk_document` FOREIGN KEY (`document`) REFERENCES `documents` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT,
CONSTRAINT `fk_customer` FOREIGN KEY (`customer`) REFERENCES `customers` (`ID`) ON UPDATE RESTRICT ON DELETE RESTRICT
*/
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
Note it is actually correct, one table having ID capital and the other one not.

Related

On Cascade Delete does not seem to be applying in my DB

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';

MySQL foreign key restrictions are not being saved

I'm using MySQL version 5.5.25 and trying to create a foreign key from id_parent to id on the same table.
CREATE TABLE `acl_roles` (
`id` int(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(60) NOT NULL,
`id_parent` int(20) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_acl_roles` (`id_parent`),
CONSTRAINT `FK_acl_roles` FOREIGN KEY (`id_parent`) REFERENCES `acl_roles` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
When I do
ALTER TABLE `acl_roles` ADD CONSTRAINT `FK_acl_roles` FOREIGN KEY (`id_parent`) REFERENCES `acl_roles` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ;
For some reason the latter executes without error yet when I execute SHOW CREATE TABLE acl_roles I get the exact same schema and the restrictions are not applied no matter how many times I run the query.
ON DELETE RESTRICT ON UPDATE RESTRICT is the default behavior for FK constraints, that is why you see no difference when viewing the schema. It is implied.

MySQL Nullable FK and the 150 error

I have a problem with create table statement in MySQL.
The scenario is, I want to have a table P_CDP wchich stores some informations, and the table P_CDPFiles which stores the data of the uploaded files.
The column SelectedCDPFileID by default should be NULL unless the user selects some file. Then that column is filled by the file ID. But, I'm still getting the errno 150, why ? I think the FK names are set properly
CREATE TABLE `P_CDP` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`P_OrderID` int(11) NOT NULL DEFAULT '0',
`SelectedCDPFileID` int(11) NULL,
PRIMARY KEY (`ID`),
KEY `FK_P_CDP_P_Orders` (`P_OrderID`),
KEY `FK_P_CDP_P_CDPFiles` (`SelectedCDPFileID`),
CONSTRAINT `FK_P_CDP_P_Orders` FOREIGN KEY (`P_OrderID`) REFERENCES `P_Orders` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_P_CDP_P_CDPFiles` FOREIGN KEY (`SelectedCDPFileID`) REFERENCES `P_CDPFiles` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `P_CDPFiles` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`FileID` int(11) NOT NULL DEFAULT '0',
`P_CDPID` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `FK_P_CDPFiles_File` (`FileID`),
KEY `FK_P_CDPFiles_P_CDP` (`P_CDPID`),
CONSTRAINT `FK_P_CDPFiles_File` FOREIGN KEY (`FileID`) REFERENCES `File` (`FileID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_P_CDPFiles_P_CDP` FOREIGN KEY (`P_CDPID`) REFERENCES `P_CDP` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
You're attempting to reference a table that does not yet exist.
If you must have references in both directions between these two tables (which generally indicates quite poor design), you will have to:
Create the first table without any reference to the as-yet-undefined table:
CREATE TABLE `P_CDP` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`P_OrderID` int(11) NOT NULL DEFAULT '0',
`SelectedCDPFileID` int(11) NULL,
PRIMARY KEY (`ID`),
KEY `FK_P_CDP_P_Orders` (`P_OrderID`),
KEY `FK_P_CDP_P_CDPFiles` (`SelectedCDPFileID`),
CONSTRAINT `FK_P_CDP_P_Orders` FOREIGN KEY (`P_OrderID`)
REFERENCES `P_Orders` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Create the second table, including its reference to the first table:
CREATE TABLE `P_CDPFiles` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`FileID` int(11) NOT NULL DEFAULT '0',
`P_CDPID` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `FK_P_CDPFiles_File` (`FileID`),
KEY `FK_P_CDPFiles_P_CDP` (`P_CDPID`),
CONSTRAINT `FK_P_CDPFiles_File` FOREIGN KEY (`FileID`)
REFERENCES `File` (`FileID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_P_CDPFiles_P_CDP` FOREIGN KEY (`P_CDPID`)
REFERENCES `P_CDP` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Alter the first table to add the intended constraint:
ALTER TABLE `P_CDP`
ADD CONSTRAINT `FK_P_CDP_P_CDPFiles` FOREIGN KEY (`SelectedCDPFileID`)
REFERENCES `P_CDPFiles` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION;

Foreign constraint On Delete Cascade not working

I have a custom table created which has a foreign constraint on the core_website table. However, the on delete cascade isn't working.
I did a search and found this relevant thread, which notes that the data types between the two columns have to be the same. Both data types are smallint(5).
I did notice one minor discrepancy in the column definition, which is that in core_website, Allow Null is not set, and Default is not set to zero, whereas in the account table, Allow Null is set and Default is zero. I didn't think changing these would have any effect, but I went ahead and changed them on the account table to match, but that didn't help.
CREATE TABLE `account` (
`account_id` smallint(11) unsigned NOT NULL AUTO_INCREMENT,
`website_id` smallint(5) unsigned DEFAULT '0',
`code` varchar(64) NOT NULL DEFAULT '',
PRIMARY KEY (`account_id`),
UNIQUE KEY `code` (`code`),
KEY `FK_WEBSITE_ID` (`website_id`),
CONSTRAINT `FK_WEBSITE_ID` FOREIGN KEY (`website_id`) REFERENCES `core_website` (`website_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8
try this and let us the result pls.
CREATE TABLE `account` (
`account_id` smallint(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`website_id` smallint(5) unsigned DEFAULT '0',
`code` varchar(64) NOT NULL DEFAULT '',
UNIQUE KEY `code` (`code`),
KEY `FK_WEBSITE_ID` (`website_id`),
CONSTRAINT `FK_WEBSITE_ID` FOREIGN KEY (`website_id`) REFERENCES `core_website` (`website_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8
You need add foreign key to core_website table and point it to website_id field in account table. In other words, foreign key should be added to the dependent table and pointed to main table, in this case when you delete row from main table - row from dependent table will be deleted because of FK. In your case you did it "upside down".

What is the difference between these two SQL queries?

I've created table Address with this SQL query:
CREATE TABLE `address` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`Street` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`Number` smallint(6) DEFAULT NULL,
`other_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`other_id`) REFERENCES `other` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
But there's also this query:
CREATE TABLE `address` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`Street` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`Number` smallint(6) DEFAULT NULL,
`other_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `other_id` (`other_id`),
CONSTRAINT `adress_ibfk_1` FOREIGN KEY (`other_id`) REFERENCES `other` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci$$
and it seems that booth query create identical tables.
So can anyone explain to me what does this line do:
KEY `other_id` (`other_id`),
and what is the difference between these two lines:
FOREIGN KEY (`other_id`) REFERENCES `other` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
and
CONSTRAINT `adress_ibfk_1` FOREIGN KEY (`other_id`) REFERENCES `other` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
If the difference between last two lines is that latter gives name 'adress_ibfk_1' to foreign key ? If that's true - should I do it ? I mean, why should I name foreign keys ? Will I ever need their names ?
Thanks ! :)
MySQL interprets KEY as an index, so the second query creates an index on the column other_id.
The difference between the two FK declaration is that you manually set the name in the second line. In the first line, MySQL automatically sets a name.
They do need names, but you don't necessarily have to be aware of them. Some more advanced RDBMS use them to be more explicit when a query raises an error.
KEY is a synonym for INDEX, so that is creating an index on the other_id column.
The only difference in the foreign key construction is that the latter constraint version allows you to name the constraint, whereas the former will be given a system generated name.
This name can be seen in the INFORMATION_SCHEMA TABLE_CONSTRAINTS table.