I am still quite new to mysql and I was curious what the best way to go about saving multiple-users' information in a database. I apologize for this question being as clueless as it is, but I have not been able to find any sort of examples or tutorials regarding this subject.
For example, if there are multiple users and they want to log the distance they have ran and then be able to access this information later, can I store their information in some sort of multi-dimensional array which is linked to their username? Is there a way to do this using cookies? Can cookies be stored on the server and then retrieved on a different computer when the user logs in? Or is it as simple as creating a new table for the user and then storing all of the information there?
Any direction you could offer me would be appreciated
You need multiple tables:
User Table:
ID (Auto increment)
Name (varchar)
...more info...
...more info...
etc...
Distance Table:
ID (auto increment)
User_id (Int)
Distance Ran (varchar)
...more info about the trip...
Now, you can do something like this to get all the runs by a certain user:
SELECT * FROM users LEFT JOIN distance ON users.id = distance.user_id WHERE users.id = $user_id
where $user_id is the person's ID. This will give you all the runs that the user did along with their user information
Good luck! Please ask if you have more questions.
P.S. If you plan to keep data for more than a couple hours, you don't want to use COOKIES or _$SESSION vars, because they are prone to expire, and won't be available to users that login from multiple endpoints.
Related
For a forum, i want to enable the users to send messages to each other to.
In order to do this, I made a table called Contacts, within this table I have 5 collumns: The user_id, a collumn for storing Friends, one for storing Family, one for storing Business and one for other contacts. These last four should all contain an array, which holds the user_id's of that type of contact. The reason I chose for this design is because I don't want to type an awful lot or limit the users on the amount of friends, like friend1, friend2 etc.
My question is: Is this correct how I do it? If not, what should be improved?And what type of MYSQL field should Friends, Family, Business and Other be?
What you should do instead of that is have a map table between your Contacts table and any related tables (User, Friends, Family, Business). The purpose would purely be to create a link between your Contact and your User(s) etc, without having to do what you're talking about and use arrays compacted into a varchar etc field.
Structured data approach gives you a much more flexible application.
E.g. UserContacts table purely contains its own primary key (id), a foreign key for Users and a foreign key for Contacts. You do this for each type, allowing you to easily insert, or modify maps between any number of users and contacts whenever you like without potentially damaging other data - and without complicated logic to break up something like this: 1,2,3,4,5 or 1|2|3|4|5:
id, user_id, contact_id
So then when you come to use this structure, you'll do something like this:
SELECT
Contacts.*
-- , Users.* -- if you want the user information
FROM UserContacts
LEFT JOIN Contacts ON (UserContacts.contact_id = Contacts.id)
LEFT JOIN Users ON (Users.id = UserContacts.user_id)
Use the serialize() and unserialize() functions.
See this question on how to store an array in MySQL:
Save PHP array to MySQL?
However, it's not recommended that you do this. I would make a separate table that stores all the 'connections' between two users. For example, if say John adds Ali, there would be a record dedicated to Ali and John. To find the friends of a user, simply query the records that have Ali or John in them. But that's my personal way of doing things.
I recommend that you query the users friends using PHP/MySQL all the time you need them. This could save considerable amount of space and would not take up so much speed.
serialize the array before storing and unserialize after retrieving.
$friends_for_db = serialize($friends_array);
// store $friends_for_db into db
And for retrieving:
// read $friends_for_db from db
$friends_array = unserialize($friends_for_db);
However, it should be wiser to follow other answers about setting up an appropriate many-to-many design.
Nevertheless, I needed this kind of design for a minor situation which a complete solution would not be necessary (e.g. easy storing/retrieving some multi-select list value which I'll never query nor use, other than displaying to user)
I have a user table which has username,user_id,password and email fields.
The user can post updates,can subscribe to users and can friend people.
What is the best way to design my database in order to store the count of the updates, subcribers and friends of a user?
Should i add 3 more fields in the user table and just increase the count of these 3 columns?
Thanks.
You can make 3 tables: friends (user1_id,user2_id), updates(user_id,content),subscribe(user1_id,user2_id).
If the database is big and you don't want to count the friends each time, you can add a field in users table and update it every time a friend is added/deleted
Maybe drawing a diagram would help:
http://en.wikipedia.org/wiki/Entity-relationship_model
First I'd try to calculate
the count of the updates, subcribers and friends of a user
on the fly, something like
select count(*) from user_updates where user_id = :uid
select count(*) from user_subcribers where user_id = :uid
select count(*) from user_friends where user_id = :uid
If you have performance problems with this approach, then you can consider adding these count fields to user table, but you have to be careful to maintain them.
Not sure if i understand your question but i think the best way to do this is to make a table for each of this functions, you can link those tables with the user_id field. Like so:
Table 'Users' :
*user_id*
username
password
email
Table 'Friends':
id
*user_id*
friendids
You can then get the users with something like
SELECT * FROM friends WHERE user_id = '$userid'
Either create a separate table with that user meta data or add them as new columns. Either way is fine.
I'll assume you meant to type "columns" instead of "friends" in that last sentence.
That's one way to do it.
You should think about the entities, relationships, and cardinalities when you design. Do you want to keep track of timestamp for each update? If yes, I'd make that a separate table with a one-to-many relationship to user. Same for subscribers and friends. The answer depends on how you choose to model the problem. There's no right or wrong answer, but there are tradeoffs.
Well, it is faster to read if you have separated relations and content, however if you have only content and generates relations from it, the result sometimes could be more accurate. So, it depends.
I've got a website where people can make posts and comment on them. I want to make a new comment notification system, so when a user logs in he can see number of new comments to his posts.
My idea is to add a 'read' table, where I will store user_id and comment_id (means user_id read comment_id). But this can make some performance issue, when table will grow big.
What's the best way to implement this?
One way to achieve that is just to save a created date for post and comment, and a "last visit" date for the user (or "last time the user click on the "show me new post" link).
Then, you just need to get all the post and comment that have a newer date than the one you find in the user table.
How about just storing the user and comment IDs for unread comments instead? Then when the user reads the comment, you can delete that row from the table.
Wouldn't it be better to store the post time in the notifications table and then look for the user's last activity (again storing the value in the users table). Then you could do a simple query:
$lastActivityTime = User->GetLastActivity();
$result = mysql_num_rows(mysql_query("SELECT COUNT(`id`) FROM `notifications` WHERE `postTime` > '$lastActivityTime'"));
Good luck!
You can choose a different storage than mySQL for this data (Like : MongoDB).
Or you can make pub/sub implementation for notifying users. (With using pubsub you dont need to store data. Just notify)
I have a list of events for example I wanna show on a page with the users that have created them which is all in a table and the user who has created them's unique id, now if I wanna show their username and avatar I would have to run 100 queries inorder to show 100 events! but I'm sure their is a easier way I don;t know!
i have a table (user_table) with fields user_id INT(8) and user_photo VARCHAR(255)
and I have another table (user_event_table) with event_id INT(8), event_user_id INT(8), event_details TEXT
so I want to show a list of all these events but I want to next to it show the user_photo !
Learn to join with SQL. It's fundamental to relational databases.
SELECT * FROM user_event_table uet
LEFT JOIN user_table ut
ON ut.user_id = uet.user_id
Now each record will have a username and photo string.
Show us your tables, along with the query you're currently using, in a different question and people will help you with the SQL.
Yes. Get the accurate current time at the start of your PHP script, and get the time at the end, and log the page name and the difference in times.
If you're worried about this, you need to conduct a security audit of your scripts. There's no easy way to tell what someone who has access to your page's contents will leak.
Again, you need a real security audit. Someone will have to read and understand all the code in order to be sure. There's no easy way.
On a social network I am working on in PHP/MySQL, I have a friends page, it will show all friends a user has, like most networks do. I have a friend table in MySQL, it only has a few fields. auto_ID, from_user_ID, to_friend_ID, date
I would like to make the friends page have a few different options for sorting the results,
By auto_ID which is basically in the order a friend was added. It is just an auto increment id
new friends by date, will use the date field
By friends name, will have a list in alphabetical order.
The alphabetical is where I need some advice. I will have a list of the alphabet A-Z, when a user clicks on K it will show all the user's name starting with K and so on. The trick is it needs to be fast so doing a JOIN on the user's table is not an option, even though most will argue it is fast, it is not the performance I want for this action. One idea I had is to add an extra field to my friendship table and store the first letter of the users name in it. User's can change there name at anytime so I would have to make sure this is updated on possible thousands of records, anytime a user changes there name.
Is there a better way to do this?
Well if you don't want to do a join, then storing the user's name or initials on the friendships table is really your only other viable option. You mention the problem of having to update thousands of records every time a name changes, but is this really a problem? Unless you're talking about a major social networking site like Facebook, or maybe MySpace, does the average user really have enough friends to make this problematic? And then you have to multiply that by the probability that a user will change their name, which I would imagine isn't something that happens very often for each user.
If those updates are in fact non-trivial, you could always background or delay that to happen during non-peak times. Sure you would sacrifice up-to-the-second accuracy, but really, would most users even notice? Probably not.
Edit: Note, my answer above really only applies if you already have those levels of users. If you are still basically developing your site, just worry about getting it working, and worry about scaling problems when they become real problems.
You could also look at a caching solution like memcached. You can have a background process that is always updating a memcached hash and then when you want this data it is already in memory.
I'd just join on the table that contains the name and then sort on the name. Assuming a pretty normal table layout:
Table Person:
ID,
FirstName,
LastName
Table Friend:
auto_ID,
from_user_ID,
to_friend_ID,
date
You could do things like:
Select person.id, person.firstname, person.lastname, friend.auto_id
from Friend
left join on person where person.id = friend.to_friend_ID
where friend.from_user_ID = 1
order by person.lastname, person.firstname
or
Select person.id, person.firstname, person.lastname, friend.auto_id
from Friend
left join on person where person.id = friend.to_friend_ID
where friend.from_user_ID = 1
order by friend.date desc
I'd really recommend adding a column in the friend table to keep the first letter around, no need to duplicate data like that (and have to worry about keeping it in sync), that's what joins are for.