How to set up rating table SQL - mysql

I'm trying to figure out how to set up a database table that will handle rating of specific users. Every user is one "blog", I would like users to be able to vote other users.
Table users
id(primary) username password email
Table rating
value user_id(foreign key)
The problem is that I can't find out, how to make another user able to rate the other user, and store it in the rating table. I would like it to look something like:
user id 2 voted user id 3 with value 5.

Maybe you should consider changing your tables to something like this:
Table users (id (primary key), username, password, email)
Table rating (rated_by_user (foreign key), rated_user (foreign key), rating)
Both foreign keys would refer to users.id.
then an insert statement like insert into rating values (2, 3, 5); would indicate that user id 2 rated user id 5 with rating value 5.
The rating table should probably have a primary key (rated_by_user, rated_user) too.

Related

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.

Inserting into one table and using the id to insert into other table

I am using MySql, and I want to implement a query.
I have 5 Tables and in MySql they look like this.
Table1- Site:
Site_ID
domain_name
site_name
Table2- Locations:
site_id (Same as from Site)
Table3- Users:
user_id (AI primary key)
site_id
Table4- Users_Roles:
role_id(AI Primary key)
site_id
Table5- Users_Addresss:
user_address_id(AI Primary Key)
user_id (Same as from Users)
site_id
With one single query, I want to insert into all of these tables. My Database is normalized
I am not able to think of the query that would do the operation.
I will be using this query in a php file and trigger it with the ajax.
First you need to insert a record into Site table
INSERT INTO Site (domain_name,site_name) VALUES ('www.google.com', 'Test site');
Then assign the last insert id i.e. Site_id into a variable like below
SET #site_id = LAST_INSERT_ID(); // This is the Site_id
INSERT INTO Users (site_id) VALUES (#site_id);
Now do the same for all the tables.
Thanks

Linking columns in different tables in MySql / parent-child relation

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.

creating a new mysql table with a primary auto incrementing id that is linked to another table?

I want two tables to share a primary auto incrementing id, is this possible? how do i do this? is their anything i need to consider?
the reasons i am doing this, is because it is a better solution than adding groups column to the users table, and also better than creating a completly seperate groups table, because if they share a primary key, i can use the existing posts table for both groups and users. instead of having to create a two distinct posts tables, (group_posts table for group posts. and a user_posts table for user posts.)
existing users table is
id(primary, ai)
username
password
email
my groups table that i want to link to my users table with a shared ai primary key
id(primary, ai, linked to users table id)
group_name
created_by
creation_date
etc.
You should make you schema clearer by doing the following:
Create a table (e.g. people)
id, primary key, auto-increment
type, tells you if it's a user or a group
Make users and groups primary keys foreign keys on people
Insert records in people
Obtain the ID that was assigned using LAST_INSERT_ID()
Insert in users or groups appropriately, using the ID obtained above
Then you'd reference "people", and not "users" or "groups" in your posts table and so on.
Conceptually, thinking of it in an OO way, it means users and groups both extend people.

How would I add a foreign key in mysql for a column that has unrelated data?

I have two tables that need to be related--a users table and an address_book table
I want each address book entry to be associated with a user_id so that when I delete a user, their address book entries get deleted. But I also have about 10000 entries in the address book that are shared among all users. The user id field for each of those entries is set to 0. There is no user with an id of 0. MySQL won't let me create a foreign key for that field if there's a broken child/parent relationship there. How would I go about setting a foreign key in the address_book table for all users except with an id of 0?
have the user_id of the shared addresses be NULL instead of 0.