Simple MYSQL data query? - php

Just a really simple question. In my SQL database I have a column named "friend_count" in table "users" to record all friends the logged in user has. This works with UserID numbers and I am trying to figure out how to record them all. Here's my example:
USER #29 becomes friends with USER #422
In the user database under USER #29's info in the column "friend_count" there will then be the number "422", if he then becomes friends with USER #500, it will show "422, 500" and so on... If he deletes one, that particular number is removed from the box. The script will then search these numbers through the user database to show a list of the people you are friends with.
How can I do this? Any ideas? Thanks!

Any time you have a delimited list of values in a column it's almost always a sign that the data model is incorrect. (Actually, I can't think of an exception to this, but I'll stick with "almost always" just to be safe.)
In this case you have two types of entities:
User
Friendship
A friendship, though not a physical object, is a conceptual entity in and of itself. It connects two users and can add more information related to the friendship itself but not necessarily to the two users.
So you might have tables like this:
User
--------
ID
Name
etc.
Friendship
--------
ID
OriginatingUser
AcceptingUser
BecameFriendsOn
etc.
So OriginatingUser might be the user who sent the friend request, and AcceptingUser might be the user who accepted it. BecameFriendsOn is the date it was accepted. You'd probably want to have statuses and other dates to keep track of pending requests, denied requests, etc. But all of this information is related to the friendship, not necessarily to the users.
The concept you're looking to understand here is called a Foreign Key. The OriginatingUser and AcceptingUser columns are the same data type as the ID column on the User table. You would create the Friendship table such that those columns are foreign keys to the User table, this enforces the integrity of the data so that you can't create a Friendship record without two valid and existing User records.
Then to get the list of friends, you'd join the tables in a query. Perhaps something like this:
SELECT
User.Name
FROM
Friendship
INNER JOIN User ON Friendship.AcceptingUser = User.ID
WHERE
Friendship.OriginatingUser = ?
When supplied with the ID of the originating user, this would get all of the names of users to whom that user sent a friend request. You can further build on the query to also get users who sent this same user a friend request, and so on. By making use of the key foreign key relationships between tables which represent different types of entities in the system, you can construct very robust queries to view that data in lots of different ways.

You are describing a relationship between two entities so you can create a table to store the details of that relationship.
Suppose that you have your user table with a userid column and other columns. You can then create a friends table with two columns that are both foreign keys to the user table.
friends = (user, friend)
Thus, for each friend that user #29 gets you need to add a row into the friends table. For example:
USER
ID NAME ...
29 Sam
30 Henry
32 Jane
Friends
user friend
29 30
29 32
Sam is friends with both Jane and Henry but Jane and Henry are not friends.

I would create a table "friendship" with two cols "user" and "friend", then you start adding pairs of user/friend ids

users table:
id, username, whatever else
friends table:
relationship_id, user_id, user_friend_id
example query to get a list of IDs that belong to the users friends:
SELECT f.user_friend_id FROM users u
LEFT JOIN friends f ON f.user_id = u.id
WHERE u.id = {$user_id}

A very simple approach, assuming that if UserA becomes friends with UserB , then UserB also becomes friends with UserA.
Usually, Comma Separated Lists are not recommended, as they will become a pain when the list is very large. A simpler approach will be, make a table friends with columns user_id and friend_id Where user_id and friend_id are the respective UserIDs .
Now when you want to add a friend to someone's list, use the following :
INSERT INTO users (user_id,friend_id) VALUES(UserA,UserB),(UserB,UserA)
Now when you execute the above query, you will have 2 new rows in your friends table :
user_id friend_id
UserA UserB
UserB UserA
When you want to get the list of a user's friends, use :
SELECT friend_id FROM friends WHERE user_id=(Your user's ID)
This will return a row one by one, and hence will give you all the IDs of friends of a particular user.
Now when you want to delete a friend, use :
DELETE FROM friends WHERE (user_id,friend_id) IN ((user_id,friend_id),(friend_id,user_id))
This removes both the rows from the table, which means that the relationship between UserA and UserB is deleted, and neither of them is friend of each other.

Related

How to Create Multiple Rows in Mysql Against One ID (Not Necessarily Primary Key)?

I am developing a reservation system for my school project. It is based on PHP and MYSQL.
The system allows a user to register. After successful login, the users can make a reservation which is stored in the following table in phpmyadmin.
User Table
When a user registers, he gets a user_id. When a user makes a reservation, the data is inserted into the table against the same user_id. But when the user tries to make another reservation, there is no way to store the information of the next reservation.
The question is how do I allow the user to make several reservations?
The user_id is my primary key so I understand it is not possible to create multiple records against one primary key.
Do I have to create a new reservation table and link it to user_id through a Foreign key relationship>? But if my reservation table has a primary key, then several records cannot be inserted against one primary key.
Somehow, each reservation must be linked the unique user_id so that the user can check all the bookings under his name.
Each reservation also needs a unique ID which can be used to cancel/update the reservation.
I believe it must be a basic MySQL question. Something like creating a new reservation table and connecting it with user_ID but I am unable to think of a concrete solution.
Your help is very much appreciated.
Thank You.
Make table users
then at least 2 fields id, name
then make table reservations and its One-To-Many relation so you need to put foreign key in reservation(many side)
reservation
id, name, user_id
then to get reservations from user 1 use select with join
SELECT * FROM reservations r JOIN user u ON r.user_id = u.id WHERE u.id = 1

How i can update junction table automatically and access data from junction table?

Now I have 2 tables: demo(detailed information about users) and users(login and password), then I create a junction table(ID, demo_ID and user_ID).
The system working like this:
User register
User login
User fill form where he gave a detailed information
And I want to fill junction table automatically with user_ID and demo_ID where user_ID will LOGGED USER and demo_ID the information of exactly this user.
How can I do this? Please help me =)
You can use query like -
INSERT INTO rel_users_demo (demo_ID,users_ID) SELECT demo.ID, users.ID join on demo.EMail = users.email
You have not mentioned which column you have in common(foreign key) between demo and users. you can keep your column at place of xx and yy.

