Thanks a lot Tristan,
yes i did misunderstood you. Thanks for clarification.
Yes this way it will work.One row update and all friends can see the
data.

Once again Thanks a lot Tristan, you saved me some hassle and few GB
of space.

One last question on this thread.

Now my UserActivity will have different extensions.(Just going object
oriented).

I may create classes like (I will keep only friends info in
UserActivity and key info but not anything related to what activity
was, like status or video or photo etc)

class StatusUserActivty extends UserActivity{
String status;
}

class CommentUserActivity extends UserActivity{
Key receiverUserId;                 //User id where i commented
String comment;
}

class NewFriendUserActivity extends UserActivity
{
Key newFriendId;
}

class VideoUserActivity extends UserActivity{
String videoUrl;
String videoType;//may be like youtube or any other site, so that i
can show it properly on webpage
}

class PhotoUserAcitivity extends UserActivity{
int numberOfPhotos;
List<Key> photoIds;
Key albumId;
}


So now should i be able to query all UserActivity like
select UserActivity from UserActivity where UserActivity='MyUserId".

And i should be able to receive all different kinds of activity. I
think this kind of inheritance is not supported in GAE. I don't know
what options are there for such things.


Thanks,
Ravi










On May 19, 4:39 pm, Tristan <[email protected]> wrote:
> I think you misunderstand what I proposed
>
> Class UserActivity {
> Key id;
> Key activityId; // id of activity class
> Key userId; // id of User class whom this user activity belongs to
> --- vvv ADD THIS vvv ---
> List<Key> friendIds; // list of all of userId's friends
>
> }
>
> When you create an update to your status "Hurray I got some solution",
> you wil create one row for class user activity where your status will
> be saved (and that row will have a list of all your friend ids in it).
> That's it.. stop adding 500 rows, you don't need them. (you need to
> put a list of all of your friends into every activity you create)
>
> When your friends look at their wall, you just query UserActivity
> where friendIds = friendId. (list query returns true if one of the
> items in the list equals friendId). This will give them your update
> because they are contained in friendIds list of that user activity.
>
> Another way of saying this. Stop looking at it from perspective of
> distributing the information all over the place when you create it.
> Instead, via friendIds list, you are marking that activity with the
> people who have access, and then when they ask for their "wall", they
> say "give me all activities I have access to arranged by date".
>
> On May 19, 9:42 am, Ravi <[email protected]> wrote:
>
>
>
> > 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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
>
> ...
>
> 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 [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.

Reply via email to