how to create foreignkey constraints in this scenario - mysql

How to create foreignkey constraints in this scenario?
One asterisk- primary key
Two asterisks- foreign key
Tutor table:
**tutorId
firstname
surname
telephoneNo
qualification
employmentDate
introducedBy*
Course table:
**courseCode
courseName
lengthHours
tuitonFee
tutorId*
roomNo*

This is well documented here:
https://www.w3schools.com/sql/sql_foreignkey.asp
I would recommend renaming your columns. Camelcase is one thing, but it is better to either use PascalCase or underscore as separator. Do note that firstname is two words, which should follow your standard. You've also not stated what the reference table is for roomNo or introducedBy, so you will have to edit my code with that information. If they are indeed supposed to be keys, they should probably have ID in the column name.
Fiddle:
https://www.db-fiddle.com/f/6EKuZ7DcCRsAvmrLGYcJrx/1
CREATE TABLE tutor (
tutorId INT NOT NULL,
firstname varchar(50),
surname varchar(50),
telephoneNo varchar(50),
qualification varchar(50),
employmentDate datetime,
introducedBy int,
PRIMARY KEY (tutorId)
/* FOREIGN KEY (introducedBy) REFERENCES ????? */
) ENGINE=INNODB;
CREATE TABLE courseCode (
courceCode int,
courceName varchar(50),
tutorId INT,
lenghtHours INT,
tuitonFee INT,
roomNo varchar(50),
INDEX par_ind (tutorId),
PRIMARY KEY (courceCode),
/* FOREIGN KEY (roomNo) REFERENCES ????? */
FOREIGN KEY (tutorId) REFERENCES tutor(tutorId)
ON DELETE CASCADE
) ENGINE=INNODB;

Related

Can a primary key of a subclass table be referenced as a foreign key?

I'm currently working on a mysql project for my class and I'm wondering if the PK-FK of a subclass table can be referenced as FK for another table instead of the PK of the parent class.
Let's say I have the subclass table employees written as:
CREATE TABLE employees (
Person_ID int PRIMARY KEY,
Designation varchar(50),
FOREIGN KEY (Person_ID) REFERENCES persons(Person_ID));
As for the parent class,
CREATE TABLE persons (
Person_ID int NOT NULL AUTO_INCREMENT,
Last_Name varchar(255),
Middle_Name varchar(255),
First_Name varchar(255),
PRIMARY KEY(Person_ID));
Let's say I want to create another table works whose FK references Person_ID from the subclass employees, not the parent class persons.
CREATE TABLE works (
project_ID PRIMARY KEY,
date_started date,
FOREIGN KEY (Person_ID) REFERENCES employees(Person_ID));
Thanks!
Yes, that's technically possible (I guess you tested that already) and is logically also OK in such a case as yours. In fact referencing persons would be wrong if, logically, only employees can take part in the "works on" relation -- the FK constraint wouldn't ensure that they're only employees.
It is no Problem, but you have always check if the id exist.
Ring connection can cause problems.
CREATE TABLE persons (
Person_ID int AUTO_INCREMENT,
Last_Name varchar(255),
Middle_Name varchar(255),
First_Name varchar(255),
PRIMARY KEY(Person_ID));
✓
CREATE TABLE employees (
Person_ID int PRIMARY KEY,
Designation varchar(50),
foreign key (Person_ID) REFERENCES persons(Person_ID));
✓
CREATE TABLE works (
project_ID Int PRIMARY KEY,
date_started date,
Person_ID int,
FOREIGN KEY (Person_ID) REFERENCES employees(Person_ID));
INSERT INTo persons VALUES (NULL,'A','B','C')
INSERT INTO employees VALUES (1,'test')
INSERT INTO works VALUES (1,NOW(),1)
db<>fiddle here

Foreign Key Constraint Incorrectly Formed

