Consider this test case.  A Person belongs to 1 or more Institutions
so there's 2 ways you would want to query this.  Query #1: Given a
particular Person then which Institutions does he belong to?  Query
#2:  Given a particular Institution then which Persons are members?

Assume entity Person and its associated child relations will form its
own entity group and, likewise, entity Institution will form its own
entity group related to its children.  In order to accommodate large
amounts of Person and Institution data, I submit that you would need
"owned" relations of each.

Therefore, you would need entity PersonInstitutions as an owned child
relation with Person for Query #1.  Similarly, you would need entity
InstitutionPersons as an owned child relation with Institution for
Query #2.

Also, each of these 2 child entities would contain both a PersonFK and
a InstitutionFK with appropriate redundant fields ancillary to the
query requirement of the app.  Again, the embedded FK class avoids
extra queries that would kill search list performance, etc.  For
example with Query #2, give me all persons at Baylor that have first
name James would only need the entity InstitutionPersons.

So, we accept the fact the design requires redundant data in the
embedded FK class but at least from a source code perspective we only
have FK class to manage.

Is it correct that we would need both "owned" relations or not?  Say
you had Persons and Institutions from around the world.  I can't
imagine satisfying the above 2 queries without both "owned"
relations.  Of course, this means updates to both relations are across
2 entity groups and separate transactions.  Another fact we have to
accept in the design right?

