Is it possible to create a new column in a SQL query results? I'm thinking of expanding my movie database to handle multiple users. I have a table with the basic movie details such as title type plot rating year released and have a table with a list of movie Ids and user ids for the movies that a user has marked as watched. I would like to generate a list for a user and to show if it has been watched or not by said user.
Ex
The matrix watched
The matrix 2
Or
The matrix 2 un-watched
Or would it be a better idea to create a table that has a list of movie ids nada user idea and a status column?
So, you have users and movies. A user could've watched many movies. A single movie could've been watched by many users. This means it's a many-to-many relationship.
That's a standard problem. The solution:
movies table - movie id, title, type etc. - you got that already
users_to_movies - user id, movie id, status (or e.g. date watched, NULL if not watched), any other data if need be
users - user id, name, last name, e-mail - whatever you need there.
The primary key in users_to_movies is a compound key, consisting of two columns: (user_id, movie_id).
The table users_to_movies is an association table. This is the "bridge" between two tables that are in a many-to-many relationship.
Example:
User with id 5 watched Matrix 2 (id 12 in movies table) on 4th Sep 6pm. So you INSERT INTO users_to_movies VALUES(5, 12, '2014-04-09'). If you want to store the information that user id 2 hasn't watched Matrix 2, you insert (2, 12, NULL).
You should add a new table
This is a Many-to-Many table relationship
this table should contain userID and movieID
I think you dont need a status column (if watched, there is a line / if not, there is nothing)
Related
Consider this case,
a user can have many groups,
groups can have many users
only people belonging to a particular group can have access to a car belonging to that group
So i am not sure how the tables will look like
below are the tables
-- Creating a new User
INSERT INTO Users (UserLogin, UserPassword, UserName)
VALUES ('SomeUser', 'SecretPassword', 'UserName');
-- Creating a new Groups
INSERT INTO Groups (GroupName, GroupDescription)
VALUES ('GroupName', 'GroupDescription');
-- Finally, updating the junction
INSERT INTO UserGroup (UserId, GroupId)
VALUES ('UserId', 'GroupId');
consider another table cars
INSERT INTO Cars (Name, Model)
VALUES ('SomeCar', 'Model');
only those people who belong to a group can have access to the carsS
So should cars have many to many relationships with UserGroups?
INSERT INTO CarUserGroup (UserGroupId, CarId)
VALUES ('UserGroupId', 'CarId');
OR Should group have a one-to-many relationship with cars?
INSERT INTO Cars (Name, Model, GroupId)
VALUES ('GroupId','SomeCar', 'Model');
can u tell which approach is the best?
thanks
If a given car can have only a single group relationship, then your second version in theory would work:
Cars (Name, Model, GroupId)
However, this approach becomes undesirable as soon as a car can be associated with more than one group. The reason is that then we would be duplicating the car's metadata:
SomeCar, SomeModel, Group1
SomeCar, SomeModel, Group2
In general, you would do better to go with the standard junction table approach, and have a table which keeps tracks only of the relationships between cars and groups:
SomeCar, Group1
SomeCar, Group2
Then, let the Cars table exist to store the metadata for each car, with one car occupying only a single record:
SomeCar, SomeModel, SomeOtherMetadata
Since,
only people belonging to a particular group can have access to a car belonging to that group
So you should create a One-to-Many relationship between groups and cars. Now, why this should be done? The intuition behind this is that a user can have a car only if it belongs to a particular group, so the dependency of cars is on group. But since the car is a composite attribute of the group table, you make its owm table with a one-to-many relationship.
Another point is, when you delete a group, all cars associated with this group should also be deleted ( this is optional, you can also have null foreign key, in which case it will be an orphan child if you dont want to delete these entries from cars table ).
I have mobile app with users. Everything is simple - each user have id and name.
Users Table
id name
1 John
2 Dave
3 Jack
Some of this users are friends and the main purpose of my question - finding the best way to rebuild friendship table that looks like (the only rule is user_id_1 < user_id_2)
Friendship table
id user_1_id user_2_id
1 1 2
2 1 3
3 2 3
How I know that users are friends? I take this information from different sources (social network A, social network B). So if two users are friends at least in one of two social networks - they are friends in my app.
Right now I am recreating friendship table each day:
Take each user, create empty array NewFriends for this user
Erase all records containing his id from friendship table
Find all his friends in network A (A-friends)
For each of A-friends - find they ids in my app and add them to NewFriends array
Find all his friends in network B (B-friends)
For each of B-friends - find they ids in my app and add them to NewFriends array if they don't already exist there
Delete all friendship records from Friendship table that are not mentioned in NewFriends array
Insert all friendship records from NewFriends array to Friendship table that were not existed there before
How can I solve this task better?
First,
you can use the only one table of the 2 networks (instead of using A-friends table and B-friends table)
and when select you could use distinct keyword
steps will be :
Take each user
Erase all records containing his id from friendship table
Find all his friends in network A and add it to (Temp-friends)
Find all his friends in network B and add it to (Temp-friends)
For each distinct of Temp-friends - add records in NewFriends table
Delete all friendship records from Friendship table that are not mentioned in NewFriends array
Insert all friendship records from NewFriends array to Friendship table that were not existed there before
You can use set data type instead array. The reason to use set is set doesn't contain duplicate values.
Use two sets oldFriendships and newFriendships.
From friendships table load data to oldFriendships
Create new newFriendships
2.1. From network A find all friends for the user and add it to the newFriendships
2.2. From network B find all friends for the user and add it to the newFrindships
Update friendship table
3.1 Find oldFriendships complement newFrindships - this is removed friendships, delete these values from friendship table
3.2. Find newFrindships complement oldFriendships - this is added friendships, add these values to friendship table
Here is wikipeda article about complement
I'm totally new to MySQL.
I'm working on a university courses system where each course ("event") has many students("users") that are signed in to that course.
I want a to build a MySQL table that for each course ID will store all the students IDs that are signed in to it. I found two approaches:
Serialize students IDs (using json for example)
Create a new row for every new student with course ID and student ID
The first approach has a performance issue because of serialization/de-serialization of students IDs, and the second approach will cause the table to explode very quickly.
What do you think I should do? Is there a better solution?
Thanks!
Your case is a Many-to-Many mapping.
You would have 3 tables.
User
Events
User_Events
The third table will store the mappings, it should consist of two columns, user_id and event_id
user_id would be the foreign key for the User table, similarly, event_id would be the foreign key for the Event table. You can then retrieve data by Joins in queries.
so if you have users with ID 1, 2, and 3
and similarly courses with ID 1, 2, 3, 4
Here's how you will represent students that are signed in a course.
user_id, event_id
1 2
1 3
2 1
3 4
This means, user 1 is signed in course 2 and 3, user 2 in course 1 and user with ID 3 in course with ID 4.
Each student/user can be in several courses/events.
Each course/event can contain several students/users.
So you need a bridge table containing all relations:
user_event (userid, eventid)
with a unique constraint on userid + eventid.
(You can add a technical ID (e.g. user_event_id) to the table, but that's not necessary.)
I'm very new to Databases and looking forward to develop an application with some advanced functionality.
Here I'm going to have a table with users just like the following one.
So, in the sports column, value will be the sports the user plays. They will be some ids from the records of sports table.
So my problem is how to store those multiple values in the same row same column ?
Thanks
PS: Please note that I'm a beginner...
The proper way to do this would be to maintain three different tables.
User: id, name, age
Sport: id, name
UserSport: user_id, sport_id
The UserSport table references the primary key (id) of both tables (User and Sport) and contains a separate entry for each sport the user participates in.
The primary key of UserSport should then be a composite key of both user_id and sport_id. This allows you to have multiple rows for each user and multiple rows for each sport, but a unique combination of both the user and sport.
I have two tables. "users" and "movies". Users table consists of "id"(Auto increment), "name" and "password" columns. There are 2 usernames stored right now. In movies table there are 'title' and 'year' columns. The PHP script allows each user to watch and add new movies to their list. How do I link or make the parent-child relationship or whatever is needed to make it happen in MySQL? Oh, and I also use Adminer. Right now when I log in one user I still see the same movies that I've added with the other user.
If you are stuck with using just two tables as stated in a comment, you have to redesign the Movies table to include a column UserID which identifies which user created that entry. Then you can filter the data so that a user only sees information about the movies they added to the list.
This isn't a good design — the answer by Jeremy Smyth suggesting an extra table to relate movies to users is much more sensible, but you've indicated that isn't allowed. The reason it isn't a good design is that you're going to end up with lots of rows indicating that the same movie was released in the same year, each row entered by a different user, so there is unnecessary repetition. There's also more chance for error; you'll get entries for 'Gone With The Wind' 1938, and 'Gone With The Wind' 1939, and 'Gone With The Wind' 1940 when there should only be one year (1939, as it happens).
Can you please be more specific about what I have to do ...
In the two-tables-only system, you would create the Movies table like this:
CREATE TABLE Movies
(
Title VARCHAR(32) NOT NULL,
Year INTEGER NOT NULL,
UserID INTEGER NOT NULL REFERENCES Users(ID),
PRIMARY KEY(Title, Year, UserID)
);
When you insert a record into this table, you record the ID of the user who did the insertion, so you can query who created which movie records.
If you are actually going to reference this table from elsewhere in the database, you might well add an ID column here, but if there are more tables, then you'd drop the UserID column from this table and create a relationship table:
CREATE TABLE Movies
(
ID INTEGER AUTOINCREMENT PRIMARY KEY,
Title VARCHAR(32) NOT NULL,
Year INTEGER NOT NULL,
UNIQUE(Title, Year)
);
CREATE TABLE Users_Movies
(
MovieID INTEGER NOT NULL REFERENCES Movies(ID),
UserID INTEGER NOT NULL REFERENCES Users(ID),
PRIMARY KEY(MovieID, UserID)
);
Now you can have one record for 'Gone With The Wind' 1939, which might have ID number 207, and twenty different people might list MovieID 207 as one of their movies with 20 simple records in the Users_Movies table.
You will need to create a "many-to-many" relationship between your two tables.
To do this:
First, create an ID column in the Movies table to uniquely identify each one
Then, create another table called user_movies (or "watched" or something useful), that contains the user ID, the movie ID, and any other information you wish to add such as date watched or rating (number of "stars") etc.
Then, whenever a user watches a movie, add a record to the user_movies table to mark the fact that they've done it.
It should be many-to-many, because each user can watch several movies, but each movie can be watched by several users. A "parent-child" relationship isn't appropriate in this case, being a one-to-many relationship.