Mysql Foreign Key Usage - mysql

I'm trying my first hand at creating a mysql database for a simple blog. I'm having trouble understanding foreign keys and their appropriate relations. If someone can explain in "layman's" terms I'll be very happy.
I have a table called users that has the basics of fields (username, email, password etc) which I've created a user_type field and set it to INT. I've created the corresponding table called user_type and added two fields (one being the type_id = primary key and the other been the type = VARCHAR).
My question is:
Am I correct in understanding that I connect the two tables together by setting the foreign key link from the user_type INT in the users table to reference the type_id from the user_type table?

Your understanding is correct.
From SQL FOREIGN KEY Constraint
A FOREIGN KEY in one table points to a PRIMARY KEY in another table.
So in your example, the user_type id in table user_types would be the primary key, and the user_type int in table users would be the foreign key entry.
This enforces that an entry in table user_types has to exist before it can be used in table users.

You referencing from user to usertype:
n users have one user_type
If you create the table with an sql statement it should include something like this in the user part:
DROP TABLE IF EXISTS `user` ;
CREATE TABLE IF NOT EXISTS `user` (
`ID` INT NOT NULL AUTO_INCREMENT ,
`username` VARCHAR(55) NOT NULL ,
`email` VARCHAR(55) NOT NULL ,
`password` VARCHAR(55) NOT NULL ,
`user_type` INT NOT NULL ,
PRIMARY KEY (`ID`) ,
INDEX `user_to_usertype_idx` (`user_type` ASC) ,
CONSTRAINT `user_to_usertype`
FOREIGN KEY (`user_type` )
REFERENCES `user_type` (`type_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
You have to create user_type before you create user, otherwise you will get a failure.

Related

Proper way to create table friends in single statement

I have table users
CREATE TABLE IF NOT EXISTS users(
id int AUTO_INCREMENT PRIMARY KEY,
user_id INTEGER NOT NULL UNIQUE,
goal VARCHAR(255) DEFAULT NULL,
age INTEGER DEFAULT NULL,
gender VARCHAR(255) DEFAULT NULL,
country VARCHAR(255) DEFAULT NULL,
city VARCHAR(255) DEFAULT NULL,
comment VARCHAR(255) DEFAULT NULL)
I want to create table friends. One key feature that is every user by default friend for itself.
This is my current statement
create table friends (user_id int, friend_id int, FOREIGN KEY (user_id) REFERENCES users (user_id), foreign key (friend_id) references users (user_id)) as select user_id from users;
update friends set shown_id = user_id;
I think it looks pretty kludgy, creating a table and changing it immediately, may be there a better way to implement it?
Another important note: the database loses connection after creating the friends table.
create table friends (user_id int, friend_id int, FOREIGN KEY (user_id) REFERENCES users (user_id), foreign key (friend_id) references users (user_id)) as select user_id from users;
ERROR: 2006: MySQL server has gone away
The global session got disconnected..
Attempting to reconnect to 'mysqlx://root#localhost:33060/test_db'....
The global session was successfully reconnected.
Don't know where shown_id came from, but I guess it's a typo.
Instead of populating only one column (user_id) of your friends table, you can add another user_id column to the select statement with friend_id alias. Immediate update query is not needed.
create table friends (
user_id int,
friend_id int,
foreign key (user_id) references users (user_id),
foreign key (friend_id) references users (user_id)
) as (
select user_id, user_id as friend_id
from users
);
Original answer https://dba.stackexchange.com/a/266893/208647

Key column doesn't exist in table

I'm having trouble adding a foreign key field that references another table.
First I created the users table as so:
CREATE TABLE users (
user_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
userName VARCHAR(256) NOT NULL,
userEmail VARCHAR (256) NOT NULL,
userPwd VARCHAR(256) NOT NULL,
);
then I'd like the quizzes table to have a foreign key that references the user_id from the first table
CREATE TABLE quizzes (
quizId INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
quizName VARCHAR(128) NOT NULL,
quizMax SMALLINT(6) NOT NULL,
FOREIGN KEY (user_id) REFERENCES users (user_id)
);
This is throwing the error: 'Key column 'user_id' doesn't exist in table.
Other answers advised to check that DB is InnoDB, which I did, and it is.
Can't understand why it's telling me that user_id doesn't exist, when it clearly does exist in the users table.
Firstly check if table user is created successfully, due to the additional ',' on last column!
Secondly, the column you reffered in FOREIGN KEY(user_id) is not defined in table quizzes, you need to add this column in quizzes table.
First: You do not need the last comma - , in the first CREATE statement. -
Second: you have to create the columns before you can use them in a foreign key constraint and user_id does not exist in the second table at the moment of constraint creation.
Take a look at the example below. The last create succeeds when user_id column is added before the constraint is created:

How to add foreign key to table in mysql

What I am doing incorrect? Trying to create these tables in sqlfiddle
does not work gives
Cannot add foreign key constraint
create table product (
pid int NOT NULL,
name varchar(10),
PRIMARY KEY (pid)
);
create table trans (
tid int NOT NULL ,
productId int NOT NULL,
userId int NOT NULL,
PRIMARY KEY (tid),
FOREIGN KEY (productId) REFERENCES product(pid),
FOREIGN KEY (userId) REFERENCES user1(uid)
);
create table user1 (
uid int NOT NULL ,
location varchar(22),
PRIMARY KEY (uid)
);
As #BillKarwin mentioned, the definitions for tables containing primary keys referenced by the trans table should appear before the definition for the trans table. So you should move the definition for the trans table to last.
However, even doing this still results in an error in SQLFiddle:
SQLFiddle (uncomment the foreign key reference in trans)
SQLFiddle seems to have some sort of problem with accepting this table schema. This is not surprising, as the site seems to have such problems frequently.
What is order you create tables. You need first to create product and user1 and at the end - trans.

Nesting of groups or elements

I'm fairly new in Mysql, but I have problem that I cannot solve. I will give you an example to demonstrate it. Please note that I know that (for current example) there are other simpler and more efficient ways to solve it... but just take it as an example of the required procedure.
First the data: The data would be the name of a Person.
CREATE TABLE person(
id INT,
name VARCHAR(100)
) TYPE=innodb;
Second: Group Creation... So this is fairly simple... and could easily done using a table 'group' with a foreignkey to person. These groups could be arbitrary, containing any number of persons, duplicated... or not... (that is simple!!)
Third: MY REAL PROBLEM--- I also would like to have Groups that have other Groups as elements (instead of persons). This is where a really get stuck, because I know how to create a groups of persons, a group of groups (having a self-referencing foreign key)... but I don't know how to create a group that MAY HAVE persons AND Groups.
I appreciate any suggestion to solve this issue.
Thank you very much for your comments.
Regards
ACombo
I'd go with firstly setting up the myGroup and person tables.
Secondly, I'd set up a myGroupGroup table with columns myGroupId, parentMyGroupId. This will allow you to relate group rows to child group rows i.e. "this group has these groups within it". If a group has no rows in this table then it has no child groups within it.
Thirdly, I'd set up a personGroup table with columns personId, myGroupId. This will allow you to relate person rows to a given group. If a group has no rows in this table then it has no persons within it.
CREATE TABLE person(
id INT UNSIGNED PRIMARY KEY,
name VARCHAR(100)
) ENGINE=innodb;
CREATE TABLE myGroup(
id INT UNSIGNED PRIMARY KEY,
groupName VARCHAR(100)
) ENGINE=innodb;
-- Holds groups within groups
CREATE TABLE myGroupGroup(
id INT UNSIGNED PRIMARY KEY,
myGroupId INT UNSIGNED,
parentMyGroupId INT UNSIGNED DEFAULT NULL,
CONSTRAINT `fk_myGroupGroup_group1` FOREIGN KEY (`parentMyGroupId`) REFERENCES `myGroup` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_myGroupGroup_group2` FOREIGN KEY (`myGroupId`) REFERENCES `myGroup` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=innodb;
-- Holds persons within a group
CREATE TABLE personGroup(
id INT,
personId int UNSIGNED NOT NULL,
myGroupId int UNSIGNED NOT NULL,
CONSTRAINT `fk_personGroup_group1` FOREIGN KEY (`myGroupId`) REFERENCES `myGroup` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_personGroup_person1` FOREIGN KEY (`personId`) REFERENCES `person` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=innodb;
I've tweaked your SQL a bit:
1) Replaced TYPE with ENGINE
2) Replaced table name group with myGroup (GROUP is a reserved word)
Good luck!
Alternative:
CREATE TABLE Entity
( EntityId INT --- this id could be AUTO_INCREMENT
, PRIMARY KEY (EntityId)
) ENGINE = InnoDB ;
CREATE TABLE Person
( PersonId INT --- but not this id
, PersonName VARCHAR(100)
, PRIMARY KEY (PersonId)
, FOREIGN KEY (PersonId)
REFERENCES Entity(EntityId)
) ENGINE = InnoDB ;
CREATE TABLE Grouping
( GroupingId INT --- and neither this id
, GroupingName VARCHAR(100)
, PRIMARY KEY (GroupingId)
, FOREIGN KEY (GroupingId)
REFERENCES Entity(EntityId)
) ENGINE = InnoDB ;
CREATE TABLE Belongs
( EntityId INT
, GroupingID INT
, PRIMARY KEY (EntityId, GroupingId)
, FOREIGN KEY (EntityId)
REFERENCES Entity(EntityId)
, FOREIGN KEY (GroupingID)
REFERENCES Grouping(GroupingId)
) ENGINE = InnoDB ;

Self relationship in MySQL

I am trying to add a self relation in an existing Innodb table here is table structure
Table person
person_id int (10) primary key not null auto increment,
parent_id int (10) NULL default null,
name varchar(30)
When I use this command
ALTER TABLE `person` ADD FOREIGN KEY ( `parent_id` ) REFERENCES `person` (`person_id`) ON DELETE RESTRICT ON UPDATE RESTRICT ;
I get the error data type mismatch. I think this could be due to null values in parent_id. Is there any way to skip this check?
Thanks
person_id and parent_id need to be the exact same data type. For example, if person_id is INT UNSIGNED and parent_id is INT, then you can't create the foreign key.
Run this command and compare the data types of the two columns:
SHOW CREATE TABLE `person`\G