Optimal Database design regarding functionality of letting user share posts by other users - postgresql

I want to implement functionality which let user share posts by other users similar to what Facebook and Google+ share button and twitter retweet.
There are 2 choices:
1) I create duplicate copy of the post and have a column which keeps track of the original post id and makes clear this is a shared post.
2) I have a separate table shared post where I save the post id which is a foreign key to post id in post table.
Talking in terms of programming basically I keep pointer to the original post in a separate table and when need to get post posted by user and also shared ones I do a left join on post and shared post table
Post(post_id(PK), post_content, posted_by)
SharedPost(post_id(FK to Post.post_id), sharing_user, sharedfrom(in case someone shares from non owners profile))
I am in favour of second choice but wanted to know the advice of experts out there?
One thing more posts on my webapp will be more on the lines of facebook size not tweet size.

I would suggest that your system would do one of the two:
Put code inline for the post (similar to a hyperlink) that would reference the original post. I do not know if you are trying to pull in images or other media. When you encounter this inline code, your system could either create a hyperlink to view the original or pull data from the original into the post that is sharing it.
Alternatively your poststable could have a column for shared_post that could either be a post_id or a hyperlink to an external item to share. Your system can then recognize that if the value is null or -1 that it is not a shared post and can treat it normally.
I would not recommend creating a new table for storing duplicates of the shared posts. It becomes harder to maintain and update.
Additionally, if you plan on having sharing groups involved in this system, you will most likely need another table that links post_id to sharing_group_id.

Related

Best way to design a URI for REST API

I am designing a REST API with similar functionality as of Posts and Comments in Facebook.
URI looks like:
/posts/{post-id}/comments/{comment-id}
To get all the comments I use the collection URI naming standard. For example:
/posts/{post-id}/comments
But I am having difficulty when I need comments for all the posts. What would be the best way to incorporate that keeping in mind that I want to use this design only for posts and comments?
Edit
I have to mention here that the resources I am using are a bit different from posts and comments in a way that the in my design I will have to use posts and cannot have comments as entirely different entity. Sorry for the misunderstanding.
Said that, is it recommended to design URI in any of these ways:
/posts//comments
/posts/"any-string"/comments
But i am having difficulty when i need comments for all the posts. What would be the best way to incorporate that keeping in mind that i want to use this design only for posts and comments.
HTTP includes the concept of redirection - a general facility for telling the client to send a request to some other resource.
GET /714eeebd-d89e-4f13-b2a8-cf8a3ee03481 ...
307 Temporary Redirect
Location: /7604abf9-d4f5-42c7-b687-96dbff32649f
What this means is that, if you choose the wrong spelling for your URI, you can correct it later.
The design of REST is such that identifiers are opaque - nobody other than the server is supposed to be extracting information from them.
Also, keep in mind that resources are not domain entities -- it's normal to have many more resources than you have domain objects. Any given Post in your domain model might have many different resources that show it.
If you are really developing a REST service, and you want to "help" clients by making it difficult to cheat, you may want to abandon the idea of using a hackable identifier.
All that said
/comments
is a perfectly reasonable collection identifier all on its own, and its perfectly reasonable to create an identifier hierarchy under that root.
Below URI should serve the purpose.
/comments
For the above given example, let's understand the relationship of entities and URI:
posts and comments are two entities on its own.
when you need only posts and just passing post_id
To retrieve the posts:
/posts
To retrieve a specific post:
/posts/{post_id}
when you need only comments and just passing comment_id
To retrieve all comments:
/comments
To retrieve specific comment:
/comments/{comment_id}
when you need comments for a given post by passing both post_id and comment_id
To retrieve comments on a post:
/posts/{post_id}/comments
To retrieve specific comment for given post:
/posts/{post_id}/comments/{comment_id}
Hope it solves your issue.

Including captions in app generated images

