I'm trying to implement the tables shown in the picture:
this picture
(database scheme taken from http://www.databaseanswers.org/data_models/recipes/index.htm).
But I'm having problems with the Recipe_step_ingredients table. When adding foreign key constraints, I get error #1215 for the recipe_steps_id constraint (when not adding that constraint, I don't get the error and I can add the other two constraints).
Here is may command for creating the table:
CREATE TABLE recipe_step_ingredients (
recipe_id INTEGER,
step_number INTEGER,
ingredient_id INTEGER,
amount_required VARCHAR(128),
CONSTRAINT FOREIGN KEY (recipe_id) REFERENCES recipe_steps (recipe_id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY (step_number) REFERENCES recipe_steps (step_number) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY (ingredient_id) REFERENCES ingredients (ingredient_id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (recipe_id, step_number, ingredient_id)
) ENGINE = INNODB
Anybody knows what could be the problem with it?
EDIT: Changed the code to match the naming conventions in the picture.
Also, here is the rest of the DDL I used:
CREATE TABLE recipes (
recipe_id INTEGER NOT NULL AUTO_INCREMENT,
recipe_name VARCHAR(128),
recipe_description VARCHAR(4096),
PRIMARY KEY (recipe_id),
INDEX (recipe_name)
) ENGINE = INNODB
CREATE TABLE recipe_steps (
recipe_id INTEGER,
step_number INTEGER,
instructions VARCHAR(4096),
CONSTRAINT FOREIGN KEY (recipe_id) REFERENCES recipes (recipe_id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (recipe_id, step_number)
) ENGINE = INNODB
CREATE TABLE ingredient_types (
ingredient_type_id INTEGER NOT NULL AUTO_INCREMENT,
ingredient_type_description VARCHAR(4096),
PRIMARY KEY (ingredient_type_id)
) ENGINE = INNODB
ALTER TABLE ingredient_types ADD COLUMN ingredient_type_name VARCHAR(128);
ALTER TABLE ingredient_types ADD INDEX(ingredient_type_name);
CREATE TABLE ingredients (
ingredient_id INTEGER NOT NULL AUTO_INCREMENT,
ingredient_type_id INTEGER,
ingredient_name VARCHAR(128),
CONSTRAINT FOREIGN KEY (ingredient_type_id) REFERENCES ingredient_types (ingredient_type_id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (ingredient_id),
INDEX (ingredient_name)
) ENGINE = INNODB
CREATE TABLE recipe_step_ingredients (
recipe_id INTEGER,
step_number INTEGER,
ingredient_id INTEGER,
amount_required VARCHAR(128),
CONSTRAINT FOREIGN KEY (recipe_id) REFERENCES recipe_steps (recipe_id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY (step_number) REFERENCES recipe_steps (step_number) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY (ingredient_id) REFERENCES ingredients (ingredient_id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (recipe_id, step_number, ingredient_id)
) ENGINE = INNODB
Make sure that:
the foreign key references ALL the attributes of the key of the referenced relation (you cannot reference only some of them). SO if the key of R is (A,B), you should reference both A and B. You cannot reference only A or only B.
the attribute(s) you are referencing in a foreign key constraint is defined as UNIQUE or is the Primary key of the relation. In Mysql this can also be done by defining the attribute a KEY or UNIQUE KEY.
If you are referencing the primary key you don't need to indicate the name of the attribute after the table (the default is its primary key).
In your case,
make sure that the table recipe_steps has an attribute recipe_steps_id, and
this attribute is either UNIQUE KEY, KEY or the primary key of the relation
Also, make sure the corresponding index (for the key) has been created.
Related
I've created two tables to do mappings between users. First for users and second for user-mappings. Deletion of users work well, but if I try to update the user id the foreign key constraints from the mapping table fail (without a helpful error output).
CREATE TABLE user (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(55),
PRIMARY KEY (`id`)
);
CREATE TABLE user_map (
map_id INT NOT NULL AUTO_INCREMENT,
user_a INT,
user_b INT,
PRIMARY KEY (`map_id`),
UNIQUE KEY `one_way` (`user_a`,`user_b`),
UNIQUE KEY `other_way` (`user_b`,`user_a`),
CONSTRAINT `acc_connections_ibfk_1` FOREIGN KEY (`user_a`) REFERENCES `user` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `acc_connections_ibfk_2` FOREIGN KEY (`user_b`) REFERENCES `user` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
Example Data:
INSERT INTO user (name) VALUES ("User A");
INSERT INTO user_map (user_a,user_b) VALUES (1,1);
If I try to update the user id afterwards I get the following error:
Cannot add or update a child row: a foreign key constraint fails
(`test_db`.`user_map`, CONSTRAINT `user_map_ibfk_2`
FOREIGN KEY (`user_b`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
DB Fiddle (Demo)
Interestingly deleting the parent row (user table) succeeds without an error.
What am I doing wrong? I see no reason why this should fail.
I don't know if this is a bug or intended behavior.
As a workaround, if your version of MySql is 8.0.13+, which supports Functional Key Parts, you can use 1 UNIQUE KEY (to check the uniqueness of the combination of the 2 columns) instead of the 2 keys and the UPDATE statement will work:
CREATE TABLE IF NOT EXISTS user_map (
map_id INT NOT NULL AUTO_INCREMENT,
user_a INT,
user_b INT,
PRIMARY KEY (`map_id`),
UNIQUE KEY unk_users((LEAST(`user_a`,`user_b`)), (GREATEST(`user_a`,`user_b`))),
CONSTRAINT `acc_connections_ibfk_1` FOREIGN KEY (`user_a`) REFERENCES `user` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `acc_connections_ibfk_2` FOREIGN KEY (`user_b`) REFERENCES `user` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
);
See the demo.
I'm referencing the primary key of the table, which is also a foreign key. The exact error I'm getting is this:
"Foreign key 'customer_username' references invalid column 'customer_username' in referencing table 'CustomerAddstoCartProduct'."
create table Customers(
username varchar(20) PRIMARY KEY,
points int
FOREIGN KEY(username) REFERENCES Users ON DELETE CASCADE ON UPDATE CASCADE
)
create table CustomerAddstoCartProduct (
serial_no int,
customer_name varchar (20)
PRIMARY KEY(serial_no, customer_name)
FOREIGN KEY(serial_no) REFERENCES Products ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(customer_username) REFERENCES Customers ON DELETE CASCADE ON UPDATE CASCADE
)
All of your foreign keys declarations are malformed, they are missing the referred column in the target table.
Eg, in table CustomerAddstoCartProduct, you should have:
FOREIGN KEY(customer_username) REFERENCES Customers(username)
ON DELETE CASCADE ON UPDATE CASCADE
Instead of:
FOREIGN KEY(customer_username) REFERENCES Customers
ON DELETE CASCADE ON UPDATE CASCADE
Another thing that is akward is that, in table Customers, your primary key column has a foreign key constraint. While this might work, this probably indicates a design issue. If you have a 1:1 relationship between Customers and Users, you should probably be storing all columns in the same table.
Include the column being referenced and use the correct column name:
create table CustomerAddstoCartProduct (
serial_no int,
customer_name varchar(20)
PRIMARY KEY(serial_no, customer_name)
FOREIGN KEY(serial_no) REFERENCES Products (serial_no) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (customer_name) REFERENCES Customers (username) ON DELETE CASCADE ON UPDATE CASCADE
);
Here is a db<>fiddle -- with the extraneous table references commented out.
I'm trying to create two relations by MySQL, while I was creating the second relation "t2", I added a foreign constraint to the first relation "t1".
The first table "t1" was been built successfully, but it showed "Error Code: 1822. Failed to add the foreign key constraint. Missing index for constraint 'FK2' in the referenced table 't1'" during creating the second table "t2".
I have checked some issues like mine, some solutions were the referenced attribute in the first table should be unique or primary key. But "Mon" already has been the PK in the first table.
What's wrong in my code?
create table t1
( Num INT(10) NOT NULL,
Mon VARCHAR(7) NOT NULL,
CONSTRAINT PK1 PRIMARY KEY (Num, Mon)
);
CREATE TABLE t2
( Num INT(10) NOT NULL,
Mon VARCHAR(7) NOT NULL,
Totle_Income Decimal(9,2) DEFAULT 0,
CONSTRAINT PK2 PRIMARY KEY (Num, Mon),
CONSTRAINT FK1 FOREIGN KEY (Num) REFERENCES t1(Num)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FK2 FOREIGN KEY (Mon) REFERENCES t1(Mon)
ON DELETE CASCADE ON UPDATE CASCADE
);
t1.mon is only the second component of the primary key, thus also only the second component of the index. That doesn't usefully index t1.mon, it needed to be the first or only component of the index.
But you likely want to reference the complete key. So the foreign key constraint should include both columns rather than having two constraints for each part of the key.
...
CONSTRAINT FK1
FOREIGN KEY (Num,
Mon)
REFERENCES t1
(Num,
Mon)
ON DELETE CASCADE
ON UPDATE CASCADE,
...
t1.monis not unique and therefore can not be refered as a foreign_key
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)
);
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.