[Seaside] Re: Seaside and GOODS

David Shaffer cdshaffer at acm.org
Sat Mar 19 16:45:24 CET 2005

>On Fri, 18 Mar 2005 17:43:42 -0500, Daniel Salama <dsalama at user.net> wrote:
>>db root at: 'people' put: people.
>>db root at: 'lastNames' put: lastNameIndex.
>>person := Person new; firstName: 'Daniel'; lastName: 'Salama'.
>>people at: 'some_magical_key_like_an_oid' put: person.
>>lastNameIndex at: (person lastName) put: person.
>>db commit.
>>Basically, I create one person object and store it twice in the
>>database. However, from your previous answers, only one instance of the
>>object is actually stored. The other one is simply a reference.
>>Are my assumptions correct? Is what I did correct?
I'm jumping in kind of late and didn't read the whole thread (sorry).  I 
just want to add to Avi's comment.  I have managed to get away with very 
few "indices" in every Seaside app I've written.  In fact, most have 
only one or two such things.  Users keyed by username is the only one 
that appears in all of my applications.  From the user I simply navigate 
to the objects I want.  Generally I don't find that I need to search 
_large_ collections of things very often.  For small collections I just 
do things like:

people detect: [:person | person lastName = 'Salama'] ifNone: []

which works fine even in GOODS as long as the people collection is small 
(<200 elements is my standard benchmark).  Maybe this sounds silly but 
most of the time you arrive at a collection by navigating object 

self currentShopper orders detect: [....]

so by the time you get to a leaf that's a collection there aren't many 
items to search through.  Basically I advise you to index only when 
absolutely necessary (for the reasons that Avi's already given you).  
And in those cases try to stick to indices with invariant keys since 
maintaining and index whose keys change can really pollute your 
persistent objects.  Let me carry the order example further...if you 
want to support customers with hundreds of orders you're done (its 
already fast enough).  If you need to deal with thousands of orders then 
you begin studying your "detect:" blocks.  What are your searches based 
on?  If its always the same invariant key change to a TSTree and you're 
done.  If you're searches vary widely consider refactoring your 
objects.  Finally, if refactoring doesn't seem warranted to support this 
search, go with index maintenance.  My extremely limited experience is 
that you don't get that far very often.

As Avi pointed out this is very different than the typical relational 
approach where relationships are maintained through foreign keys.  I 
wouldn't ever, for example, need to index all of the orders in my system 
on the name of the customer that owns the order.  The relationship is 
maintained in the objects themselves.  Also, I would also never (in 
Seaside) pass a foreign key of an object to a callback.  For example 
here's how I'd write a "choose your order" view (in renderContentOn:):

self currentShopper orders orderedListDo: [:order |
    html anchorWithAction: [self orderSelected: order] text: order 

Notice that I don't pass a key for the order to the callback, I pass the 
order itself.  This is very different from your typical 
JSP/PHP/ASP/mod_perl/whatever application where your links carry keys 
for objects, not the objects themselves.  As an exercise I'd try to 
create your application with almost no indices and follow the 
prescription above.  If you can't get the performance you need then 
ignore my comments from now on :-)

Again, I'm sorry if this was a repeat of a previous post.  I hope there 
is something usefull in it.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/seaside/attachments/20050319/a92cb2ca/attachment-0001.htm

More information about the Seaside mailing list