I'm having an issue in which I can't create some tables because their foreign keys are "incorrectly formed." I don't know why I'm getting this error because the keys are of the same type and have unique names. The code is pretty straightforward:
CREATE TABLE Vehicle(
vin VARCHAR(25),
ID VARCHAR(20),
make VARCHAR(20),
model VARCHAR(20),
year_ VARCHAR(20),
condition_ VARCHAR(20),
PRIMARY KEY(vin, ID),
FOREIGN KEY(ID) REFERENCES Listing(CarID)
);
CREATE TABLE Listing(
CarID VARCHAR(20),
state_ VARCHAR(20),
price INT(10),
url VARCHAR(50),
PRIMARY KEY(CarID),
FOREIGN KEY(CarID) REFERENCES Vehicle(ID)
);
If the primary key of Vehicle is (vin, ID) then a foreign key that references it must also have two columns, in the same order, with the same data types.
But in your case, your Listing table doesn't have a vin column, so it can't reference the primary key of Vehicle.
What would it mean for Listing to reference part of the primary key of Vehicle? There is no guarantee that only one row exists with a given value of ID in Vehicle. It could have multiple rows with the same ID and different vin values. So a Listing could potentially be the child of multiple vehicles, which probably doesn't make sense.
So you must either:
Add a vin column to Listing, so its foreign key can reference exactly one row by its primary key (both columns).
Modify the Vehicle table to make ID alone be its primary key.
Update:
I just noticed that you appear to have foreign keys in both tables. That's not usually needed. As I think about what you are trying to model, I would guess that a Listing has one or more Vehicles, right? So the Vehicle should reference its parent Listing. But a Listing does not need to reference a Vehicle.
So the following works:
First, create the parent table, because you can't make a foreign key until the parent table exists. In your case, the Listing is the parent table.
CREATE TABLE Listing(
CarID VARCHAR(20),
state_ VARCHAR(20),
price INT(10),
url VARCHAR(50),
PRIMARY KEY(CarID)
);
Then create the child table, with a foreign key that references its parent.
CREATE TABLE Vehicle(
vin VARCHAR(25),
ID VARCHAR(20),
make VARCHAR(20),
model VARCHAR(20),
year_ VARCHAR(20),
condition_ VARCHAR(20),
PRIMARY KEY(vin, ID),
FOREIGN KEY(ID) REFERENCES Listing(CarID)
);
I tested on MySQL 5.7.27.
This is the correct way:
CREATE TABLE Vehicle(
vin VARCHAR(25),
ID VARCHAR(20),
make VARCHAR(20),
model VARCHAR(20),
year_ VARCHAR(20),
condition_ VARCHAR(20),
PRIMARY KEY(vin, ID)
);
CREATE TABLE Listing(
CarVin VARCHAR(25),
CarID VARCHAR(20),
state_ VARCHAR(20),
price INT(10),
url VARCHAR(50),
PRIMARY KEY(CarVin, CarID),
FOREIGN KEY(CarVin, CarID) REFERENCES Vehicle(vin, ID)
);
In your data model there are a listing and vehicles.
A vehicle can be in the Listing (or not). The Listing have n vehicles (so you have a 1 to n relation).
Each row in Listing have a reference to a vehicle, so it need the vehicle primary key fields (or some unique fields) to reference to it (The vehicle primary key is compound by "vin" and "ID" fields).
So the primary key in Listing should be compound by "vin" and "ID" too, like in Vehicle's table. It's a good practice to use integer autoincrement field as primary key for each table.
You need to add in table Listing "CarVin" field and then the foreign key in Listing will be FOREIGN KEY(CarVin, CarID) REFERENCES Vehicle(vin, ID).
The foreign key will check, when you insert a Listing row, that the vehicle with the values CarVin and CarID exist.
To add a foreign key in table Vehicle too, you should disable foreign key check (SET FOREIGN_KEY_CHECKS=0;) until the tables will be created, because table Listing doesn't exist yet (if you create first table Vehicle). But I think it doesn't have sense in this case, at least you want ensure that all Vehicles are in Listing table.
To insert data you have to insert first a vehicle, and then add it to Listing table (foreign key is check, at least you disable foreign key check until the end), otherwise the foreign key check will fail.
In #"Bill Karwin"'s model you need first insert the Listing row and then the Vehicle.
MySql foreign key constraint documentation, each storage engine in MySql implements foreign key constraint in different way.
Both tables with foreign key constraint to each other:
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE Vehicle(
vin VARCHAR(25),
ID VARCHAR(20),
make VARCHAR(20),
model VARCHAR(20),
year_ VARCHAR(20),
condition_ VARCHAR(20),
PRIMARY KEY(vin, ID),
FOREIGN KEY(vin, ID) REFERENCES Listing(CarVin, CarID)
);
CREATE TABLE Listing(
CarVin VARCHAR(25),
CarID VARCHAR(20),
state_ VARCHAR(20),
price INT(10),
url VARCHAR(50),
PRIMARY KEY(CarVin, CarID),
FOREIGN KEY(CarVin, CarID) REFERENCES Vehicle(vin, ID)
);
SET FOREIGN_KEY_CHECKS = 1;

Can we use constraint name of a primary key as foreign key reference?

For example, I'm creating two tables as shown below:
create table A (
department_id int,
college_id int,
constraint Pk_name primary key(department_id,college_id)
);
create table B (
student_name varchar(75),
department_id int,
college_id int,
foreign key(department_id,college_id) references A(Pk_name)
);
Can I write like this?
I don't think so because there's no way that the RDBMS could know whether PK_name is a column or a constraint name so I suggest if you stick with the usual :
create table A (
department_id int,
college_id int,
constraint Pk_name primary key(department_id,college_id)
);
create table B (
student_name varchar(75),
department_id int,
college_id int,
foreign key(department_id,college_id) references A(department_id,college_id)
);
I will update the answer once I find an other answer .

SQL many to many relationship table

