MySQL how to link tables - mysql

I am trying to create a to do web app using mysql. Can someone explain how I can select the todos specific for one user? How do I link the users table with the todos table? General advice would be preffered, not actual code.

It is called a foreign key relation. It goes like this
users table
-----------
id (auto increment primary key)
name
address
...
todos table
-----------
id (auto increment primary key)
user_id (id from users table - this is the foreign key and relation to the user)
todo_text
...
If you want to select the todos of a user later then you can use a join:
select todos.*
from todos
inner join users on users.id = todos.user_id
where users.name = 'john'

You would link them by id's
So if you have two tables (UserTable) and (ToDoTable) you would get the todos with a select like this.
Select * from ToDoTable where ToDoTable.user_id = 1;
That query is essentially saying give me everything from the todotable where the user is bob (since bob has a primary key id of 1)
The user table will have users like :
Name | id
Bob 1
John 2
and the TodoTable will have
Task | user_id
Clean dishes 2
Take out Trash 1
That way we link the tasks to the user table by the user_id
The User table will have a primary key (id)
and it is referenced on the todo table as a foreign key

Related

How to do a "DELETE" relational database with another table in MySQL

I want to have a relational data between two table with DELETE query.
I don't know what keyword should I search and such confusing for me to learn relational database.
So in this case, I want to delete one of the user data in the user table.
So the buy_product table which contains the user_id column will also be deleted along with the rows in it.
This is user table:
user_id
name
1
John
2
Doe
This is buy_product table:
id_product
name
user_id
1
Cookies
2
2
Pizza
2
3
Burger
1
For example, if I run the DELETE FROM user WHERE user_id = 2 query, the result is:
user_id
name
1
John
And buy_product table with user_id = 2 also deleted the data that I want without run DELETE FROM buy_product WHERE user_id = 2 query like this:
id_product
name
user_id
3
Burger
1
I think for all understandable answers means a lot to me. Thanks!
If you defined a foreign key constraint with ON DELETE CASCADE between buy_product and user then deleting a row from the parent table user will automatically delete the related rows in the child table buy_product.
For example, buy_product could be created as:
create table buy_product (
id_product int,
name varchar(50),
user_id int references user (user_id) on delete cascade
);
Ideally you should configure cascading deletion such that when a record is deleted from the user table all dependent records are also deleted from the buy_product table. In lieu of that, we can try doing a delete join here:
DELETE u, bp
FROM user u
INNER JOIN buy_product bp
ON bp.user_id = u.user_id
WHERE u.user_id = 2;

Merging rows and updating related foreign key

I have a current users table. A distinct user is defined as when the email and phoneNumber together are unique. Currently the table looks like this:
And another table called giftee_info which has the foreign key on column userId to users.id:
The users table is going to be parsed out into 2 tables: users and user_metadata. Now a distinct user will be defined by the phoneNumber. So you can see in the data above, users with id's 4 and 5 are the same, and have to be merged.
The new users table will look like:
And the new user_metadata table will look like this:
Note how the 4th row has userId of 4, so users 4 and 5 have merged to one user.
And giftee_info will look like this:
See how the 3rd row in giftee_info contains userId 4, as the user with id 5 has been merged into one user.
The data I've provided is basic. In reality there are many rows, and a user with the same number may have 5 different email address (and so are currently treated as separate users in the current schema).
The part I'm having most trouble with is updating giftee_info. So any rows with userId's that have been merged down into one user need to be updated. How can I do this?
Since phonenumber can be NULL, I'm using externalid as the unique identifier below.
Start by creating the new users table from the distinct phone numbers in the old users table:
CREATE TABLE new_users (id INT PRIMARY KEY AUTO_INCREMENT, externalid VARCHAR(32), phonenumber VARCHAR(32))
SELECT DISTINCT NULL, externalid, phonenumber
FROM users
Then put all the emails into the user_metadata table, by joining the old and new users tables to get the emails along with the new user IDs.
CREATE TABLE user_metadata (id INT PRIMARY KEY AUTO_INCREMENT, userid INT, email VARCHAR(100), subscribe INT(1))
SELECT NULL, nu.id, u.email, 0
FROM new_users as nu
JOIN users AS u ON nu.externalid = u.externalid
Now you can update giftee_info by replacing the old user IDs with the new user IDs.
UPDATE giftee_info AS g
JOIN users as u ON g.userid = u.userid
JOIN new_users As nu ON nu.externalid = u.externalid
SET g.userid = nu.userid
Once this is all done you can rename the tables so new_users is now users.

