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.
Related
I am developing a MySQL db for a user list, and I am trying to determine the most efficient way to design it.
My issue comes in that there are 3 types of users: "general", "normal", and "super". General and normal users differ only in the values of certain columns, so the schema to store them is identical. However, super users have at least 4 extra columns of info that needs to be stored.
In addition, each user needs a unique user_id for reference from other parts of the site.
So, I can keep all 3 users in the same table, but then I would have a lot of NULL values stored for the general and normal user rows.
Or, I can split the users into 2 tables: general/normal and super. This would get rid of the abundance of NULLs, but would require a lot more work to keep track of the user_ids and ensure they are unique, as I would have to handle that in my PHP instead of just doing a SERIAL column in the single table solution above.
Which solution is more efficient in terms of memory usage and performance?
Or is there another, better solution I am not seeing?
Thanks!
If each user needs a unique id, then you have the answer to your question: You want one users table with a UserId column. Often, that column would be an auto-incremented integer primary key column -- a good approach to the implementation.
What to do about the other columns? This depends on a number different factors, which are not well explained in your question.
You can store all the columns in the same table. In fact, you could then implement views so you can see users of only one type. However, if a lot of the extra columns are fixed-width (such as numbers) then space is still allocated. Whether or not this is an issue is simply a question of the nature of the columns and the relative numbers of different users.
You can also store the extra columns for each type in its own table. This would have a foreign key relationship to the original table, using the UserId. If both these keys are primary keys, then the joins should be very fast.
There are more exotic possibilities as well. If the columns do not need to be indexed, then MySQL 5.7 has support for JSON, so they could all go into one column. Some databases (particularly columnar-oriented ones) allows "vertical partitioning" where different columns in a single table are stored in separate allocation units. MySQL does not (yet) support vertical partitioning.
why not build an extra table; but only for the extra coloumns you need for super users? so 2 tables one with all the users and one with super users's extra info
If you want to have this type of schema. try to create a relation
like:
tb_user > user_id , user_type_id(int)
tb_user_type > user_type_id(int) , type_name
this way you will have just 2 tables and if the type is not set you can set a default value to a user.
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.
This is a question of is it possible and should i try to do it?
i have two rows in my table one named jobs and one named contacts (hope you still with me)
in jobs i have the following columns
typeofjob
id
name
phone
address
budget
due
in contacts i have the following columns
id
name
phone
address
is there a way to sync the 2 tables for certain rows?
id
name
phone
address
i ask as this would make life a lot easier for me but worried as id might conflict
and what happens if i delete a user from contacts i would only want it deleted from that row
i am very new to this and learning so if you can answer me with simplify answers that be great just treat it like your trying to explain this to your nan or something, but on the other hand she might pick this up faster than i am :)
What you want as an ID in one of the columns with an ID of a row in another table. So, you could add a column contact_id in jobs table, under the assumption that each contact could potentially spawn multiple jobs. You can then query it, such as
SELECT * FROM `jobs` WHERE `contact_id` = 'whatever'
You could also use JOINS to do more complex and efficient work (remember, the less trips to the database, the better!).
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.
I wondered how a table should be structured when there is going to be more than one value for a certain field. For example, If I have a user who has 10 friends should there be a table that has 10 rows with the user's name and a different friend on each row or should there be one row with the user's name and all the friends put into one? Thanks, the answers will help a lot.
You should make a many-to-many table that links the foreign keys together of two people who are friends. So if Person is the entity you are using, you wouldn't want to constrain the structure by introducing limitations such as 10 friends into a single row.
Fundamentally, what you're trying to do is normalize your data. You should read up a bit on Database Normalization