I am having a doubt regarding the Facebook policies. It is being stated that:
IV. Application Integration Points
.....
You must not pre-fill any of the fields associated with the following products, unless the user manually generated the content
earlier in the workflow: Stream stories (user_message parameter for
Facebook.streamPublish and FB.Connect.streamPublish, and message
parameter for stream.publish), Photos (caption), Videos (description),
Notes (title and content), Links (comment), and Jabber/XMPP.
.....
Source: https://developers.facebook.com/policy/
And from the examples & explanation page, it says the following for Photos:
You must not pre-fill Photo captions unless the user manually
generated the content earlier in the workflow. These fields are
intended for users to express themselves. Pre-filling these fields
erodes the authenticity of the user voice.
So, my question is: I have seen 99% of the apps (that I used), is auto-filling caption field for photos with say, something like: You can try it by visiting here: http://www.apps.blahblah.com/appname
Isn't that against the facebook policy ? Or they are not flagged because they are using the extended permissions(publish_stream) instead of the post_actions ?
If it is not allowed for both the permissions, then my next question is, how would we tell the users viewing the photo, the link to the app so that these audiences can also try the app ?
Also, if possible, I would like to see a small example of the caption that would be generated in the workflow as mentioned here in the policies: ...You must not pre-fill any of the fields associated with the following products, unless the user manually generated the content earlier in the workflow....
Thanks in advance.
It is against policies, but many apps do it nevertheless.
I think a compromise would be to have the user enter their own message, and then just append a little link to the end of that before posting it.
As for the example, what exactly would you like to know/see? You have the user put in a message through a text field/input box/whatever, and set that as the message while posting the image.
Currently its forbidden. User should fill the whole caption text. Adding anything to it also is also forbidden.
You can watch the Facebook policy video about pre-filling here:
https://developers.facebook.com/docs/apps/review/prefill

Facebook note shared info

My client need to randomize over everyone that shared a specific note on his facebook page, it's like a raffle, however, i didn't found a way to get any info, even the name in a way that i can randomize over them, is there any way that i can fetch this information?
You can query the note for the comments or likes if you are looking at a specific note. Or you can query the user for all their notes and loop over that.
Depending on what language you are using, randomly choosing from an array of items should be trivial.

How does facebook store the friends of a user?

I am wondering how exactly the information that a user with id x is friends with users with ids z,y,w is stored in a very large scale app like facebook.
I am thinking of several possibilities
a) Have a table which maps friendships with the ids of the people involved as foreign keys, as shown here:
Person|isFriendsWith
x -------------------y
x ------------------ z
x------------------- w
Which seems to me it wouldnt scale well at all.
b) Have a field in the users row that stores the ids of their friends in a kind of serialized format like a string "#z#y#w". I suppose with the right algorithm the parsing and updating of this string would be easy.
c) Have a separate table with the friends of each user. Would this be too much load on the server?
d) Something else?
So, if anybody knows what facebook does and can share details it will be appreciated, that's what the question is about. Also, if someone can share insight why what I listed here would not scale well or would have other problems performance-wise, I am interested in hearing it.
Thanks
Here are some links. The first link's page has a link in it on the words "largely complex" that link to a flickr image of a schema. I cannot vouch for the correctness of any of the information in these links:
http://www.makeuseof.com/tag/facebook-work-nuts-bolts-technology-explained/
http://www.theregister.co.uk/2011/07/13/mike_stonebraker_versus_facebook/
http://gigaom.com/cloud/facebook-trapped-in-mysql-fate-worse-than-death/
http://snarfed.org/facebook_data_store_api_thoughts/
The image I mentioned was created by analyzing the business entities in the API that Facebook has opened up. http://blogs.x2line.com/al/archive/2007/06/02/3124.aspx
That was 2007, so may or may not be representative any longer.

Facebook Graph API: Getting the total number of posts

I've been using the Facebook Graph API to display user posts. When I get the initial "page" of posts, the resulting data object has a paging property object with a previous and next URL property. I was hoping to generate navigation links based on this available paging information. However, sometimes these URLs point to an empty set of data, so I obviously don't want to navigate the user to an empty page.
Is there a way to find the total count of objects in a collection so that better navigation can be derived? Is there any way to get smarter paging data?
Update:
Sorry if my post isn't clear. To illustrate, look at the data at https://graph.facebook.com/7901103/posts and its paging property URLs. Then follow those URLs to see the issue: empty pages of data.
Since it pages the datas with date-time base. You can't get the knowledge of whether if there are datas or not before you actually send the request to it. But you can preload the data from previous url to determine is it suitable to dispaly a previous link in your web page.
Why be dependent of Facebook?
Why don't you preload all data for a user and save into a database. Then you fetch the posts from db and show to user. This way you have all the control on how many posts there are and how to manage next and prev.
I was going to try to post this as a comment to your question, but I can't seem to do so...
I know that the Graph API returns JSON, and while I've never come across a way to have the total number of posts returned, depending on what technology you are using to process the response, you might be able to capture the size of the JSON array containing the posts.
For example, if I were using a java application I could use the libraries available at json.org (or Google GSON, or XStream with the JSON driver) to populate an object and then simply use the JSONArray.length() method to check for the number of posts returned.
see:
http://www.json.org/javadoc/org/json/JSONArray.html
It might seem like a bit of a simplistic solution, but might be the type of work around you require if you can't find a way to have Facebook return that data.
Can you specify what technology your application is based in?