I have the followiing tables:
CREATE TABLE `Atletica` (
`Universidade` varchar(100) NOT NULL,
`Nome` varchar(100) NOT NULL,
`Logo` varchar(100) NOT NULL,
`GritoDeGuerra` varchar(100) NOT NULL,
`EnderecoCEP` int(11) NOT NULL,
`EnderecoNumero` int(11) NOT NULL,
`MedalhaOuro` int(6) NOT NULL,
`MedalhaPrata` int(6) NOT NULL,
`MedalhaBronze` int(6) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `Endereco`
--
CREATE TABLE `Endereco` (
`Rua` varchar(50) NOT NULL,
`Numero` int(11) NOT NULL,
`Bairro` varchar(50) DEFAULT NULL,
`CEP` int(11) NOT NULL,
`Cidade` varchar(50) NOT NULL,
`Estado` varchar(50) NOT NULL,
`Complemento` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `Atletica`
--
ALTER TABLE `Atletica`
ADD PRIMARY KEY (`Universidade`,`Nome`),
ADD KEY `EnderecoCEP` (`EnderecoCEP`),
ADD KEY `EnderecoNumero` (`EnderecoNumero`);
--
-- Indexes for table `Endereco`
--
ALTER TABLE `Endereco`
ADD PRIMARY KEY (`Numero`,`CEP`);
And I keep getting the error:
Error creating foreign key on EnderecoCEP, EnderecoNumero (check data types)
when I try to execute the following command:
ALTER TABLE `Atletica`
ADD FOREIGN KEY (`EnderecoCEP`, `EnderecoNumero`)
REFERENCES `proj3`.`Endereco`(`CEP`, `Numero`)
ON DELETE RESTRICT ON UPDATE RESTRICT;
Ive read tons of similar questions here but all of them the error was an obvious data type mismatch. I only have those two table on my database. Please help.
Thank you very much for your time.
As it turns out, when you create a foreign key with multiple columns, it should be in the same order ar the primary key in the referencing table.
Related
I´m trying to create Foreign Keys in phpmyadmin, but I get this error:
Error creating foreign key on revision (check data types)
I don´t understand it because the data types are equal. So, what I want is to create a Foreign Key from 'acoustictreatment' to 'filterspecifications' which contains tag, offerid and revision. But I get the error that I mentioned.
This are my tables:
CREATE TABLE `offer` (
`projectid` varchar(20) NOT NULL,
`customer` varchar(255) NOT NULL,
`creator` varchar(255) NOT NULL,
`date` date NOT NULL,
`revision` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `offer`
ADD PRIMARY KEY (`projectid`,`revision`);
CREATE TABLE `filterspecifications` (
`tag` varchar(100) NOT NULL,
`gasFlow` double NOT NULL,
`dustToHandle` double NOT NULL,
`offerid` varchar(20) NOT NULL,
`selectedFilter` varchar(20) NOT NULL,
`revision` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `filterspecifications`
ADD PRIMARY KEY (`tag`,`offerid`,`revision`),
ADD KEY `offerid` (`offerid`,`revision`);
ALTER TABLE `filterspecifications`
ADD CONSTRAINT `filterspecifications_ibfk_1`
FOREIGN KEY (`offerid`,`revision`) REFERENCES `offer` (`projectid`, `revision`) ON DELETE CASCADE ON UPDATE CASCADE;
CREATE TABLE `acoustictreatment` (
`tag` varchar(100) NOT NULL,
`offerid` varchar(20) NOT NULL,
`outputFanSilencer` tinyint(1) NOT NULL,
`fanAcousticInsulation` tinyint(1) NOT NULL,
`revision` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `acoustictreatment`
ADD PRIMARY KEY (`tag`,`offerid`,`revision`);
The solution that I found is to delete the 'acoustictreatment' table and create it again with the foreign key from the beginning. Because what I was trying to do was to create all the tables and then create the foreign keys, but that didn´t work for me
Creating a new database here for school and having difficulty in understanding what's wrong here.
For example, I want to create this table (automated SQL output):
-- -----------------------------------------------------
-- Table `jobsearch`.`Employer`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `jobsearch`.`Employer`
(
`EmployerID` SMALLINT(5) NOT NULL AUTO_INCREMENT,
`IndustryID` SMALLINT(5) NOT NULL,
`Address` VARCHAR(45) NOT NULL,
`City` VARCHAR(45) NOT NULL,
`State` CHAR(2) NOT NULL,
`Zip` VARCHAR(5) NOT NULL,
`Phone` VARCHAR(10) NOT NULL,
PRIMARY KEY (`EmployerID`, `IndustryID`),
INDEX `fk_Employer_Industry1_idx` (`IndustryID` ASC),
CONSTRAINT `fk_Employer_Industry1`
FOREIGN KEY (`IndustryID`) REFERENCES `job search`.`Industry` (`IndustryID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
I have this table that the foreign should be referencing (This table was created without any issue):
CREATE TABLE IF NOT EXISTS `jobsearch`.`Industry`
(
`IndustryID` INT NOT NULL AUTO_INCREMENT,
`IndustryName` VARCHAR(45) NOT NULL,
`Region` VARCHAR(45) NOT NULL,
PRIMARY KEY (`IndustryID`))
ENGINE = InnoDB;
The datatype for the referencing column must match exactly that of the referenced column. You've defined `Industry.IndustryID as
`IndustryID` INT ...
and Employer.IndustryID as
`IndustryID` SMALLINT(5) ...
Change Employer.IndustryID to INT and you should be shiny.
I have the following InnoDB tables:
CREATE TABLE `vehicle` (
`ID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) DEFAULT NULL,
`Model` varchar(100) DEFAULT NULL,
`Engine_Type` varchar(70) DEFAULT NULL,
`Construction_From` date DEFAULT NULL,
`Construction_To` date DEFAULT NULL,
`Engine_Power_KW` mediumint(8) unsigned DEFAULT NULL,
`Engine_Power_HP` mediumint(8) unsigned DEFAULT NULL,
`CC` mediumint(8) unsigned DEFAULT NULL,
`TTC_TYP_ID` int(11) unsigned DEFAULT NULL,
`Vehicle_Type` tinyint(1) DEFAULT NULL,
`ID_Body_Type` tinyint(3) unsigned DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=49407 DEFAULT CHARSET=utf8;
CREATE TABLE `part` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ID_Brand` smallint(5) unsigned DEFAULT NULL,
`Code_Full` varchar(50) DEFAULT NULL,
`Code_Condensed` varchar(50) DEFAULT NULL,
`Ean` varchar(50) DEFAULT NULL COMMENT 'The part barcode.',
`TTC_ART_ID` int(11) unsigned DEFAULT NULL COMMENT 'TecDoc ID.',
`ID_Product_Status` tinyint(3) unsigned DEFAULT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `TTC_ART_ID_UNIQUE` (`TTC_ART_ID`),
UNIQUE KEY `ID_Brand_Code_Full_UNIQUE` (`ID_Brand`,`Code_Full`)
) ENGINE=InnoDB AUTO_INCREMENT=3732260 DEFAULT CHARSET=utf8;
CREATE TABLE `vehicle_part` (
`ID_Vehicle` mediumint(8) unsigned NOT NULL,
`ID_Part` int(11) unsigned NOT NULL,
PRIMARY KEY (`ID_Vehicle`,`ID_Part`),
KEY `fk_vehicle_part_vehicle_id_vehicle_idx` (`ID_Vehicle`),
KEY `fk_vehicle_part_part_id_part_idx` (`ID_Part`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Table vehicle has about 45.000 records, table part has about 3.500.000 records and table vehicle_part has approximately 100.000.000 records.
Creating the secondary indexes for vehicle_part did not take too long, about 30 min for both.
What I cannot do though is create the foreign key constraints: for example
ALTER TABLE `vehicle_part`
ADD CONSTRAINT `fk_vehicle_part_vehicle_id_vehicle`
FOREIGN KEY (`ID_Vehicle`)
REFERENCES `vehicle` (`ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
takes ages to complete. I understand the table is rebuilt since it consumes a lot of disk space. What can I do to improve the performance?
If I create the table with the fk constraints and then add the records the insert process in vehicle_part also takes ages (about 3 days).
I am using a laptop with 4GB RAM.
EDIT 12/01/2016
The answer given by Drew helped a lot in improving the performance dramatically. I changed every script using SELECT ... INTO outfile and then LOAD DATA INFILE from the exported csv file. Also sometimes before LOAD DATA INFILE dropping the indexes and recreating them after the load proccess saves even more time. There is no need to drop the fk constraints just the secondary indexes.
If you know your data is pristine from an FK perspective, then establish your structure without secondary indexes as suggested in comments, but with the FK in the schema yet with FK checks temporarily disabled.
Load your data. If external data, certainly do it with LOAD DATA INFILE.
After your data is loaded, turn on FK checks. And establish secondary indexes with Alter Table.
Again, going with the assumption that your data is clean. There are other ways of proving that after-the-fact for the risk-adverse.
create table student
( id int auto_increment primary key,
sName varchar(100) not null
-- secondary indexes to be added later
);
create table booksAssigned
( id int auto_increment primary key,
studentId int not null,
isbn varchar(20) not null,
constraint foreign key `fk_b_s` (studentId) references student(id)
-- secondary indexes to be added later
);
insert booksAssigned(studentId,isbn) values (1,'asdf'); -- Error 1452 as expected
set FOREIGN_KEY_CHECKS=0; -- turn FK checks of temporarily
insert booksAssigned(studentId,isbn) values (1,'asdf'); -- Error 1452 as expected
set FOREIGN_KEY_CHECKS=1; -- succeeds despite faulty data
insert booksAssigned(studentId,isbn) values (2,'38383-asdf'); -- Error 1452 as expected
As per op comments, how to drop auto-generated index in referencing table after initial schema creation:
mysql> show create table booksAssigned;
| booksAssigned | CREATE TABLE `booksassigned` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`studentId` int(11) NOT NULL,
`isbn` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_b_s` (`studentId`),
CONSTRAINT `booksassigned_ibfk_1` FOREIGN KEY (`studentId`) REFERENCES `student` (`id`)
) ENGINE=InnoDB |
mysql> set FOREIGN_KEY_CHECKS=0;
Query OK, 0 rows affected (0.00 sec)
mysql> drop index `fk_b_s` on booksAssigned;
Query OK, 0 rows affected (0.49 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table booksAssigned;
| booksAssigned | CREATE TABLE `booksassigned` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`studentId` int(11) NOT NULL,
`isbn` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `booksassigned_ibfk_1` FOREIGN KEY (`studentId`) REFERENCES `student` (`id`)
) ENGINE=InnoDB |
Further links
Temporarily disable foreign keys
A Rolando Answer
I am attempting to create a data model. It's fairly complicated, but I'm trying to link the Splits table to the Trials table. A screenshot of the model is below:
I'm attempting to make Splits.protocol + Splits.resultID + Splits.trialNumber a foreign key to Trials. Those three relations are the primary key of Trials. I'm doing this with MySQL Workbench and it throws an Error #150. Does anyone know what the problem is?
Here is the SQL statement and the error that it throws when attempting to execute it:
ERROR 1005: Can't create table '403898_BAMNormalized.#sql-7285_6c29081' (errno: 150)
SQL Statement:
ALTER TABLE `403898_BAMNormalized`.`Splits`
ADD CONSTRAINT `FK_FromTrial`
FOREIGN KEY (`protocol` , `resultID` , `trialNumber`)
REFERENCES `403898_BAMNormalized`.`Trials` (`protocol` , `resultID` , `trialNumber`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
ERROR: Error when running failback script. Details follow.
ERROR 1050: Table 'Splits' already exists
SQL Statement:
CREATE TABLE `Splits` (
`protocol` varchar(255) NOT NULL,
`resultID` int(11) NOT NULL,
`trialNumber` int(11) NOT NULL,
`splitNumber` int(11) NOT NULL,
`splitScore` decimal(10,0) NOT NULL,
PRIMARY KEY (`protocol`,`resultID`,`trialNumber`,`splitNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Here are the create table statements:
CREATE TABLE `Trials` (
`resultID` int(11) NOT NULL,
`protocol` varchar(255) NOT NULL,
`trialNumber` int(11) NOT NULL,
`trialScore` decimal(10,0) NOT NULL,
`best` char(1) DEFAULT NULL,
`DQFlag` varchar(45) DEFAULT NULL,
PRIMARY KEY (`resultID`,`protocol`,`trialNumber`),
CONSTRAINT `FK_trialID` FOREIGN KEY (`resultID`, `protocol`) REFERENCES `ResultsDetails` (`resultID`, `protocol`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `Splits` (
`protocol` varchar(255) NOT NULL,
`resultID` int(11) NOT NULL,
`trialNumber` int(11) NOT NULL,
`splitNumber` int(11) NOT NULL,
`splitScore` decimal(10,0) NOT NULL,
PRIMARY KEY (`protocol`,`resultID`,`trialNumber`,`splitNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Indexes of Trials table:
Reordering the index to represent the same order as the foreign key was the solution. See comments appended to original post for detailed information.
I have this weird issue with creation of foreign key.
Given 2 tables:
CREATE TABLE IF NOT EXISTS `groupdeals` (
`groupdeals_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`product_id` int(10) NOT NULL,
`merchant_id` int(11) NOT NULL,
`minimum_qty` int(11) NOT NULL,
`maximum_qty` int(11) NOT NULL,
`target_met_email` int(11) NOT NULL,
`coupon_barcode` text NOT NULL,
`coupon_merchant_address` int(11) NOT NULL,
`coupon_merchant_contact` int(11) NOT NULL,
`coupon_expiration_date` date DEFAULT NULL,
`coupon_price` int(11) NOT NULL,
`coupon_fine_print` int(11) NOT NULL,
`coupon_highlights` int(11) NOT NULL,
`coupon_merchant_description` int(11) NOT NULL,
`coupon_business_hours` int(11) NOT NULL,
`coupon_merchant_logo` int(11) NOT NULL,
`coupon_additional_info` text NOT NULL,
`position` int(11) NOT NULL,
PRIMARY KEY (`groupdeals_id`),
KEY `groupdeals_id` (`groupdeals_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and
CREATE TABLE IF NOT EXISTS `groupdeals_coupons` (
`coupon_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`groupdeals_id` int(11) NOT NULL,
`order_item_id` int(11) NOT NULL,
`coupon_code` varchar(255) NOT NULL DEFAULT '',
`redeem` varchar(255) NOT NULL DEFAULT '',
`status` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`coupon_id`),
KEY `fk_groupdeals_coupons_groupdeals1_idx` (`groupdeals_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I try to add foreign key by executing following query:
ALTER TABLE `groupdeals_coupons`
ADD CONSTRAINT `fk_groupdeals_coupons_groupdeals1`
FOREIGN KEY (`groupdeals_id`)
REFERENCES `groupdeals` (`groupdeals_id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
All I receive is Error:
#1215 - Cannot add foreign key constraint
Show engine innodb status
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2013-08-17 13:47:49 7ff5dbb2c700 Error in foreign key constraint of table xxxxx/#sql-7b23_282b1a:
FOREIGN KEY (`groupdeals_id`)
REFERENCES `groupdeals` (`groupdeals_id`)
ON DELETE CASCADE
ON UPDATE CASCADE:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
The column groupdeals.groupdeals_id is a primary one, so I really can't understand where is a problem :|
Any hints?
Server type: Percona Server
Server version: 5.6.11-rc60.3-log - Percona Server (GPL), Release 60.3
Your types are inconsistent:
CREATE TABLE IF NOT EXISTS `groupdeals` (
`groupdeals_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
CREATE TABLE IF NOT EXISTS `groupdeals_coupons` (
[...]
`groupdeals_id` int(11) NOT NULL,
As you will see, in one table you have int unsigned. In the other, just int.
BTW, I noticed you have two keys on groupdeals_id. Is that on purpose?
CREATE TABLE IF NOT EXISTS `groupdeals` (
[...]
PRIMARY KEY (`groupdeals_id`),
KEY `groupdeals_id` (`groupdeals_id`)
Try these two steps to add foreign key:-
alter table groupdeals_coupons modify groupdeals_id int unsigned not null default 0;
ALTER TABLE groupdeals_coupons ADD CONSTRAINT fk_groupdeals_coupons_groupdeals1 FOREIGN KEY (groupdeals_id) references groupdeals (roupdeals_id);