I'm trying to make a many-to-many relationship between these two tables.
CREATE TABLE series (
title VARCHAR(30),
language VARCHAR(30),
year INT,
PRIMARY KEY (title)
);
CREATE TABLE actors (
name VARCHAR(30),
age INT,
country VARCHAR(30),
serie VARCHAR(30),
PRIMARY KEY (name , age , country , serie),
FOREIGN KEY (serie)
REFERENCES series (title)
);
I tried to create a separate table to form a many-to-many relation. Does this look correct?
CREATE TABLE series_actors_combined (
title VARCHAR(30),
name VARCHAR(30),
age INT,
country VARCHAR(30),
serie VARCHAR(30),
FOREIGN KEY (title)
REFERENCES series (title),
FOREIGN KEY (name)
REFERENCES actors (name),
FOREIGN KEY (age)
REFERENCES actors (age),
FOREIGN KEY (country)
REFERENCES actors (country),
FOREIGN KEY (serie)
REFERENCES actors (serie)
);
Your tables do not look right.
As a starter, you have a foreign key in the actors table that references the series, which basically defeats the purpose of the bridge table.
Also, the foreign keys from the bridge table to actors are not well-formed: you have one key per column, while you should have a unique, multi-column key to reference the actor. I would recomend having auto incremented primary keys rather than using these combinations of columns. This gives more flexibility to your design (in real life, two different series might have the same title), and makes it much easier to create foreign keys in the bridge table.
Consider:
create table series(
id int primary key auto_increment,
title varchar(30) unique,
language varchar(30),
year int
);
create table actors(
id int primary key auto_increment,
name varchar(30),
dob date, -- better than age
country varchar(30)
);
create table series_actors(
series_id int references series(id),
actor_id int references actors(id),
primary key (series_id, actor_id)
)

MySQL FOREIGN KEY assistance

I'm working on a database assignment and have run into this error.
The database should look like...
Legend: **Primary Key** *Foreign Key
.
Movies (**title, year**, length, genre, *studioName, *producerID)
StarsIn(***movieTitle, *movieYear, *starName**)
MovieStar(**name**, birthdate, address, gender)
MovieMaker(**ID**, name, address)
Studio (**name**, address, *presidentID)
And my code looks like this...
CREATE TABLE Movies (
title varchar(50),
year int,
length int,
genre varchar(50),
studioName varchar(50),
producerID varchar(50),
PRIMARY KEY (title,year)
FOREIGN KEY (studioName) REFERENCES Studio(name),
FOREIGN KEY (producerID) REFERENCES MovieMaker(ID),
);
CREATE TABLE StarsIn (
movieTitle varchar(50),
movieYear int,
starName varchar(50),
PRIMARY KEY (movieTitle,movieYear,starName),
FOREIGN KEY (movieTitle) REFERENCES Movies(title),
FOREIGN KEY (movieYear) REFERENCES Movies(year),
FOREIGN KEY (starName) REFERENCES MovieStar(name)
);
CREATE TABLE MovieStar (
name varchar(50),
birthdate int,
address varchar(50),
gender varchar(50),
PRIMARY KEY (name)
);
CREATE TABLE MovieMaker (
ID varchar(50),
name varchar(50),
address varchar(50),
PRIMARY KEY (ID)
);
CREATE TABLE Studio (
name varchar(50),
address varchar(50),
presidentID varchar(50),
PRIMARY KEY (name),
FOREIGN KEY (presidentID) REFERENCES MovieMaker(ID)
);
However, I get quite a few errors stating that the syntax for my foreign keys are off. Any chance someone could lend a helping hand?
Tables referencing other tables via foreign keys may only be defined after the referenced tables already exist. You must therefore reorder your tables so that those which are referenced in FOREIGN KEY constraints get created first.
Additionally, the foreign keys referencing Movies.year and Movies.title are going to fail because you do not have indices defined on those columns individually. You do have them as a composite PRIMARY KEY, but they need their own indices.
/* MovieStar, MovieMaker are referenced by other tables
but have no FKs of their own, so create them first */
CREATE TABLE MovieStar (
name varchar(50),
birthdate int,
address varchar(50),
gender varchar(50),
PRIMARY KEY (name)
);
CREATE TABLE MovieMaker (
ID varchar(50),
name varchar(50),
address varchar(50),
PRIMARY KEY (ID)
);
/* Studio can be created next, referencing only MovieMaker */
CREATE TABLE Studio (
name varchar(50),
address varchar(50),
presidentID varchar(50),
PRIMARY KEY (name),
FOREIGN KEY (presidentID) REFERENCES MovieMaker(ID)
);
/* Movies references 2 of the above */
CREATE TABLE Movies (
title varchar(50),
year int,
length int,
genre varchar(50),
studioName varchar(50),
producerID varchar(50),
/* A comma was missing here... */
PRIMARY KEY (title,year),
FOREIGN KEY (studioName) REFERENCES Studio(name),
FOREIGN KEY (producerID) REFERENCES MovieMaker(ID),
/* Add individual indices on Movies. Omitting this would result in errno 150 */
INDEX (year),
INDEX (title)
);
CREATE TABLE StarsIn (
movieTitle varchar(50),
movieYear int,
starName varchar(50),
PRIMARY KEY (movieTitle,movieYear,starName),
FOREIGN KEY (movieTitle) REFERENCES Movies(title),
FOREIGN KEY (movieYear) REFERENCES Movies(year),
FOREIGN KEY (starName) REFERENCES MovieStar(name)
);
Here is a demo of the whole thing building properly: http://sqlfiddle.com/#!2/eaf70c