I am storing user ID values in a table field separated by a | (user_id1|user_id2|user_id3|user_id17).
A user ID will be added and removed from this field at certain points.
How can I check if the current users ID exists in the field or not using a query?
And it of course needs to be an exact match. Can't look for user_id1 and find user_id17.
I know I could use a SELECT query, explode the field, then use in_array but if there's a way to do it using a query it'd be better.
I guess I'll explain what I am doing: I made a forum for a small private website (7 users), but coding it for larger scale.
My table structure is pretty good: forum_categories, forum_topics, forum_posts. Using foreign keys between the tables for delete and update queries.
What I am seeking help on is to mark Topics as unread for each user. I could create a new table with topic_id & user_id, each one being a new row but that wouldn't be good with alot of users & topics.
If somebody has a better solution I am all for it. Or can prove to me that 1 row per user_id is the best way then I'll be more than willing to do that.
I think you want to track read messages, not the other way around. If you tracked unread messages, every time you add a user you'll have to add that user to every topics "unread list".
I looked into SMF like my comment suggested. They are using a separate table to track read messages.
A simple table that holds user_id and topic_id are you are need. When a user reads a topic, make sure there is a row in the table for that user.
Another reason to use a separate table. It's going to be faster to query against 2 int values in the database than to use LIKE % statements.
Related
I have a table, where I store user uploaded files. There can be 5 different file types: profile picture, cpr file, degree file, video file, background check file.
Table structure is this:
file_id, user_id, file_type, file_size, file_name, file_new_name, file_path, file_cat, date_created
My questions:
Is this structure efficient or should I create 5 different tables?
If I would like to update, lets say user profile picture row, then what would be the best way to do it? --- I came up with a solution that probably is not be the best one- I update the row where file_cat = "profile_picture" and user_id=:user_id. Would that put a lot of load in the system?
First when user signs up, he doesn't have any files. Should I user insert into ... VALUES ... on duplicate key update with a hidden value in a form?
Thank you in advance.
This is three questions not one.
Is this structure efficient or should I create 5 different tables?
One table is good enough
If I would like to update, lets say user profile picture row, then
what would be the best way to do it? --- I came up with a solution
that probably is not be the best one- I update the row where file_cat
= "profile_picture" and user_id=:user_id. Would that put a lot of load in the system?
Not if you have an index on file_cat, user_id (composite index on both fields). If you want to make things a bit leaner you can store constants instead of 'profile_picture' etc. eg
profile_picture = 1
cpr = 2
....
background = 6
This would make the tables and indexes a bit smaller. It might make the queries slightly faster.
First when user signs up, he doesn't have any files. Should I user
insert into ... VALUES ... on duplicate key update with a hidden value
in a form?
No need for that. not having a record for new users actually makes things easier. You can do an COUNT(*) = 0 query or better still an EXISTS query without having to fetch rows and examine them.
Update:
These EXISTS queries are really usefull when you are dealing with JOINs or Sub Queries for example to quickly find if a user has uploaded a profile picc
SELECT * from users WHERE exists (SELECT * from pictures where pictures.user_id = users.id)
If you use the primary key properly then your insert ... on duplicate key update ... query will do everything for you.
For your table you need to define a primary key column. In this case I would say it is your file_id column. So if you do your insert, the MySQL server will check to see if your file_id column is defined already for that value, if so it will update with the new values, other wise it will add a new row of data with the new file_id.
I should be easy enough to separate it though, make 1 script for creating new rows and another for updating. Usually you will know when you are creating as opposed to updating in an application. Again using a primary key correctly will help you out a lot. Using a primary key in your where clause I am pretty sure is one of the most efficient ways to update.
https://dev.mysql.com/doc/refman/5.5/en/optimizing-primary-keys.html
I have a MySQL database that stores user emails and news articles that my service provides. I want users to be able to save/bookmark articles they would like to read later.
My plan for accomplishing this was to have a column, in the table where I store the users' emails, that holds comma-delineated strings of unique IDs, where the unique IDs are values assigned to each article as they are added into the database. These articles are stored in a separate table and I use UUID_SHORT() to generate the unique IDs of type BIGINT.
For example, let's say in the table where I store my articles, I have
ArticleID OtherColumn
4419350002044764160 other stuff
4419351050184556544 other stuff
In the table where I store user data, I would have
UserEmail ArticlesSaved OtherColumn
examlple1#email.com 4419350002044764160,4419351050184556544,... other stuff
examlple2#email.com 4419350002044764160,4419351050184556544,... other stuff
to indicate the first two users have saved the articles with IDs 4419350002044764160 and 4419351050184556544.
Is this a proper way to store something like this on a database? If there is a better method, could someone explain it please?
One other option I was thinking of was having a separate table for each user where I can store the IDs of the articles they saved into a column, though the answer for this post that this is not very efficient: Database efficiency - table per user vs. table of users
I would suggest one table for the user and one table his/her bookmarked articles.
USERs
id - int autoincrement
user_email - varchar50
PREFERENCES
id int autoincrement
article_index (datatype that you find accurate according to your structure)
id_user (integer)
This way it will be easy for a user to bookmark and unbookmark an article. Connecting the two tables are done with id in users and id_user in preferences. Make sure that each row in the preferences/bookmarks is one article (don't do anything comma seperated). Doing it this way will save you much time/complications - I promise!
A typical query to fetch a user's bookmarked pages would look something like this.
SELECT u.id,p.article_index,p.id_user FROM users u
LEFT JOIN preferences ON u.id=p.id_user
WHERE u.id='1' //user id goes here, make sure it's an int.. apply appropriate security to your queries.
"Proper" is a squirrely word, but the approach you suggest is pretty flawed. The resulting database no longer satisfies even first normal form, and that predicts practical problems even if you don't immediately see them. Some of the problems you would be likely to encounter are
the number of articles each user can "save" will be limited by the data type of the ArticlesSaved column;
you will have issues around duplicate "saved" article IDs; and
queries about which articles are saved will be more difficult to formulate and will probably run slower; in part because
you cannot meaningfully index the the ArticlesSaved column.
The usual way to model a many-to-many relationship (such as between users and articles) is via a separate table. In this case, such a table would have one row for each (user, saved article) pair.
Saving data in CSV format in a database field is (almost) never a good idea. You should have 3 tables :
1 table describing users with everything concerning directly the user
1 table describing articles with data about it
1 table with 2 columns "userid" and "articleid" linking both. If a user bookmarks 10 articles, this table will have 10 records with a different aticleid each time.
I have to create a system to save user's vote for two different type of module: News and Video.
This table should have the same fields:
id
entry_id
vote
user_id
So I tought to add a new field to save also the name of the module (module), in this way I can have just one table in the DB and filter it when needed and create two views for statistic purpose.
I don't really know if the best solution is one table with the new field or is better have two different table.
Let's assume that I have 1000 news and 1000 users and all of them will vote each news I will have 1000000 rows in the table.
Now assume that I have also 1000 videos and also in this case all my users will vote it, other 1000000 rows for an amount of 2000000 rows in a single table.
Do I have any performance problem in this case? And If I will have much more video, news an users?
Operation that I should do:
Insert
Update
Search
If you need more infos please ask
I think the way to answer this question is based on entry_id. The votes are going to be about something and that something is going to reference another table.
So, if you have two separate tables for News and Videos, then you should have two separate votes tables. Neither will have entry_id. One will have news_id and the other video_id.
If you have one table, say Entries for both News and Videos, then have one table.
In other words, I am advising against having one table conditionally reference multiple other tables. It becomes very difficult to express foreign key restraints, for one thing. In addition, join operations are cumbersome to express. Someone else might visit the table and not realize that entry_id can refer to multiple tables, and incorrectly set up queries.
All of these problem can be overcome (and there are situations where one table may be the preferred solution). However, if the original entities are in different tables, then put the votes in different tables.
I am working on creating a favorites section on my website where users can simply store certain items in their favorites section for easy access. Each of the items are already well-defined and have multiple attributes. So my question is lets say I had 10,000 users and I would like to implement a 'favorites' system, what would be the best way to keep track of what favorite items have been added by each user?
I was thinking implementing this the following way: link each favorited item id to a username and then run a query for if the user with a particular username is logged in than retrieve all the favorited items by that username.
I appreciate any help with figuring out of a good way to do this. My goal is to store in a way that is later easy to retrieve and use the data and minimize redundant information.
It's pretty easy, you need to create a new table with 3 fields:
id
favoriteID
userID
Every time a user adds a new favourite, it adds a new record to this table, storing both the ID of the favorite, and the ID of the user. There is no redundant information and it's easy to retrieve the details of either the favorite or the user by implementing a join query. This is what relational databases are for.
Within an RDBMS you would probably have a many to many table with the user id and article id. You do not need an independent id column:
create table favourites (user_id int, article_id int);
These of course reference your user table and articles table. (Or whatever you have in place of articles.)
You would then need to retrieve all rows for a single user when wanting to show that user's favourites. You might also want to make a combined UNIQUE index on the columns to prevent duplicates.
You may have faster response with something like cassandra where you can simply retrieve based on the key of the user_id and get all their favourites in one easy spot. But then you're dealing with mutilple systems.
I've heard, but haven't had a chance to look into, that MySQL can now support a Key-Value system similar to Cassandra and that may be your best bet.
I'm working on an app in JavaScipt, jQuery, PHP & MySQL that consists of ~100 lessons. I am trying to think of an efficient way to store the status of each user's progress through the lessons, without having to query the MySQL database too much.
Right now, I am thinking the easiest implementation is to create a table for each user, and then store each lesson's status in that table. The only problem with that is if I add new lessons, I would have to update every user's table.
The second implementation I considered would be to store each lesson as a table, and record the user ID for each user that completed that lesson there - but then generating a status report (what lessons a user completed, how well they did, etc.) would mean pulling data from 100 tables.
Is there an obvious solution I am missing? How would you store your users progress through 100 lessons, so it's quick and simple to generate a status report showing their process.
Cheers!
The table structure I would recommend would be to keep a single table with non-unique fields userid and lessonid, as well as the relevant progress fields. When you want the progress of user x on lesson y, you would do this:
SELECT * FROM lessonProgress WHERE userid=x AND lessonid=y LIMIT 1;
You don't need to worry about performance unless you see that it's actually an issue. Having a table for each user or a table for each lesson are bad solutions because there aren't meant to be a dynamic number of tables in a database.
If reporting is restricted to one user at a time - that is, when generating a report, it's for a specific user and not a large clump of users - why not consider javascript object notation stored in a file? If extensibility is key, it would make it a simple matter.
Obviously, if you're going to run reports against an arbitrarily large number of users at once, separate data files would become inefficient.
Discarding the efficiency argument, json would also give you a very human-readable and interchangeable format.
Lastly, if the security of the report output isn't a big sticking point, you'd also gain the ability to easily offload view rendering onto the client.
Use relations between 2 tables. One for users with user specific columns like ID, username, email, w/e else you want to store about them.
Then a status table that has a UID foreign key. ID UID Status etc.
It's good to keep datecreated and dateupdated on tables as well.
Then just join the tables ON status.UID = users.ID
A good option will be to create one table with an user_ID as primary key and a status (int) each row of the table will represent a user. Accessing to its progress would be fast a simple since you have an index of user IDs.
In this way, adding new leassons would not make you change de DB