Thanks Tristan
I like the idea of UserRegistrar class, may be i will use this to keep
the Friend relation.

But still worried about UserActivity as GAE doesn't support more then
30 parameters in contains query. So i will be able to query
UserActivity only for 30 users at one time(then run remaining in the
batch of 30 each) and then i will need to sort them in memory for
latest activities and it will not be scalable solution.So as Baz said
need to look into write once kind of solution. And make sure data is
not being duplicated a lot but i will just keep ids in every user's
activity table.
So something liek this
class Acitivty
{
Key id;
String status;
....
}

Class UserAcitivity{
Key id;
Key actitityId; //Id of Activity Class
Key userId; //Id of User Classm whome this UserActivity belongs
boolean myUpdate;//it will distinguish if this activity is mine or my
friends/some group etc
}

So basically if i want to update my status as "Hurray i got some
solution". Then i will create one row for class Activity where my
status will be saved.
Then i will create one row in UserActitvity where my userId,just
created activityId and myUpdate=true.
And say i have 500 Friends, then i will create 500 more rows with
userId as my friend's id, activityId as what i created above and
myUpdate as false;(And i hope i will be able to finish it before Big
Daddy DeadlineExceedException comes to me :) )

So when i want to see all updates including mine and friend's on my
wall, then i will query this table(UserActivity) with userId=myId
order by updationDate and according to my web page i may be interested
in top 30 or 50 or 100 results only and then for that i can lookup
Activity table to get exact data.
And if retrieval of data from Activity class is pain, then i may merge
it with the userActivity and duplicate the data like activityStaus in
500 rows(just to make retrieval faster).


Feel free to comment on this design.

(There is always a better solution)
Thanks,
Ravi.