Linking two rows from same table MYSQL

As an example, let's say I want users to be friends on the website.
Say, user_id 1 and user_id 2 become friend, I add a row to my table friends:
table friends (user_id1 INT, user_id2 INT), the problem with this table is that I have to query each column to get my results.
Rows may be:
user_id1 user_id2
1 2
2 3
So to get friends of user with id 2, I need to query both columns (which make some not so practical queries), is there a better way to do this?
ie:
$u_id = 2;
SELECT * FROM friends WHERE (user_id1 = $u_id OR user_id2 = $u_id)
I would go for the less space efficient method of adding two rows one linking person A to person B and the second linking person B to person A. Then a single query on a single column will retrieve all friends.
This set up can also be used where "friends" have different privileges or levels of friendship. So person A can give B more access to their stuff than B gives to A.
You could try a different approach, storing all friends of a person inside a field friends in the table and storing everything as a json object.
This way you'd have all one person's friends in a single query and you could get tehir profile with a simple foreach query.
I've been using this for several many-to-many logics and it works flawlessly without the aid of a link table.
I think I'd prefer a UNION, something like:
SELECT user, friend FROM (
SELECT user_id1 AS user, user_id2 AS friend FROM friends
UNION
SELECT user_id2 as user, user_id1 AS friend FROM friends
) u
WHERE u.user = $u_id
(with appropriate caveats about using prepared statements instead of bare variables of course)

MySQL Search for line in text

in MySQL, I have a row for each user, with a column that contains friends names separated by \n.
eg.
Friend1
Friend2
Friend3
I'd like to be able to quickly search all the users where the Friends field contains Friend2.
I've found FIND_IN_SET but that only works for commas and the data can contains commas and foreign characters.
Obviously searching with regular expressions and the such will be slow. I'm new to the whole cross referencing so I'd love some help on the best way to structure the data so that it can be found quickly.
Thanks in advance.
Edit: Ok, I forgot to mention a point that the data is coming from a
game where friends names are stored locally and there are no links to
another users ID. Thus the strings. Every time they connect I am given
a dump of their friends names which I use in the background to help match games.
The most commonly used structure for this kind of data is usually adding an extra table. I.e.
user
id,
name
email,
e.t.c.
user_friend
user_id
friend_id
Querying this is a matter of querying the tables. I.e.
List all of a users friends names:
SELECT friend_id
FROM user_friend
WHERE user_id = :theUser
Edit: Regarding OPs edit. Just storing the names is possible too. In this case the table structure would become:
user_friend
user_id
friend_name
and the query:
SELECT friend_name
FROM user_friend
WHERE user_id = :theUser
Why are you keeping friend names as text? This will be inefficient to edit uf say a user removes a friend or changes their name. That's another thing, you should store friend names by some auto_increment id key in your database. It's much faster to search for an integer than a string, especially in a very large database. You should set up a friends table which is like
Column 1: connectionid auto_increment key
Column 2: user1id int
Column 3: user2id int
Column 4: date added date
ect...
Then you can search the connection table above for all rows where user is user1id or user2id and get a list of the other users from that.
My database hasn't been filled yet so I can easily change the format and structure in which the data will be stored.
Yes, you need to normalize your database a bit. With current structure, your searches will be quite slow and consume more space.
Check out this wiki for detailed help on normalization.
You can have the friends table and users table separate and link them both by either foreign key constraint or inner joins.
The structure would be:
Users table
id: AUTO_INCRMENT PK
name
other columns
Friends table
id: AUTO_INCREMENT(not required, but good for partitioning)
UserID:
FriendsID
DateAdded
OtherInfo if required.

PHP script for adding friends

Well I'm trying for last 5 days to create simple register, confirm, login PHP script, which is for assignment at UNI, but thing which I'm trying for last 5 days and it's not working is adding friends into friend list. Kid a like Facebook but much much simpler, it's for Android game we got as group assignment.
I have one TABLE users where I have fields ID, username, password, email, friends.
Into field friends I would like to save multiple values as ID's of your friends. To retrieve in game some of user information.
This db and tables are on MySQL and INSERT or UPDATE are not working for me, INSERT is creating new record and can't insert only to one column of existing record and UPDATE can't just insert value but will delete old one and insert new one in.
Seeing as this is a many-to-many relation (if I'm correct) so it'd be smart to create a seperate table that records this.
Table: Friends
userID
userID2 (or friendID)
Which you can fill.
For more info: http://www.singingeels.com/Articles/Understanding_SQL_Many_to_Many_Relationships.aspx
Normally you would add a freinds table with the fields:
user_id
friend_id
where both fields are references to the user tables id field.
If you - for some reason - need it to be a field in user table serialize the id values and save them there.
ATTENTION: you won't be able to easily join the tables and there is no automated possibility to keep integrity. If a user is deleted none of the references to this user in friends field will be deleted. This would all be possibile with the secondary friends table and foreign keys.
What you've described here is a many-to-many relationship between people and their friends. The canonical way do implement this in a relational database is to use a pivot table in which each row represents a "friendship" between two people. You'd have two fields to hold the IDs:
users table:
id, name, email, etc.
friendships table:
user_id_1, user_id_2
Then if user 1 is friends with user 2 and user 3, you'd have records (1,2) and (1,3) in the friendships table. You can treat these as reciprocal relationships if you like, or you can require a (2,1) record to denote that user 2 is also friends with user 1.

Categories