Is there a way to check whether a new row in a table agrees with entries in other tables? [SQL]

I am using MySQL Workbench CE for a college assignment. I have 4 tables: Applicants, Universities, Job, Interview. Interview has foreign keys in the other 3 tables: appID (applicant ID), uniID (university ID) and jobID (job ID). Additionally, the job table has a uni column, which is a foreign key to universities.id. Essentially, each job has a job number and a university associated with it. Each interview has an applicant, a job and a university, in addition to some other information.
I am trying to figure out how to check whether the job offering (job number + its associated university) entered into the interview table actually exists in the job table.
For example, if the only row in job is:
ID | JobID | UniID | ..
1 1 1 .
Then the interview table shouldn't accept something like:
ID | AppID | JobID | UniID | ...
x x 1 2 .
as there is no job with JobID = 1 and UniID = 2.
SELECT * FROM job as J LEFT JOIN interview as I ON J.uni = I.uniid WHERE J.id = I.jobid is a check I came up with for this issue, however, I'm not sure whether I should attempt to use it in a trigger or as part of an assertion.
You are looking for a foreign key relationship.
If the jobs table does not already have a primary/unique key on the two columns, then define one:
alter table jobs add constraint unq_jobs_jobid_uniid on job(jobID, uniID);
Then, you can add a foreign key to interviews:
alter table interviews add constraint fk_interviews_jobid_uniID
foreign key (jobID, uniID) references job(jobID, uniID);
Note that this works even if jobID is already the primary key in jobs.

MySQL - How to change the primary key while importing the data from one database to another database?

Basically, I have two table users and user_details. Users table is as follows.
id name
1 A
2 B
and user details table is as follows
id user_id division branch
1 1 D1 B1
2 1 D2 B2
User_details table have user_id as the foreign key.
I need to import data from these two table into another database having similar two tables.
The problem is tables in db2 might already have entries with similar primary keys of user table. i.e. same user_id's.
Is there any way , I can change primary keys while maintaining the foreign key relation with user details table.
e.g. If db2 has user ids till 100, user id from db 1 should become 101 and this should also change the corresponding user id in user details table to 101 and so on.

Limit many to many relationship by number in Sql

Three tables: users, roles and a pivot table (many to many) role_user.
user:
- id
- name
role:
- id
- name
role_user
- id
- user_id: foreign key link to user
- role_id: foreign key link to role
If I wanted to limit the amounts of maximum roles a user can have to only 1 for example, I could put the role_id foreign link on the user as a role_1 field instead of using a pivot table of many to many.
users:
- id
- name
- role_id_1
The same goes if I wanted only two roles per user.
users:
- id
- name
- role_id_1
- role_id_2
What if I wanted to limit the amount to 1, 2 or something else using a pivot table (Not using foreign role links on the user table) ? Is there an option for that in sql ?
Something like a composite unique index option including role_id and user_id in the pivot table, but instead of a constraint on the uniqueness, a custom constraint on the limit of the user_id number of appearances.
There is a way you can implement this in SQL without triggers. It is a bit complicated, but you could do it.
It starts by adding another table. Let me call it RoleNumbers. This table would consist of one row for each possible role for a user. So, you set it up with 1, 2, or however many roles you want.
Then for the junction table:
create table UserRoles (
UserRoleId int not null auto_increment primary key,
UserId int not null references users(user_id),
RoleId int not null references roles(role_id),
RoleNumber int not null references RoleNumbers(Number),
unique (UserId, RoleId),
unique (UserId, RoleNumber)
);
This uses my naming conventions. I have no problem with having a synthetic key on a junction table.
When you insert a new record, you would have to assign a value to RoleNumber that is not already being used. Hence, you get the limit. The most efficient way to do this is via triggers, but that is not strictly necessary. You could do an insert as:
insert into UserRoles(UserId, RoleId, RoleNumber)
select $UserId, $RoleId, coalesce(max(RoleNumber), 0) + 1
from UserRoles
where UserId = $UserId;
delete would require a separate query for maintaining the numbering scheme.