Tables basics: One-to-one, many-to-many, one to many - mysql

I want my tables to have different relations between each other, this is my first post and I'm a total dummy.
Each dragon can have multiple eggs, but each egg can have only one owner.
Each egg can have only one adornment(embellishment?) and vice-versa. There cannot be an adornment without an egg.
Dragon can originate from multiple lands, and lands can have multiple dragons, but they can't repeat.
So these are my tables:
CREATE TABLE dragons (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(256),
colour VARCHAR(256),
wingspan_in_centimeters INT,
lands_id INT,
eggs_id INT,
FOREIGN KEY (lands_id) REFERENCES lands (id),
FOREIGN KEY (eggs_id) REFERENCES eggs (id)
);
CREATE TABLE eggs (
id INT AUTO_INCREMENT PRIMARY KEY,
weight_in_grams INT,
diameter_in_centimeters INT,
dragon_id INT,
adornment_id INT,
FOREIGN KEY (dragon_id) REFERENCES dragons (id),
FOREIGN KEY (adornment_id) REFERENCES eggs_adornments (id)
);
CREATE TABLE eggs_adornments (
id INT AUTO_INCREMENT PRIMARY KEY,
colour VARCHAR(256),
pattern VARCHAR(256)
);
CREATE TABLE lands (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(256),
dragons_id INT,
FOREIGN KEY (dragons_id) REFERENCES dragons (id)
);
How do I do it?
I'm not sure how foreign keys and references work.

Related

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;

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)
)

Database Design: linking 2 tables with foreign keys in both

I am designing a small database and am having trouble with 2 tables. I have a team and registeredAccount table. A registered account can have 0 or 1 teams. A team has a team manager, which is a registered account.
I am struggling to link the registeredAccountId into the team table. An sql error occurs saying that it cannot add the foreign key in the team table.
If anyone has any suggestions on how to design this better, that would be great.
Here are my tables:
CREATE TABLE team(
teamId INT PRIMARY KEY,
teamName VARCHAR(20),
teamManagerId INT,
CONSTRAINT team_fk_registeredAccount
FOREIGN KEY (teamManagerId)
REFERENCES registeredAccount(registeredAccountId)
);
CREATE TABLE registeredAccount(
registeredAccountId INT PRIMARY KEY,
displayName VARCHAR(20),
subscribed BOOLEAN,
teamId INT,
CONSTRAINT registeredAccount_fk_team
FOREIGN KEY (teamId)
REFERENCES team(teamId)
);
There is no need to set foreign key on registered account since it can be null and is independent of team
A team has a team manager. that is where you set the relationship.
CREATE TABLE team(
teamId INT PRIMARY KEY,
teamName VARCHAR(20),
teamManagerId INT,
CONSTRAINT team_fk_registeredAccount
FOREIGN KEY (teamManagerId)
REFERENCES registeredAccount(registeredAccountId)
);
CREATE TABLE registeredAccount(
registeredAccountId INT PRIMARY KEY,
displayName VARCHAR(20),
subscribed BOOLEAN,
teamId INT,
CONSTRAINT registeredAccount_fk_team
FOREIGN KEY (teamId)
REFERENCES team(teamId)
);

Why can't I add a foreign key constraint on this?

CREATE TABLE usertypes (
userType INTEGER,
userName VARCHAR(12),
PRIMARY KEY(userType)
);
CREATE TABLE Users (
loginid CHAR(9),
name VARCHAR(15),
netid VARCHAR(15) NOT NULL,
password VARCHAR(15) NOT NULL,
userType INTEGER,
PRIMARY KEY (loginid),
UNIQUE (netid),
FOREIGN KEY (userType) REFERENCES usertypes(userType)
ON DELETE NO ACTION
);
CREATE TABLE Courses (
majorid CHAR(3),
cid CHAR (3),
secNum CHAR(2),
year CHAR(4),
semesterid CHAR(2),
profID CHAR(9),
PRIMARY KEY (majorid,cid,secNum,year,semesterid),
FOREIGN KEY (majorid) REFERENCES Majors (majorid),
FOREIGN KEY (profID) REFERENCES Users(loginid)
);
create table transcript(
cid char(3),
grade char(2),
primary key(cid, grade),
foreign key(cid) references courses(cid)
);
I can't add a foreign key cid in transcript. The foreign key for majorid in courses works fine but the one in transcript doesn't work.
Here's the error
Error Code: 1215. Cannot add foreign key constraint
Course.cid is not a key, so transcript cannot create a foreign key. Try the following:
CREATE TABLE Courses (
majorid CHAR(3),
cid CHAR (3),
secNum CHAR(2),
year CHAR(4),
semesterid CHAR(2),
profID CHAR(9),
PRIMARY KEY (majorid,cid,secNum,year,semesterid),
KEY (cid)
);
Short version is I don't think you can have a foreign key to something that isn't identified as a primary key or something with a unique constraint, see Foreign Key to non-primary key
I'm not sure how you are using the cid in the Courses table, if it is perhaps 110 and there is a Math 110 and a Physics 110. This has the problem of if someone has 110 on their transcript, does it reference Math or Physics?
If cid is a primary key, a unique value for each class, it should be a primary key all by itself. If you are in the situation of 110 for math and physics, you might be best served by adding a primary key that is unique for every row, such as an identity, auto incrementing key.