On Nov 3, 2:22 pm, James H <james.hollier...@gmail.com> wrote:
> Ok Bryce...I'm back.  Going to test with your ideas now.  In my case,
> I tend to avoid generic column names like "id" in favor of "bookId"
> and "chapterId" so I should not have any naming conflicts (at least
> rarely).  Also, my FK embedded classes should not have any collections
> though I have a feeling they may come up as I get further into it.
>
> I'll just test with Book and owned relation Chapter as you have it
> here.  How do we tell JDO whether a relation is "owned" vs "unowned"
> by the way?  Because I would like to have a child object of each for
> the testing.  Thanks!
>
> On Oct 9, 12:06 pm, bryce cottam <bcot...@gmail.com> wrote:
>
>
>
> > FYI, this video was hugely helpful for me, and this information helps
> > me decide how to structure my data model to run best on the
> > app-engine, it's a Google I/O session on how the app-engine big table
> > implementation works:http://www.youtube.com/watch?v=tx5gdoNpcZM
>
> > On Fri, Oct 9, 2009 at 10:46 AM, James H <james.hollier...@gmail.com> wrote:
>
> > > Ylmz, thats how I see it too.  Any significant data model will be
> > > riddled with FKs and since GAE datastore does not support Joins you
> > > have NO choice but to denormalize your data to meet the needs of your
> > > app queries.  The Cottam Pattern above allows best management of
> > > source to accomplish this denormalization.
>
> > > I assume the simple example you are referring to either only stores
> > > the Keys in the physical table (which would be insufficient for app
> > > queries) or stores the whole record (which would be massive overkill).
>
> > > Does that make any sense?
>
> > > On Oct 8, 4:46 am, bryce cottam <bcot...@gmail.com> wrote:
> > >> yes, I think the point that we are making is that we are trying to
> > >> managed "un-owned" relationships  :)
> > >> You are describing owned relationships, which I use as well, but in
> > >> many cases, I really want un-owned relationships.  For a variety of
> > >> reasons really, one of which is that the children I have in my
> > >> collection get get rather big, and there is a cap on the number of
> > >> writes that can happen on an entity group.  So, in come cases it's
> > >> better to model the relationships as foreign keys.
>
> > >> The problem comes in when you try to manage your data.  It's a pretty
> > >> common suggestion from the app-engine team to denormalize, we're just
> > >> trying to come up with a way to denormalize and minimize code
> > >> duplication etc.  Denormalizing will let you query better/faster etc.
> > >> but can create headaches when trying to update a single field which is
> > >> mirrored on several other entities.
>
> > >> For instance, you could have an Employee that works for several
> > >> departments in a company.  It's the same Employee, so it should be a
> > >> single record.  So, in this case you'd have a Company, Division and
> > >> Employee.  A Company "owns" it's Divisions and it also "owns" it's
> > >> Employees, yet a Division "owns" it's Employees as well.  So, where
> > >> does the collection of Employees live?  On the Company, or the
> > >> Division?  If it's the Division, then you can't share employees with
> > >> other divisions (unless you duplicate the Employee record).  If the
> > >> Company owns the Employee, then you have to make some way for the
> > >> Division to know who's in it.  You could do this by putting a
> > >> collection of Division Key objects on an Employee record, or a
> > >> collection of Employee Keys on a Division record.  Yet, this doesn't
> > >> allow for simple querying, like "select all employees that work in a
> > >> division located in New York and has less than 20 people in it".  Or,
> > >> "select all divisions who have an employee named Fred".
>
> > >> you can do queries like this if you denormalize the data though  :)
>
> > >> On Thu, Oct 8, 2009 at 3:35 AM, ylmz <yilmazhuse...@gmail.com> wrote:
>
> > >> > may I suggest different kind of desing
> > >> >http://code.google.com/appengine/docs/java/datastore/relationships.html,
> > >> > in this document it suggests to use collection types to design one to
> > >> > many relation ships.
> > >> > and it works pretty well actually. when you use a collection type. app
> > >> > engine does not really use the original colection type you used.
> > >> > instead
> > >> > it uses its own replacement. so if you want to add a new employee to
> > >> > the company you just add a new one to the list. it automatically added
> > >> > to datastore.
> > >> > and if I understand right, when you get a company you dont get all the
> > >> > employees inside. you only get a collection type which is actulally
> > >> > empty but look like it has employees inside.
> > >> > so when you get any element from collection type
> > >> > it pulls that record from datastore.
> > >> > there is also some collection types that excepts unique values.
> > >> > Is there a spesific reason you don't use collections that I didn't
> > >> > understand?
>
> > >> > On Oct 7, 4:16 am, James H <james.hollier...@gmail.com> wrote:
> > >> >> Wow, this is majorly useful...can't wait to try it out!!!  For the
> > >> >> life of me I can't figure out why this problem domain has NOT already
> > >> >> been exhausted in this Group since denormalization is a requirement
> > >> >> with this technology for any significant business application!
>
> > >> >> I believe your example should be placed in a section on how to handle
> > >> >> Advanced Relations w/Denormalization in this section of the docs:
>
> > >> >>http://code.google.com/appengine/docs/java/datastore/relationships.html
>
> > >> >> Great work, Bryce!  I'll see if I can break it :)
>
> > >> >> As for our other achilles' heel, that being Distributive
> > >> >> Transactions...do you think the Open Source team will deliver any time
> > >> >> soon?  I worry about contention in that solution since everything is
> > >> >> concentrated into 1 table - the DT instruction table...  Meanwhile,
> > >> >> I'm thinking about queuing 2nd and N-phase transactions to the Task
> > >> >> Queue, yep its a bandaid.
>
> > >> >> On Oct 6, 6:29 pm, bryce cottam <bcot...@gmail.com> wrote:
>
> > >> >> > oh, I should clarify, the @ReferencedField, is an annotation I 
> > >> >> > wrote,
> > >> >> > it's not part of any library or anything:
> > >> >> > @Retention(RetentionPolicy.RUNTIME)
> > >> >> > @Target({ElementType.FIELD, ElementType.METHOD})
> > >> >> > public @interface ReferencedField {
> > >> >> >         public String srcField();
>
> > >> >> > }
> > >> >> > On Tue, Oct 6, 2009 at 5:19 PM, bryce cottam <bcot...@gmail.com> 
> > >> >> > wrote:
> > >> >> > > Thanks for the update Diana,
> > >> >> > > I hadn't thought to look in this forum for a "series"  nice moves 
> > >> >> > >  :)
>
> > >> >> > > I've gotten some pieces of this to work out well so far.  This is 
> > >> >> > > an
> > >> >> > > overview of what I have (using the Book/Chapter example)
>
> > >> >> > > @PersistenceCapable(identityType=IdentityType.APPLICATION,
> > >> >> > > detachable="true")
> > >> >> > > public class Book {
>
> > >> >> > >   �...@primarykey
> > >> >> > >   �...@persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
> > >> >> > >    private Key id;
>
> > >> >> > >   �...@persistent
> > >> >> > >    private String title;
> > >> >> > >   �...@persistent
> > >> >> > >    private String isbn;
>
> > >> >> > >    // getters and setters
> > >> >> > > }
>
> > >> >> > > @PersistenceCapable(detachable="true")
> > >> >> > > public class BookFK {
> > >> >> > >     �...@persistent
> > >> >> > >      private Key id;
> > >> >> > >     �...@persistent
> > >> >> > >      private String title;
> > >> >> > >     �...@persistent
> > >> >> > >      private String isbn;
> > >> >> > >     // getters and setters
> > >> >> > > }
>
> > >> >> > > @PersistenceCapable(identityType=IdentityType.APPLICATION,
> > >> >> > > detachable="true")
> > >> >> > > public class Chapter {
> > >> >> > >   �...@primarykey
> > >> >> > >   �...@persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
> > >> >> > >    private Key id;
>
> > >> >> > >   �...@persistent
> > >> >> > >    private String title;
> > >> >> > >   �...@persistent
> > >> >> > >    private int numPages;
>
> > >> >> > >   �...@persistent
> > >> >> > >   �...@embedded
> > >> >> > >    private BookFK book;
>
> > >> >> > >    // getters and setters
> > >> >> > > }
>
> > >> >> > > so, this looks promising, but we still have the problem of name 
> > >> >> > > collissions
> > >> >> > > (the "title" and "id" fields in this case).
> > >> >> > > in order to resolve this, we put a "members" field in our 
> > >> >> > > @Embedded
> > >> >> > > annotation.  However, I've noticed that JDO seems to like it 
> > >> >> > > better if you
> > >> >> > > itemize all fields of an embedded class if you itemize any of 
> > >> >> > > them:
>
> > >> >> > >   �...@persistent
> > >> >> > >   �...@embedded(members= {
> > >> >> > >         �...@persistent(name="id", 
> > >> >> > > colum...@column(name="bookId")),
> > >> >> > >         �...@persistent(name="title", 
> > >> >> > > colum...@column(name="bookTitle")),
> > >> >> > >         �...@persistent(name="isbn")
> > >> >> > >     })
> > >> >> > >    private BookFK book;
>
> > >> >> > > either that, or we need to rename the fields in our BookFK class:
>
> > >> >> > > public class BookFK {
> > >> >> > >     �...@persistent
> > >> >> > >      private Key key;
> > >> >> > >     �...@persistent
> > >> >> > >      private String bookTitle;
> > >> >> > >     �...@persistent
> > >> >> > >      private String isbn;
> > >> >> > > }
>
> > >> >> > > I lean towards the latter when it's simple (like in the "id" vs 
> > >> >> > > "key"
> > >> >> > > example.  The idea here, is that you're going to be querying on 
> > >> >> > > these
> > >> >> > > fields, so you probably doing want to make them hard to remember. 
> > >> >> > >  It'd be
> > >> >> > > great if you could always have the fields in the FK class be the 
> > >> >> > > same name
> > >> >> > > as the fields in the mirrored Entity class.  Then you'd have 
> > >> >> > > queryies like
> > >> >> > > this:
> > >> >> > > select from Chapter where book.id = 1234 and book.title = "The 
> > >> >> > > Art of JDO on
> > >> >> > > the App-Engine"
> > >> >> > > but in our (my)
>
> ...
>
> read more »- Hide quoted text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
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-java@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