I'm wokring on a simple social network site and I would like to build a simple news update feed. Feed not in the actual sense but you know like those little reports you get on facebook eg when someone posts a picture you get a simple report saying in your main page that - so and so added a picture, or so and so added a comment. Stuff like that one liners.
However I want to build something similar. I was thinking of running a union based query on all my tables but that is INSANELY impractical. Another idea I had was to create a news feed table which would have fields like:
Who - Action - ON WHAT
Where 'WHo' - refers to the user ID of the individual who did something
Action refers to the action ie.. adding a comment
WHAT refers to like if the action was done ON something like a comment passed on an article.
However I'm not so sure if this is a good idea... I want a simple solution - any ideas would be much appreciated.
I think this sort of depends on what sort of actions you are expecting to be performed on your items. I'm no expert, but I think the approach I would take is to keep each action distinct.
Let's assume that you have news items to display in your feed, and users can vote on them (or even just 'Like' them a la Facebook) or add a comment about the item.
I'd likely set up my database as such:
NewsItems
---------
NewsId
UserId (if this is like Facebook where it's someone posting their item)
Body
Timestamp
Votes
-----
VoteId
NewsId
UserId
VoteType (or possibly VoteValue with values +1 and -1 or something)
Timestamp
Comments
--------
CommentId
NewsId
Body
Timestamp
Using this, you can retrieve the last n items that a user posted from the NewsItems table, and as you display each, you can use it's NewsId to determine it's current vote count from the Votes table, and also use NewsId to retrieve a chronological listing of all comments made on the item.
I suppose you could also replace the Body field in NewsItems with two other fields, like NewsType and TypeId. The former tells you which table to use to lookup an action (since you probably don't want picture BLOBs and status update text in the same field/table. The second gives you the key to lookup in that table.
Just my two cents. Hope it helps.
thats a tricky and not so easy thing to do.
I worked for a start up social network and it was something they wanted as well.
I dont think i still have the code laying around but if i recall correctly i went about it something like this
DB:
USERS
id : guid "a unique identifier for this user"
"other user info"
ACTIONS
when : unix_timestamp
who : guid "the user who made the actions guid"
type : set('image','news') "replace with a list of the type of things you want to track"
what : url "not like a web address but the guid of the thing that was made"
FRIENDS
id1 : guid "one of the 'friends' guid's
id2 : guid "the other persons guid
PHOTOS
id : guid "a unique identifier for the image"
url : varchar(255) "where is the image stored (file name directory etc)
who : guid "the user who posted the photos guid"
"other info you want to keep track of"
NEWS (think status update)
id : guid "a unique identifier for this statu update"
who : guid "the guid of the person who posted this"
when : unix_timestamp "timestamp of when it was posted
what : text "the contents"
using the above structure i would have my code make an entry into the ACTIONS table anytime a user posted a photo or a status update. then when their friend logged on it would go through the ACTIONS table pulling out all the actions of anyone it found was friends (via the FRIENDS table)
the TYPE field is used to differentiate what table to use when linking the IDs of the actions. so if the person posted an image when it writes the action to the screen it can set the link up to point to whatever script your using to display images. etc etc
ill see if i can find the code, if i can ill post it (company went under and i retain ownership of the code)
If my explanation isnt clear ill take some more time later to better document the process and code.
Related
I have a website coded in html/css and a bit of js and jQuery.
MySql is my choice of database.
I have a login-system and users can create their own accounts on my site.
The problem is, that I'm trying to somehow restrict users so that only user A can view content (in this case, images) that I have specified for him. User B can only view its own content and so on.
I tried to mess with Role Based Access Control in php but I failed.
I'm looking for a simple solution. I have one (1) table with users where the "user_id" is the primary key.
Isn't there a way to do something like this?
if(user_id == 1) {
Do somethnig here
}
Charles, as commented there are many "open source content management systems" available that do this out of the box - I personally favour http://www.silverstripe.org/
However your question is about how to structure your database and I would recommend a "many many" relationship ( https://en.wikipedia.org/wiki/Many-to-many_(data_model) ). To create this you will need a table in the middle that stores all the id's from both ends.. e.g.
member - id - plus other fields
member_image - contains only member_id and image_id
image - id - plus other fields
to complete your code example...
$sql = "SELECT 1 FROM member_image WHERE member_id = $iMemberID AND image_id = $iImageID"
...it would be "if" the above SQL returned a row or not they member can access that image
I am new to MySQL and PHP. I am having issues wrapping my mind around how to accomplish something. I am building a site that has basically a forum style post page. Users enter text into a textarea which then posts that text along with a timestamp and $_SESSION['Username'] into a MySQL table titled "campaigns." So the table has postEntry, postName and postDate rows currently.
On this same page that I have the form, I then display the entire contents of the campaigns table into a div. So it can show each post in descending order.
This has been working great for me, but I am now trying to look at the bigger picture and am thinking this is not a good way to do what I need. I basically need the ability to have an endless amount of "campaigns" each with their own set of posts. Then give the user the ability to select which campaign they want to view and show corresponding posts for that campaign in the div.
So the real question is: Is there a way to do this with just one table. Or would each campaign need it's own table in the database?
Add a campaign_id to the POST table and viola!
edit: more info:
you need one table for the campaign like so:
Campaign
-------------
campaign_id
name
then you need another one for all the posts
post
-------------
post_id
campaign_id
post_time
name
this way, each post is associated to a specific named campaign.
im making a site thats a news/blog kind of site where people can leave comments to the posts that are made. then logged in users are able to give a comment a thumb up or down. it works fine at the moment i click the thumb and it uses ajax to add the count to the database and update the number and it also stops the person from being able to click the thumb again but if you press f5 to refresh the page you can click the thumb up again. how can i stop this from happening?
adding this to a database is an option i was thinking of but the site needs to be able to handle lots of comments and users there could be thousands of thumbs made to comments since its an easy action to perform the database table would be huge after a short amount of time which would surely slow down page loads since it will be querying a massively long table every time you view a page with comments.
currently i keep count of the thumbs up and down in the comment table so it querys the comments table and will display the numbers. are you suggesting i add a new table that contains userid and a commentid if someone makes a thumb up so i can query that table and if there is a row where userid == the logged in user and commentid == the comment dont allow? if so this is the thought i had on how to do it but as i said above it will lead to a massive table that will surely slow down the loading of the page
One way to go is when you load the comments also load if that user has already casted a vote on each of them, disable the thumb up button if that user already voted.
You shouldnt store the click as a simple counter but store the actual event
Create a seperate table called 'clicklog' or something and add the fields like userid, commentid, IsThumbsUp. Then in your ajax page you can add the thumbs up to this table (IsThumbsUp is a boolean. True for thumbsup and false for thumbs down.
then instead of using something like SELECT comment, thumbsUp, thumbsDown you could use
SELECT id, comment,
(SELECT count(commentid) FROM clicklog WHERE commentID=id AND IsThumbsUp=1) AS thumbsUp,
(SELECT count(commentid) FROM clicklog WHERE commentID=id AND IsThumbsUp=0) AS thumbsDown
FROM comments
And also in your AJAX page you can check if the user has voted before. If he has, dont allow it. Or even better. When he has voted UP, he can change it to vote DOWN (change the IsThumbsUp from 1 to 0) or visa versa.
Just make sure each user only has one connection with commentid and userid.
Also make sure you put an index on the fields in clicklog to get the information quickly. I'd put the primary key on commentid and userid combined and then a seperate index on commentid and IsThumbsUp combined
I have a website where people can post messages and I store them in this form:
post_id : {user_display_name, title, body}
for example:
234567 : {
user_display_name : "John Doe",
title : "Title here now",
body : "Body of the post here"
}
My problem now is, what happens if John Doe decides he's gonna change his name to John Lorem? In a relational database, I would just have a user id that points to user information so that if he changes his name, changes will reflect everywhere.
How can I achieve this in a NoSQL database?
Because I don't think it is practical to lookup John Doe in the whole keyspace and change it to John Lorem.
Thank you
If you maintain a Column Family for post's by user you should pull all the post's for that user and change their display name.
Similarly in RDBMS without index (aka relation ship) you will end up accessing full table to change display name.
However, you can write Map-Reduce to identify post for user and change their display names and for future you can maintain a column_family with.
ROW -> USERID (or) USERID_YYYYMM (to avoid hot-spots)
COLUMN Name -> Reverse(TimeStamp):PostId
This column family will also help you quickly fetch latest Postid's by userid.
Personally I find it sometimes still makes sense to store data that may change using IDs as you would in a relational model. Considering the extra lookup to get the name for ID is really cheap, this tends to be more reasonable than running through your entire CF to make the change.
In my database are 2 tables: "books" and "users". I'm displaying all the books on a page and would like the option for a user to click a little link "I've Read This", similar to Facebook's Like function with statuses. The user could click that they've read the book or unclick to "unread" the book. Other users logged in could also see who has read what. I'm questioning my approach and would like to get feedback on other directions to take for something like this.
What I had in mind was to have a field in the "users" table, maybe something like "books_read", in which I would store an array of values (book_id's). On the frontend where all the books are displayed, I would query the "books_read" field and if a value matched the current book_id, then underneath that book would be something like "User X has read this".
In short, I would store an array of "book_id"s in the "users" table to collect what books each user has read. I would pull this array and compare IDs to each book queried, and if there is a match, output that the user has read that book.
Am I missing something or maybe not looking at a cleaner approach?
In a RDBMS such as MySQL, it's rarely ever a good idea to store lists in a field, especially when you know you will be looking for specific pieces in the list later on. The database can not take advantage of an index by doing that.
Instead, you should make an additional table that links users and books read. Optionally, you could call it *users_books* and move read in to its own column.
users_booksread
-----------
user_id
book_id
Create a separate table, perhaps called book_read.
In it, for each book a user likes, store the user_id and the book_id.
Then you don't have messy arrays to deal with, everything is normalized, your design will be cleaner, and your database more flexible. Additionally, your user table won't have a bunch of extra crud bolted on to it that will affect performance in unfortunate ways.