5

For reference, here is a question on SO that I asked recently that is relevant to this question: How to model Friendship relationships

On that question, we figured out a way to display news feed items only if posted by friends. However, what I need is advice on how to check for friendship in a more dynamic way so it can be used throughout several site functions.

For example, I've just installed a comment system, allowing users to post comments on news posts. However, this isn't restricted to friends, and it should be (and later should be made optional by the author of the post).

Posting news items only by friends was slightly different because I was getting data directly from the database, and using SELECT subqueries to only get posts by friends of the current user. However, in the example of the commenting, I only want to display the comment post form if the person is a friend. I'm not actually pulling anything from the database to pick, sort, and display.

Knowing issues like this will arise many times throughout the site, what would be the simplest way to check for friendship? Could I somehow pull all the friends' user IDs from the database into a session array of some kind and then do an if(in_array($friends)) whenever I needed to determine if the person in question is a friend of the currently logged in user? Off the top of my head, this sounds like it would work fine, but I'd like your input first.

The question I linked to above explains how my friendship table works, in case that help you help me with this.

Community
  • 1
  • 1
vertigoelectric
  • 1,307
  • 4
  • 17
  • 37
  • `MY_DATA_ACCESS_LAYER.IS_FRIEND(my_id, other_id)` -- Use the database. Love the database. Worry about "other stuff" later. (A trivial extension is to make it take in multiple ID's to process at once; the point is: if it's hidden in the DAL, it doesn't really matter and when -- but really *if* -- performance *is* an issue there are many ways to approach it.) –  Oct 08 '11 at 03:14
  • @pst, would you mind explaining that to me a little better? What exactly is `MY_DATA_ACCESS_LAYER.IS_FRIEND(my_id, other_id)` and how would I use it? Can you provide an example? – vertigoelectric Oct 08 '11 at 03:40
  • It is part of the DAL (Data Access Layer) and would "use the database". The name is atrocious and was chosen to stand out. Different frameworks will facilitate different DAL approaches, but it sounds like this is already present: That is, *don't* worry about the session or in_array stuff at all. Only worry about "limiting trivial DB usage" when there is a *proven* performance use-case that fails to meet requirements. –  Oct 08 '11 at 22:42
  • @pst, if I understand correctly, you're saying to go ahead and access the database as often as is necessary to check for friendships because it isn't a performance problem. Is that right? Well performance isn't what I'm worried about. It's convenience. I'd have a lot of extra big blocks of code all over the place any time I wanted to check for friendships and that just doesn't seem efficient to me. It feels like going back to the store to get each ingredient one at a time for a recipe when you're ready to add it to the pot rather than getting it all at once. – vertigoelectric Oct 09 '11 at 23:56
  • Note the use of a function to hide "how it does it" behind an API -- `IsFriend(myId, otherId)` -> returns true or false as appropriate. Simple. Pass in the id of the currently logged in user and the id of said comment(s). There is no problem here -- don't invent one. Using the database *avoids the need to do extra work and muck with the session at all*. –  Oct 10 '11 at 00:07
  • @pst, okay... but how do I create such a function? That's what I need explained... and out of curiosity, why are you posting as a comment and not an answer? – vertigoelectric Oct 10 '11 at 06:45
  • Also, I just noticed I lost 2 reputation points because I was downvoted for this question. Why? – vertigoelectric Oct 10 '11 at 06:47
  • Someone didn't like it ... sometimes they leave comments (I recommend to do so). "using SELECT subqueries to only get posts by friends of the current user." <-- *it's exact same thing*, only modified for this case (determining friendship) and depends on database schema as well as access method, etc. –  Oct 10 '11 at 20:19
  • Okay, well I figured out a single query that I can probably use throughout the site to test for friendships. I was hoping for something shorter, but this seems to work. Thank you. – vertigoelectric Oct 10 '11 at 21:31
  • I agree with the comment 'use the database, love the database'. But then he goes on to say you should shove it all in your DAL and forget about it. Using a single query with LEFT join would be a much better way to 'love your database', why ignore database indices and batter it with a heapload of single queries ? – carpii Oct 14 '11 at 01:59
  • @carpii, well, it sounds like you may have a better idea, but I have no idea what you're talking about, so it doesn't help me. In fact, nothing said on this page so far has been very helpful at all. The best I know to do at this point is run a DB query each time I want to check friendship between two users. – vertigoelectric Oct 14 '11 at 07:11

1 Answers1

0

Actually, it is a very bad idea to stor the friend array in the session. What happens if some you add a new friend after the session variable is created? It does not get updated in the session.

Since you will be checking the list of friends a lot of times on the same page, why not just query it out and store it in a local array that you can keep using on the same page.

When the page finish executing, the array will be discarded.

So basically, you will only query the list out once.

A recommended implementation would be to follow the advise of "pst" in the above comment, and just query for every time you need to find the relationship first, as that is simple to implement. Later, when the speed of the query starts to become a issue, you can just change the internal of that method to cache the friend list in a local array when it is first called to speed things up. (exchange memory usage for processor usage).

iWantSimpleLife
  • 1,944
  • 14
  • 22
  • Thanks for the reply. Well, as it is now, I have a query that checks the `friendships` table for an existing, valid match between two users. If the number of rows found is not zero, then a friendship is determined. To use the local array method, I'd need to change my query to pull all valid friendship matches from the table, and then test against that. I realize now that the array idea is less efficient. However, it brought up a question I have. Does there come a point in which you can query the database too often, or does that not really matter? – vertigoelectric Oct 14 '11 at 15:57
  • My take on that is that database query is getting cheaper, cpu power is getting cheaper. Basically, the capabilities of computers are getting cheaper every day. So the first thing you should be concerned with is to do the right thing. Get it working with the correct logic first. Then see if it needs to be optimised. If it runs fast without any optimisation, then you have just saves a lot of time. If it runs show, at least your codes are easily understood by anyone, because there is no weird logic to attempt to speed up the codes. It will make the codes easier to maintain and to optimise. – iWantSimpleLife Oct 18 '11 at 02:20
  • You will most likely need to write the codes, then bench mark it against real live conditions, then you can decide if the number of queries are too much. But as a rule of thumb, I try to stop at 50 queries per PHP page. – iWantSimpleLife Oct 18 '11 at 02:25
  • Thanks for your input. I've decided that I'd just go ahead and do whatever works, without worrying **too** much about perfect efficiency and optimization. I'm sure the site can support many users, and if we ever get millions of users, maybe it'll provide enough income to hire someone to optimize the code. – vertigoelectric Oct 18 '11 at 22:01
  • Hey @vertigoelectric, how about checking the the tread answered if you are satisfied. – iWantSimpleLife Oct 19 '11 at 09:09
  • I think storing the friendlist in something like Memcache or Redis in memory would be a good solution – JasonDavis May 08 '12 at 01:28