I have a site where users can post things like statuses, pictures, etc. I'm wan't to create a notification system similar to Facebook . Something that alerts the user of their friends recent activity. My problem is i'm not sure how I should structure my table. I'm following some advice from an older tutorial Tutorial for the db scheme, and doing something like this
id | user_id | subject | body | object_id | object_type | is_read | sent_at | created_at | updated_at
I know what to do for the majority of the code, or at least have a good idea, my problem and question is for the is_read column, should i create a separate table to store that information, if not then how can I mark a notification as is_read with the current setup.
I guess you want to have a "is read" for EVERY friend/user, this was a bit unclear. If this is the case your best bet (in my opinion) would be to create a new table, as you said, containing the post_id, and user_id. All you then have to do is to check is such a relationship exists, and if so, show a notification.
Related
Information:
I have 2 tables(users for the users of the website and new_themes for themes/posts(whatever) created by the users.
!!!There is no relationship between these 2 tables.(A user can create a new post if he is logged in)
Tables:
Users:
1 id
2 name
3 email
4 password
New_themes:
1 id
2 title
3 text
4 upVotes
5 downVotes
6 TagName
What I want to do:
I created the feature that user can like the post(but he can like it unlimited number of times) but I want them to be able to like just once in a life time a post.
What I can't figure out is the idea/structure/logic of how to make it. I am thinking of creating a table . A "pivot" one for tables users and new_themes(many to many relationship in Laravel)
1 id_user
2 id_theme
Where the both of them have a composite primary key so they won't be any duplicate values, so if the user wants to vote once again the same post he won't because there can't be duplicate values.
Here is the problem:
If this is the solution, I have doubt and no idea on how to populate the pivot table when a user likes a theme. If this isn't the solution any advice or idea will be very helpful for me to finish my last feature of my wep app.
Thank you very much.
What I can't figure out is the idea/structure/logic of how to make it. I am thinking of creating a table . A "pivot" one for tables users and new_themes(many to many relationship in Laravel)
That's the way to go. So it would look like this:
+---------+----------+
| user_id | theme_id |
+---------+----------+
| 1 | 1 |
+---------+----------+
| 12 | 1 |
+---------+----------+
| 14354 | 1 |
+---------+----------+
To 'like' a theme, just insert the user and theme id into the table. The rest is just taking care of the response from the database - giving the user feedback for his try to like something more than once etc.
And of course you should not forget the ability to unlike - so you need to delete from the table again... if you want users to unlike.
First you have to create a new table with following fields (id, user_id, theme_id, status) as you said, maintain the relation between user and theme in that table.
when user like the theme insert a record with status 1 , if user unlike the theme, first check the user_id in the table, if user id is present then just update the status to 0 otherwise insert new entry with status 1.
I work on a message system. in this message system admin can send messages to single user, user group or all users and users just can see messages.
know i want to find unread messages in user panel.
i designed two database table like this :
1- msg_messages :
| id | title | messages | date | status |
2- msg_control :
| id | message_id | from | toUser | toGroup | status |
Know i think about this two methods of saving users who saw the messages.
Method 1 : create a string with readers id Like this : 1,5,9,12,... and check users id with this string by Strpos php function or in_array function.
Method 2 : create a new table like below table and save readers id in that :
| id | message_id | readers_id | date |
which one of this two method is better ?
A new way to find unread messages ...
after think more about this problem i decided to use a new method by combining method 1 and method 2. actually i added a new column to user table and named it read_msg . system will save read message_id in this filed in a string like this 1,5,9,12,98,125,... for each user (message_id in this filed refer to msg_control table ) and when we want to find unread messages just need to compare msg_control ids with this filed.
we use strpos to compare read_msg and message_id because its faster than is_array (reference).
I once implemented a small messaging system and structured it as follows (however it might not be perfect and there are multiple possibilities):
Tab Conversation
ID | Conv Title | ... master data
Participants
UserId | ConversationID | lastRead
MessageHeaders
ConversationID | messageID | ... use your "inbox"-schema here. You can remove the toUser/toGroup etc. fields as this is covered using the participants table.
Using the timestamps of a message and the "last-read"-timestamp of a user for a conversation you can determine which messages are new/unread and which are not.
Using constructs like in your first suggestion can become very inefficient. Storing data atomar is considered good practice in my opinion. This means no multiple values in a single field.
How would things like customer reviews be stored in a database? I cant imagine there would be rows for each item and columns for each review as one product may have 2 reviews and another may have 100+ - id presume they were stored in a separate file for reviews but then surely not one file per item! I dont know enough about storing data to be able to figure this one out by myself!
A similar situation is something like an online calendar - there is all the information about each appointment (time, duration, location, etc) and there can be many of these on each day, every day, for all users! A logical way would be to have a table for each user with all their appointments in, but at the same time that seems illogical because if you have 1000+ users, thats alot of tables!
Basically Id like to know what the common/best practice way is of storing this 'big dynamic data'.
Customer reviews can easily be stored by using two tables in one-to-many relationship.
Suppose you have a table containing products/articles/whatever worth reviewing. Each of them has an unique ID and other attributes.
Table "products"
+-------------------------------------+
| id | name | attribute1 | attribute2 |
+-------------------------------------+
Then you make another table, with its name indicating what it's about. It should contain at least an unique ID and a column for the IDs from the other table. Let's say it will also have an email of the user who submitted the review and (obviously) the review text itself:
Table "products_reviews"
+--------------------------------------------+
| id | product_id | user_email | review_text |
+--------------------------------------------+
So far, so good. Let's assume you're selling apples.
Table "products"
+-------------------------------+
| 1 | 'Apple' | 'green' | '30$' |
+-------------------------------+
Then, two customers come, each one buys one apple worth 30$ and likes it, so they both leave a review.
Table "products_reviews"
+-------------------------------------------------------------------------------+
| 1 | 2 | alice#mail.com | 'I really like these green apples, they are awesome' |
| 2 | 2 | bob#mail.com | 'These apples rock!' |
+-------------------------------------------------------------------------------+
So now all you have to do is to fetch all the reviews for your apples and be happy about how much your customers like them:
SELECT *
FROM products_reviews
INNER JOIN products ON products_reviews.product_id = products.id
WHERE products.name = 'Apple';
You can now display them under the shopping page for apples (just don't mention they cost 30$).
The same principle applies for things like an online calendar. You have one table with users, and many tables with other stuff - appointments, meetings, etc. which relate to that user.
Keep in mind, however, that things like meetings are better displayed in a many-to-many table, since they are shared by many people (usually). Here's a link that visualizes it very good, and here's a question here on SO with sample code for PHP. Go ahead and test it for yourself.
Cheers :)
I am making a notification system so that when users in a group perform an action, it will notify all the other users in the group. I want the notification to be marked "read" or "unread" for each user of the group. With that, I can easily retreive any unread notification for a user and display it. I am think about creating a notification table that have the following fields.
+----------------------+
| notification |
+----------------------+
| id |
| userid |
| content |
| status (read/unread) |
| time |
+----------------------+
My question is:
Whether it is the correct way of making the system? As it means that when there is 1,000 users in a group, then I have to insert 1,000 rows to the table. If not, what is the better way of doing this?
If it is the way to do this, how can I write the php/mysql codes to do the looping of inserting the rows?
Thanks!
A better way of doing that would be to separate the notification from the user, by doing the following:
Table Notification
------------------
not_id
time content
Table User
----------
u_id
Table NotificationStatus
------------------------
id
u_id
not_id
bool read
That way you have to save each notification only one, what makes it easier to modify/edit notifications
Consider the following data structure:
Table: Events
----------------
event_id
user_id (foreign key to users table)
action_id (foreign key to actions table)
time_stamp
Table: Log
----------------
user_id (foreign key to users table)
event_id (foreign key to events table)
time_stamp
The logic should be that all events are considered unread by user X unless Log table contains the event_id for that user
Actions table may have many types of actions.
You will be able to count and notify all users how many other users have "recieved" the action by querying the log. etc'...
yes..u can do it in this manner..
example: suppose any user "PQP" (user_id=1) is adding a photo then u have to write ur notification query on success of photo adding query (u need to write write query for notification on code wherever u want that point as notification) so your notification table will got new entry as
id = 1
userid =1
content = "Photo Added By User PQP"
status = Unread
time = currenttime
so by this case whenever someone uploads a photo then notification table will got entry in it..
Firstly I think this question can be related to any language, but I specified what I was using.
Excuse me if I start to bore also, but I am trying to find out the best way to build a dynamic survey management system.
My client basically has said to me that the data has to be stored in MS SQL as his client has only got MS SQL connector for SAS, which is going to do reporting.
My logic so far is this:
1st. Setup the survey itself, i.e. ask for title, quick overview, etc, etc.
2nd. Define your questions.
3rd. Publish survey.
Now what I have done so far is that when they "publish survey", I have created a dedicated database table for this survey which will house the responses.
From the admin side of this, they will not be able to modify the questions, maybe the question title but that is about it. They cant add/remove questions.
Question is, is creating individual database tables a good thing? My only worry really is that say the admin creates like 30 questions, I will have 30 columns in that dedicated table. To go with that, this way might be easy for the SAS system to pull in data for reporting. The administrator will not see the survey responses in the admin panel btw.
I have done something similar for a language grading exam. I opted for a more flexible approach with the following tables
+------+ +-------------+ +-------------+ +-------------+ +----------+
| Exam | | Question | | Choice | | Answer | | User |
+------+ +-------------+ +-------------+ +-------------+ +----------+
| id | | id | | id | | id | | id |
| name | | questionNb | | choice | | user_id | | name |
+------+ | question | | question_id | | exam_id | | email |
| exam_id | | isAnswer | | question_id | | password |
+-------------+ +-------------+ | choice_id | +----------+
| isGood |
+-------------+
This model allowed me to easilly have a 15 questions exam, a 30 questions exam and a 50 questions exam. To adapt this model for survey, you might just have to remove the isAnswer and isGood part and you should be good and replace users data with anonymous general data like age, income, sex.
Creating a column for each question is totally wrong, altering the database at runtime for business oriented purpose is a "never ever do".
Read something about "relational databases" things should look like this:
table_surveys
id
survey_name
table_questions
id
fk_survey (foreign key to table_surveys)
question_text
(question value? maybe)
table_questions_options
id
question_id(foreign key to table_questions)
option_value (this can be true/false for a test or a numeric value for a survey)
option_label
table_users
id
username
pass
name
table_answers
id
options_fk (foreign key to table_question_options)
users_fk (foreign key to table_users)
This way everything is linked together (No reusing of options,or questions or stuff into different surveys)
According to the comments in the documentation, MS SQL Support in PHP is iffy at best. Is PHP the only language you are allowed to use for the project? If not, you might want to consider using C#, VB.Net or something more compatible with SQL Server. Otherwise, you could initially store the data in MySQL, and export it to MS SQL Server when you needed to do analysis.
Dont know, if I really understand your question. But I once built such a survey system. And it came out pretty quick and easy with about the following tables (if I remember right):
USER, SURVEYS, QUESTIONS, ANSWERS, [some mapping tables]
The SAS will fetch the data from virtual any table. If everything in one or two tables, it will even be easier.
With all due respect to Kibbee, PHP/MSSQL support is actually VERY good. We do it quite often, and the performance bests PHP/MySQL and matches compiled C#/MSSQL (in our very limited and unscientific testing). This is assuming you're running PHP on a Win machine. Running PHP with a TLS connector to a separate MSSQL box is another ball of wax and can be a pain to configure.
Anyway, we had a similar scenario and went with one table to manage forms (Forms w/ FormID as the primary), another to manage fields/questions (Fields w/FieldID, FieldType such as Y/N, text, select, etc.), and another to "assign" a field to a form (FormFields w/ FormFieldID, FormID, FieldID, parameters in an array for select items, etc.). Then yet another set of tables to deal with the answering of the questions.
I agree with the rest of the group. Make sure to normalize and don't create a separate column for each question. It'll be more work initially, but you'll appreciate it when you simply have to add a few rows to a table instead of re-writing your queries and re-designing your tables.