MySQL failing to create a new table using Foreign Keys - mysql

I only get an error 150 when I run this. The other tables are InnoDB, the types are primary key, and the data types match. So I can't see what I'm doing wrong, (and I see no obvious syntax errors). Any ideas?
CREATE TABLE grouptosite (
groups_id BIGINT(20),
usertogroup_groupID BIGINT(20),
usertogroup_userID BIGINT(20),
usertosite_id INT(10),
gts_id INT(10) AUTO_INCREMENT NOT NULL,
PRIMARY KEY (gts_id),
index (gts_id),
index (groups_id),
index (usertogroup_groupID),
index (usertogroup_userID),
index (usertosite_id),
FOREIGN KEY (groups_id)
REFERENCES groups(id)
ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (usertogroup_groupID, usertogroup_userID)
REFERENCES usertogroup(groupID, userID)
ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (usertosite_id)
REFERENCES usertosite(id)
ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=INNODB;

Are you sure your columns are the same type? I first created the usertosite table with the id of BIGINT (following the same pattern of the other tables), but the grouptosite.usertosite_id column was INT: http://sqlfiddle.com/#!2/d821a.
As mentioned in another comment, datatypes for foreign keys need to be the same.

Related

Why KEY has automatically created when I make fk constraint for field?

I am creating the table with this syntax:
CREATE TABLE movies_genres
(
id BIGINT AUTO_INCREMENT,
movie_id INT NOT NULL,
genre_id INT NOT NULL,
PRIMARY KEY (id),
CONSTRAINT `fk_movie_id` FOREIGN KEY (movie_id) REFERENCES movies(id),
CONSTRAINT `fk_genre_id` FOREIGN KEY (genre_id) REFERENCES genres(id),
CONSTRAINT unique_id_pair UNIQUE(movie_id, genre_id)
);
But then I look at the info about the table in MySQL Workbench I see:
CREATE TABLE `movies_genres` (
`id` bigint NOT NULL AUTO_INCREMENT,
`movie_id` int NOT NULL,
`genre_id` int NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_id_pair` (`movie_id`,`genre_id`),
KEY `fk_genre_id` (`genre_id`),
CONSTRAINT `fk_genre_id` FOREIGN KEY (`genre_id`) REFERENCES `genres` (`id`),
CONSTRAINT `fk_movie_id` FOREIGN KEY (`movie_id`) REFERENCES `movies` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
Why this line of code has generated?
KEY `fk_genre_id` (`genre_id`)
Also I see that extra index was created that I didn't order...
Screenshot with extra index
https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html says:
MySQL 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.
(emphasis mine)
(Bill gave the answer; this is providing another tip.)
Get rid of id from the table and change to these two indexes:
PRIMARY KEY (`movie_id`,`genre_id`),
KEY `fk_genre_id` (`genre_id`),
That will make some of your uses of this many-to-many table run faster. It will also shrink the table size.
If need id
Since you need id for single-row deletion and updating, keep id, but use
PRIMARY KEY (id)
INDEX(`movie_id`, `genre_id`),
INDEX(`genre_id`, `movie_id`),
The PK will continue to make Delete/Update efficient; the other two indexes will make the many-to-many JOIN efficient.

Foreign Key on MySQL

I am new to SQL and I started building my own project. I am having issues creating a foreign key on my second table. . Please let me know what I am missing here.
The second CREATE TABLE statement should be:
CREATE TABLE entry (
issuer_id INT AUTO_INCREMENT PRIMARY KEY,
issuer_name VARCHAR(20) NOT NULL,
fine INT,
book_id INT,
due_date DATE,
FOREIGN KEY (book_id)
REFERENCES book_table (book_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (due_date)
REFERENCES book_table (due_date)
ON DELETE CASCADE
ON UPDATE CASCADE
);
A foreign key is a column or set of columns in one table that links to a unique key (typically the primary key) in another table. The columns must exist in both tables. They must match in type and the order within the key declarations. They must constitute a unique key in the foreign table.

Duplicate entry error in 1 column of a composite key

I am trying to insert pseudo data into my db to get going, and in one particular table I have two columns which are FK's and PK's of the table; fk_product_manf_code and fk_content_id. To my understanding, these are considered composite keys in their current state.
So I add data to the table:
fk_product_manf_code fk_content_id
NOV-ABC123 1
I then want to associate another content_id to the same product_manf_code, so I perform the following:
INSERT INTO `mydb`.`package_contents`
(`fk_product_manf_code`, `fk_content_id`)
VALUES
('NOV-ABC123', 2);
However I'm greeted with the following error:
Error Code: 1062. Duplicate entry 'NOV-ABC123' for key 'fk_product_manf_code_UNIQUE'
I don't understand what's going, because I thought a composite key makes 2 columns unique? So why is it kicking up a fuss about just 1 column being unique?
Here is the table CREATE statement
CREATE TABLE `package_contents` (
`fk_product_manf_code` varchar(255) NOT NULL,
`fk_content_id` int(11) NOT NULL,
PRIMARY KEY (`fk_content_id`,`fk_product_manf_code`),
UNIQUE KEY `fk_content_id_UNIQUE` (`fk_content_id`),
UNIQUE KEY `fk_product_manf_code_UNIQUE` (`fk_product_manf_code`),
CONSTRAINT `content_id` FOREIGN KEY (`fk_content_id`) REFERENCES `contents` (`content_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `product_manf_code` FOREIGN KEY (`fk_product_manf_code`) REFERENCES `products` (`product_manf_code`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
So, you are learning why composite primary keys are a pain, especially for foreign key constraints. Not only are integer keys more efficient, but a single key is easier to work with.
I would suggest changing your table structure to be more like this:
CREATE TABLE package_contents (
package_contents_id int not null auto_increment primary key,
fk_product_manf_id int NOT NULL,
fk_content_id int(11) NOT NULL,
UNIQUE KEY (fk_content_id, fk_product_manf_id),
CONSTRAINT content_id FOREIGN KEY (fk_content_id)
REFERENCES contents(content_id) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT product_manf_code FOREIGN KEY (fk_product_manf_id)
REFERENCES products(product_manf_id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Note that I changed the manufacturer code to an id as well. This should also reduce the size of the table, assuming that the "code" is longer than 4 bytes.
If you do this for all your tables, the database will be a bit more efficient, and you won't need superfluous unique constraints. The foreign key constraints should always be to primary keys (unless there is a very good reason for using a different unique key).

Cannot add foreign key constraint on a date field

I have the following SQL statements:
CREATE TABLE patient(
Name varchar(255),
Geburtsdatum date,
CONSTRAINT pk_patient PRIMARY KEY (Name,Geburtsdatum)
);
CREATE TABLE fake(
Name varchar(255),
PName varchar(255),
PGeburtsdatum date,
CONSTRAINT pk_fake PRIMARY KEY (Name,PName,PGeburtsdatum),
CONSTRAINT fk_PName2 FOREIGN KEY (PName) REFERENCES patient(Name) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_PGeburtsdatum FOREIGN KEY (PGeburtsdatum) REFERENCES patient(Geburtsdatum) ON DELETE CASCADE ON UPDATE CASCADE
);
This gives me the error "#1215 - Cannot add foreign key constraint". If I remove the last constraint in the second table creation everything works. All my other foreign key constraints work exactly the same way. What am I missing here?
Not sure why you tagged a mysql question as db2. Anyway, the MySQL documentation states:
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan
So add an index in the Geburtsdatum column:
CREATE TABLE patient(
Name varchar(255),
Geburtsdatum date,
INDEX (Geburtsdatum),
CONSTRAINT pk_patient PRIMARY KEY (Name,Geburtsdatum)
);

Error when inserting multiple MySQL foreign keys

When I try to insert the current table into my table in SQL I get an error (Products table):
CREATE TABLE parent(
Barcode INT(9),
PRIMARY KEY (Barcode)
) ENGINE=INNODB;
CREATE TABLE SuppliedBy(
Onr CHAR(10),
OrgNR INT(10),
Date DATE NOT NULL,
PRIMARY KEY (Onr),
FOREIGN KEY (OrgNR) REFERENCES Supplier(OrgNR)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=INNODB;
CREATE TABLE Products(
Onr CHAR(10),
Barcode INT(9),
Quantity INT(10) DEFAULT 0
CHECK (Quantity >= 0),
PRIMARY KEY (Onr, Barcode),
FOREIGN KEY (Onr) REFERENCES SuppliedBy(SSN)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (Barcode) REFERENCES parent(Barcode)
ON DELETE CASCADE
ON UPDATE CASCADE
)ENGINE=INNODB;
I get the following message:
#1005 - Can't create table '.\db_project\#sql-b58_6d.frm' (errno: 150)
I'm sure it has to do with the several foreign keys in this relation, I searched around on the internet, but can't find the solution.
There is no column SuppliedBy.SSN.
FOREIGN KEY (Onr) REFERENCES SuppliedBy(SSN)
Perhaps you meant
FOREIGN KEY (Onr) REFERENCES SuppliedBy(Onr)
ON DELETE CASCADE
ON UPDATE CASCADE,
I believe the issue is likely that one of the tables you're defining the FOREIGN KEYS to point to does not have an index foreign key field you're pointing to.
For FOREIGN KEY's to work, the field you're pointing to needs to have an index on it.
See Mysql. Can't create table errno 150
Also, check that you meet all the criteria for creating the key. The columns in both tables must:
Be the same datatype
Be the same size or length
Have indexes defined.