On May 19, 1:13 am, Tristan <tristan.slomin...@gmail.com> wrote:
> What about doing this?
>
> Have your user activity object keep track of friends as well... So
> something like
>
> Class UserActivity
> {
> Key id;
> String statusMessage;
> Date time;
> User user;
> List<Key> friends
>
> }
>
> Then when you want to display the "wall", you just query all User
> Activity objects that have your user in it. (for one, I would not user
> List<Key> because you have a potential of running out of space, ie >
> 1MB and then you start getting errors, but it's a design decision).
> But the above saves you a lot of time... because when User Activity is
> generated by user1 (who is friends with user2), you just copy the
> user1's friend list into it while you're creating it, so just 1 write
> operation. Then if you're user2 and want to see your wall, just run a
> query against User Activity where friends = user2Key. 1 query
> operation.
>
> As far as how to be friends of friends, instead of storing the
> relationship in your User object, have something like UserRegistrar
> that is essentially this:
>
> UserRegistrar {
> List<Key> users
>
> }
>
> Most of the time you will just have 2 users in that list, but what
> that buys you is being able to do 1 write and document relationship
> going both ways. Then if you want to find friends of user2, you just
> query UserRegistrar where friends = user2. When you have all those,
> combine the list and every user listed (except listing of user2) is a
> friend of user2. So again, 1 query operation.
>
> On May 18, 1:47 pm, Baz <b...@thinkloop.com> wrote:
>
>
>
> > I think you're best bet is to do all the work in the write, and have each
> > profile's page constantly updated and ready for an extremely simple read.
> > For one, this will significantly reduce your costs, because everyone reads
> > more than they write. Two, by the time you get big enough to surpass the 30
> > second limit, you will probably be able to use "Background servers capable
> > of running for longer than 30s" 
> > (http://code.google.com/appengine/docs/roadmap.html)
>
> > Cheers,
> > Baz
>
> > On Tue, May 18, 2010 at 8:43 AM, Ravi <ping2r...@gmail.com> wrote:
> > > Thanks Li for looking into it.
> > > For me 1-2 minute delay is fine, problem is like contains query(for
> > > finding friend's data), i can pass max 30 user id, so basically on one
> > > page i will be able to show max 30.
> > > But in other case where wall type data need to be saved queries need
> > > to perform faster and need to break the limit of 30 as i would like to
> > > get latest activity from all of my friends rather then first 30
> > > friends. So if i have 300 friends i may need to run such query 10
> > > times in the batch of 30 nad each time need to go through activties
> > > and sort them out which will be very time consuming and sure user will
> > > not like the response time.
> > > I am thinking why not do it at the write time that my updates goes to
> > > all of friend's domain but again in one 30 second request i will try
> > > to create/update my domain(user Data) + 300(assuming i have 300
> > > friends) other domains. I am not sure how it will perform.
>
> > > But i would love to see some solution where write is less and still
> > > read is faster like any other site(facebook/twitter etc)
>
> > > Ravi.
>
> > > On May 18, 4:31 pm, Yiming Li <yiming...@umail.ucsb.edu> wrote:
> > > > This is an interesting problem, I am not an expert on database design,
> > > > especially key-value based datastore,  but I will try to answer this
> > > > question.
>
> > > > For me, the design like
> > > > Class User{
> > > > Key id;
> > > > String name;
> > > > String email;
> > > > List<key> friends.
> > > > ...etc}
>
> > > > makes perfect sense, and as you said, you can do more query on
> > > > something like "UserActivity" or "TimeBecomeFriends", with
> > > > "user1Id=<userId> or user2Id=<userId>". approach. I am also fine with
> > > > it.
>
> > > > How big is your application? I think a good design is relevant to the
> > > > scalability, and we are always trading storage space with query time.
>
> > > > Another thing maybe useful is memcache, using it may lead to a gain in
> > > > performance, although it may bring a bit data inconsistency,  however
> > > > I think it's ok. For example, it should be fine if you see your
> > > > friends' latest post 1 minute later.
>
> > > > Maybe there is some paper talking about datastore design for scalable
> > > > applications? Not sure.
>
> > > > Thanks
>
> > > > On Tue, May 18, 2010 at 7:58 AM, Ravi <ping2r...@gmail.com> wrote:
> > > > > Hi,
> > > > > I am trying to design a website like Facebook, where user will have
> > > > > friends and will have wall where they can see there friend's updates
> > > > > etc. While designing it on GAE i got confused with what will be the
> > > > > best approach like data duplicate, data read time or data write time
> > > > > etc
>
> > > > > Friend's Design:
> > > > > I thought there will be User and User will be friend with another
> > > > > User.
>
> > > > > Class User{
> > > > > Key id;
> > > > > String name;
> > > > > String email;
> > > > > ...etc
> > > > > }
>
> > > > > Now i definitely can not have owened relatioship with Friends means I
> > > > > can not have List<User> friends in my User Class as it will not be
> > > > > same domain(User) data, so i thought ok i will have List<Key> or
> > > > > List<Long> User Ids as Friends
> > > > > Class User{
> > > > > Key id;
> > > > > String name;
> > > > > String email;
> > > > > List<key> friends.
> > > > > ...etc
> > > > > }
> > > > > And confusion/problem begins.
> > > > > First a Friendship is supposed to be from both side, so it should be
> > > > > defined only once but in this design both Friends will have each
> > > > > other's id in there friend list. Basically its not a typical
> > > > > relationship. What if i want to keep friendship info like when it
> > > > > started, who introduced etc. Then i may need to create a new Friend
> > > > > class with two fields as user1Id and user2Id and query this class with
> > > > > user1Id=<userId> or user2Id=<userId>. But not sure about this
> > > > > approach.
> > > > > Second i am doing data duplicate(but i am fine with it if it can be
> > > > > proved as best solution).
> > > > > Third: I am showing one user's profile and want to show his friends on
> > > > > one page, so first i need to get the User and its Friend List<Key>
> > > > > then i need to search User for each and every Id to get each user's
> > > > > data(like name.profile id and photo). For me it seemed bit longer
> > > > > process.Not sure how queries will perform.
> > > > >  Pseudo Code will be like this
> > > > >   > Get Logged In User
> > > > >   > Loop through friends field
> > > > >        >Begin
> > > > >          get User for each iterated Friend Id.
> > > > > //and if we want to show how many friends that user have, then i will
> > > > > be accessing friend list for each friend,so there will be lot of data
> > > > > read from database.
> > > > >        >End
> > > > > put all data in jsp to compile and show it to user.
>
> > > > > Other design problem related to wall like Facebook wall/profile,
> > > > > Lets say i have UserActivity class to keep track of User's Activity
> > > > > and that can be owned by User, so User class can look like
> > > > > Class User
> > > > > {
> > > > > Key id;
> > > > > String name;
> > > > > String email;
> > > > > List<Key> friends//assume we are going with this kind of design
> > > > > List<UserActivity> activities
> > > > > }
>
> > > > > Class UserActivity
> > > > > {
> > > > > Key id;
> > > > > String statusMessage;
> > > > > Date time;
> > > > > User user;
> > > > > }
>
> > > > > Now i want to show all activities of a user to him/her order by
> > > > > time(recent first/on the top).
> > > > > Now again i see one way of doing it as get all the Friend's id from
> > > > > List<Key> friends field, query all User data then go through
> > > > > UserActivity and get all data in memory and sort it out. This seems
> > > > > not a good option to me.
> > > > > How can i solve this problem efficiently and design a good solution.
>
> > > > > Thanks in advance
> > > > > Ravi.
>
> > > > > --
> > > > > You received this message because you are subscribed to the Google
> > > Groups "Google App Engine for Java" group.
> > > > > To post to this group, send email to
> > > google-appengine-j...@googlegroups.com.
> > > > > To unsubscribe from this group, send email to
> > > google-appengine-java+unsubscr...@googlegroups.com<google-appengine-java%2B
> > >  unsubscr...@googlegroups.com>
> > > .
> > > > > For more options, visit this group athttp://
> > > groups.google.com/group/google-appengine-java?hl=en.
>
> > > > --
> > > > Yiming
> > > > MS student of CS Department @UCSB
>
> > > > --
> > > > You received this message because you are subscribed to the Google 
> > > > Groups
> > > "Google App Engine for Java" group.
> > > > To post to this group, send email to
> > > google-appengine-j...@googlegroups.com.
> > > > To unsubscribe from this group, send email to
> > > google-appengine-java+unsubscr...@googlegroups.com<google-appengine-java%2B
> > >  unsubscr...@googlegroups.com>
> > > .
> > > > For more options, visit this group athttp://
> > > groups.google.com/group/google-appengine-java?hl=en.
>
> > > --
> > > You received this message because you are subscribed to the Google Groups
> > > "Google App Engine for Java" group.
> > > To post to this group, send email to
> > > google-appengine-j...@googlegroups.com.
> > > To unsubscribe from this group, send email to
> > > google-appengine-java+unsubscr...@googlegroups.com<google-appengine-java%2B
> > >  unsubscr...@googlegroups.com>
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/google-appengine-java?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "Google App Engine for Java" group.
> > To post to this group, send email to google-appengine-j...@googlegroups.com.
> > To unsubscribe from this group, send email to 
> > google-appengine-java+unsubscr...@googlegroups.com.
> > For more options, visit this group
>
> ...
>
> read more »

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine for Java" group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.

Reply via email to