Database Design: linking 2 tables with foreign keys in both - mysql

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

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

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

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.

Foreign Key Constraint Error - MySQL

I am trying to create a database containing information from a game for an assignment but am having issues when creating the tables with assigning the primary and foreign keys. Any help would be amazing.
The error code I am getting is: #1215 - Cannot add foreign key constraint on table Boss. It creates the first table fine it just stops working and throws the error at the foreign key when creating table boss.
Within the item table the field Boss needs to be able have the same data entered for multiple different items.
CREATE TABLE item ( ID SERIAL, Name VARCHAR(35), Boss VARCHAR(25), Type VARCHAR(20), Slot VARCHAR(20), PRIMARY KEY (Name,Boss) );
CREATE TABLE boss ( ID SERIAL, Boss VARCHAR(25), Type VARCHAR(20), Location VARCHAR(20), Difficulty INT, PRIMARY KEY (ID, Location), FOREIGN KEY (Boss) REFERENCES item(Boss) );
CREATE TABLE dungeon ( ID SERIAL, Name VARCHAR(25), Location VARCHAR(20), Rating INT, PRIMARY KEY (Name), FOREIGN KEY (Location) REFERENCES boss(Location) );
I can see many things wrong with your db creation script, but I will only stick to the ones that immediately affect getting it to work in the first place:
You should always refer to another table through its primary key and nothing else.
Your references are put in the wrong tables. If you want to refer to a "boss" from "item" then you should do just that and not refer to "item" from "boss".
But the most important thing is that references should be of the same type as the primary keys they refer to.
A composite key is a bad idea when you don't really need one.
So, a working script would be:
CREATE TABLE dungeon ( ID BIGINT(20), Name VARCHAR(25), Location VARCHAR(20), Rating INT, PRIMARY KEY (ID) );
CREATE TABLE boss ( ID BIGINT(20), Type VARCHAR(20), LocationId BIGINT(20), Difficulty INT, PRIMARY KEY (ID), FOREIGN KEY (LocationId) REFERENCES dungeon (ID) );
CREATE TABLE item ( ID BIGINT(20), Name VARCHAR(35), BossId BIGINT(20), Type VARCHAR(20), Slot VARCHAR(20), PRIMARY KEY (ID), FOREIGN KEY (BossId) REFERENCES boss (ID) );
You can adjust it to your needs, but before doing that, I would suggest reading a good book on database design or -at least- a tutorial on basic relational databases principles.

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