Okay so im new to databases, and have created a site with a users table, and i also hace a list table, where suers can insert list items, however when they log in everyones list is appearing, how can i link the user table to the lists table, is it creating the same field in each one and using a foreign key? Sorry I am very new to this. Appreciate any help
I think you can just use user_id on both tables to fix this. Let me give an example:
Table A (user_id, username, password)
Table B (list_item_id, user_id , any_other_attribute)
When you design your tables like this a simple sql call will do what you need like:
SELECT 'list_item_id','any_other_attribute' FROM Table B Where user_id=$user_id
Where $user_id is the user_id of the one's who loginned your system.
Also by your question, i suggest you to read about these : 'sessions' , 'sql queries' , 'generating sql query results' on your choice of programming language.
It calls MANY MANY relationnship. There mus be 1 table with fields user_id and field_id that will join this 2 tables
Related
In database in table user I have three columns:
id
name
friends
In column friends are names of people who are friends with person whose name is stored in column name. Column friends looks like this:
friendname1,friendname2,friendname3,friendname4
Each of those friends have it's own row where name is equal to their name.
I also have another table called post where I have four columns:
id
name_posted
post
visible
What I would like now, is to select all posts from table post where name_posted is equal to name of the logged in user or any of his friends which are stored in column friends in table user.
Name of the logged in user is stored in variable $user.
For selecting only posts from logged in user I can use this:
$all_posts = mysqli_query($connect_db, "SELECT * FROM post WHERE name_posted='$user' AND visible='yes'");
but I don't know how to include to select also posts from his friends. Something like Facebook have, when you log in and you see your posts plus your friends posts. I don't know how they created that. Sorry for long post, I just wanted to give you detailed description.
For selecting data based on information across multiple tables I suggest reading up on MySQL Joins.
Maybe with two querys, first select friends something like this:
SELECT * FROM user WHERE name='$user'
You then have all his friends in string like this if I understood correctly :
friend1,friend2,friend3...
Explode $row['friends'] -> explode(',',$row['friends']); to get all friends names in array and then you can do another select in foreach loop to get all posts from friends and display it the way you like or you can even better do IN in query
select * from posts where name_posted IN ($row['friends'])
this is the other way, which would be longer
foreach($friendarray as $k=>$friend){
...
mysqli_query($connect_db,
"SELECT * from post where name_posted='$friend' AND visible='yes'");
...
}
and also the query you already have to get own posts. Don't forget to escape all values and stuff...
You could also join two tables but I cant write that query from my mind , would have to sit down and try it with real data but that would be ultimate solution for you.
Don't know if I hit it right but shout if you need help
You can do it in a single query with something like:
SELECT p.*
FROM user u
join post p
on (u.name = p.name or concat(',',u.friends,',') like concat('%,',p.name,',%')
AND p.visible='yes'
WHERE u.name='$user'
- but the performance is likely to be much poorer than if you had a properly normalised design for the relationship between users and their friends.
You should probably reconsider the design of your DB. From what you've described, you should have three tables: userinfo, friendship, posts.
That way, you can then do a quick union between all three tables to get what you're looking for in one query.
Let me talk about how I will solve that case if its required from me.
I will use the following tables
users - user_id, name, email and whatever I need
relations - relation_id, user_id, fiend_id -- this table will relate one user to other
posts - post_id, user_id, content, visible
Now basically we have everything needed.
For selecting all data from the currently logged user and all of his friend I will use the following query:
SELECT * FROM posts
WHERE Visible = 1
AND (
user_id IN (SELECT friend_id FROM relations WHERE user_id = 1)
OR
user_id = 1)
What I do here, I use nested queries to accomplish that.
The interesting part here is the nested query - which basically return "array" with the ids of my friends. MySQL IN function check the user_id against that "array" After that in the main parentheses I add OR user_id = 1 which is the my user_id.
In that way I should have the content which I want to use to my feed.
However this code I away from fast and optimized but it's good example how to do that.
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.
I have a voting script which pulls out the number of votes per user.
Everything is working, except I need to now display the number of votes per user in order of number of votes. Please see my database structure:
Entries:
UserID, FirstName, LastName, EmailAddress, TelephoneNumber, Image, Status
Voting:
item, vote, nvotes
The item field contains vt_img and then the UserID, so for example: vt_img4 and both vote & nvotes display the number of votes.
Any ideas how I can relate those together and display the users in order of the most voted at the top?
Thanks
You really need to change the structure of the voting table so that you can do a normal join. I would strongly suggest adding either a pure userID column, or at the very least not making it a concat of two other columns. Based on an ID you could then easily do something like this:
select
a.userID,
a.firstName,
b.votes
from
entries a
join voting b
on a.userID=b.userID
order by
b.votes desc
The other option is to consider (if it is a one to one relationship) simply merging the data into one table which would make it even easier again.
At the moment, this really is an XY problem, you are looking for a way to join two tables that aren't meant to be joined. While there are (horrible, ghastly, terrible) ways of doing it, I think the best solution is to do a little extra work and alter your database (we can certainly help with that so you don't lose any data) and then you will be able to both do what you want right now (easily) and all those other things you will want to do in the future (that you don't know about right now) will be oh so much easier.
Edit: It seems like this is a great opportunity to use a Trigger to insert the new row for you. A MySQL trigger is an action that the database will make when a certain predefined action takes place. In this case, you want to insert a new row into a table when you insert a row into your main table. The beauty is that you can use a reference to the data in the original table to do it:
CREATE TRIGGER Entries_Trigger AFTER insert ON Entries
FOR EACH ROW BEGIN
insert into Voting values(new.UserID,0,0);
END;
This will work in the following manner - When a row is inserted into your Entries table, the database will insert the row (creating the auto_increment ID and the like) then instantly call this trigger, which will then use that newly created UserID to insert into the second table (along with some zeroes for votes and nvotes).
Your database is badly designed. It should be:
Voting:
item, user_id, vote, nvotes
Placing the item id and the user id into the same column as a concatenated string with a delimiter is just asking for trouble. This isn't scalable at all. Look up the basics on Normalization.
You could try this:
SELECT *
FROM Entries e
JOIN Voting v ON (CONCAT('vt_img', e.UserID) = v.item)
ORDER BY nvotes DESC
but please notice that this query might be quite slow due to the fact that the join field for Entries table is built at query time.
You should consider changing your database structure so that Voting contains a UserID field in order to do a direct join.
I'm figuring the Entries table is where votes are cast (you're database schema doesn't make much sense to me, seems like you could work it a little better). If the votes are actually on the Votes table and that's connected to a user, then you should have UserID field in that table too. Either way the example will help.
Lets say you add UserID to the Votes table and this is where a user's votes are stored than this would be your query
SELECT Users.id, Votes.*,
SUM(Votes.nvotes) AS user_votes
FROM Users, Votes
WHERE Users.id = Votes.UserID
GROUP BY Votes.UserID
ORDER BY user_votes
USE ORDER BY in your query --
SELECT column_name(s)
FROM table_name
ORDER BY column_name(s) ASC|DESC
I have a table for the users on my site. The table consists of the the columns
user_id, fname, lname, email, password, interest1, interest2, interest3, interest4,
interest5
Now, It's turning out to not be so practical to store the interests individually like so. What is a better way to do this. A way that keeps it easy to edit/access user interests?
Thanks.
Database normalization does what you want.
You'd create a new interests table with structure like this:
interest user_id
"skiing" 1
"programming" 4
etc...
Then, you can get all the interests for a given user with a query like this:
SELECT `interest` FROM `interests` WHERE `user_id` = :my_user_id;
You have a many-to-many relationship between users and interests. Create a seaparte table of interests and introduce a junction table to link users with their interests.
Create a new table named interests with columns user_id and interest.
Serialize them. This way you can store zero to as many interests you they want and when you unserialize them you can maintain the same data structure (i.e. array or object) that you created them with.
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.