Syntax error User_id not found in table help !

Sql wont let me create these table because of a syntax error can someone help me.
drop table users;
drop table intrest;
drop table friendships;
create table users(
id INT,
Fname char(15),
Lname char(15),
email char(20),
street char(15),
state char(2),
zip INT,
age INT,
gender char (2),
phone INT,
User_password char(15),
primary key (id),
foreign key (intrest_id) references intrest(id)
);
create table Intrests(
id INT,
description char(30),
Primary key (id),
foreign key (users_id) references users(id)
);
create table User_intrest(
foreign key (users_id) references users(id),
foreign key (intrest_id) references intrest(id)
);
create table friendships(
User_1_id INT,
User_2_id INT,
description Char(20),
foreign key (users_id) references users(id)
);
create table Intrests( id INT, description char(30),
Primary key (id),
foreign key (users_id) references users(id) );
create table User_intrest( foreign key (users_id) references users(id),
foreign key (intrest_id) references intrest(id) );
For interests table, where is the column users_id defined?
Column definitions for user_interest table?
You have a cyclical FK relationship:
Users has Interests(id) as a FK, and Interests has user(id) as a FK.
You don't need EITHER of these since you have a user_intrest table to link them!
You also have several typos with table names, like intrests and intrest.
Also, you should make both your User fields in Friendships be FK to Users, I'm not sure why you want a third, unrelated Users_Id field.
The first (of many) syntax errors you have is in
create table users(
...
primary key (id),
foreign key (intrest_id) references intrest(id) <--- there is no table intrest
);
I would suggest:
But STOP! Don't just copy-paste. Try yourself to see why MySQL gives you that error message: Key column 'intrest_id' doesn't exist in table, isn't the error you get?
Try to first fix that error. What do you have to do? Add an intrest_id field in table users, not just declare it as FOREIGN KEY. (It's not a useful field to have in the end, but do it anyway).
Then rerun your query and try to fix next error. One by one. If you realy get stuck somewhere, well, you know a site to ask questions :)
So, try to fix errors one by one, until you have a script that is running without any errors at all. You'll have learned much more than simply copying and pasting any answer.
CREATE TABLE Users(
id INT,
Fname char(15),
Lname char(15),
email char(50), <-- 20 is too small for emails
street char(15),
state char(2),
zip INT,
age INT,
gender char (2),
phone char(20), <-- phone should be char, not INT
user_password char(15),
PRIMARY KEY (id)
); <-- You don't really need a foreign key to Interests,
<-- that's why you have the User_interest "middle" table
CREATE TABLE Interests(
id INT,
description char(30),
PRIMARY KEY (id)
); <-- You don't really need a foreign key to Users,
<-- for the same reasons.
CREATE TABLE User_interest(
user_id INT, <-- These foreign keys are
interest_id INT, <-- good, but you need to
<-- declare them as fields, too
PRIMARY KEY (user_id, interest_id), <-- It's good if all tables have PK
FOREIGN KEY (user_id) REFERENCES Users(id),
FOREIGN KEY (interest_id) REFERENCES Interests(id)
);
CREATE TABLE Friendships(
user_1_id INT,
user_2_id INT,
description char(20),
PRIMARY KEY (user_1_id, user_2_id),
FOREIGN KEY (user_1_id) REFERENCES Users(id),
FOREIGN KEY (user_2_id) REFERENCES Users(id)
);