I don't see what extra protection storing an email as a separate entity buys you. If you store the same email address twice you do not get an exception thrown like in an RDBMS... it just silently overwrites the existing one. In either case, storing the email as a key or as a field, you would need to do a query (or get) in a transaction to be sure you were not going to overwrite an existing record with the same email.

On 23 Feb 2010, at 13:37, Jeff Schnitzer wrote:

I don't think we're disagreeing - user-defined keys are the only way
to enforce uniqueness.  I was just trying to point out that
user-defined longs work just as well for enforcing uniqueness as
user-defined Strings if your natural key is numeric.  There's no
reason to convert it to a String.

I don't personally think there's anything wrong with carefully chosen
natural keys.  Domain name in your example is a great natural key.

Accounts with an email address is a little weirder.  You want two
things:  Accounts should be able to change their email addresses (so
using the email as the Account key is a bad idea) but you also want to
enforce uniqueness of the email address field (users use it to log
in).  So the appropriate model for this in appengine is probably to
have Account and Email as separate entities, Account with a generated
id and Email with a tautological natural key.

...which provides one more illustration of why the JDO claim of
"transparent persistence" across multiple datastores is bogus.  You'd
never do this in an RDBMS.

Jeff

On Mon, Feb 22, 2010 at 8:09 PM, Max Ross (Google)
<[email protected]> wrote:
Jeff,

I agree with the majority of your design philosophy and the advice you're dispensing, but I still disagree with you on one pretty fundamental point.
If I'm understanding your argument correctly, you're saying that best
practices for primary key management don't involve user-defined strings, therefore user-defined strings aren't a necessary feature, but I think this ignores a pretty basic usage of uniqueness constraints. Let's say you're a domain registrar, you're building your registration workflow on App Engine, and you need to guarantee that a domain name can only be claimed once. If you use a numeric id mapped to the domain name you run the risk of letting two users reserve the same domain, and if you're a domain registrar that's really really bad. There's no natural key we can bring in here. Whether we as application developers run into them frequently or not, there exists a class of problems where a user-defined string pk is a necessary part of the
solution.

Regards,
Max

On Mon, Feb 22, 2010 at 1:52 PM, Jeff Schnitzer <[email protected]> wrote:

On Mon, Feb 22, 2010 at 1:19 PM, Max Ross (Google)
<[email protected]> wrote:

user-defined long-id keys are not quite as easily used. You either need
to
commit to not letting the datastore generate ids for that kind or you
need
to reserve a batch of ids using the DatastoreService.allocateIds method. Otherwise you run the risk of a silent collision. There is no such risk
with user-defined string keys.

Right, but if the user has a natural key (long, String, whatever) they
won't be using the generator anyways.  There are plenty of natural
long keys in the world... facebook userid being a popular one.

FWIW, Objectify makes the distinction between ids of type Long, which
can be null and thus autogenerated, and long (the primitive) which
cannot be autogenerated.  I really hadn't intended to plug Objectify
here, really!

Valid point about renaming, but going back to the example I provided,
the
datastore does not distinguish between inserts and updates. The only
way
you can guarantee that an entity was inserted, and therefore the only
way
you can guarantee the uniqueness of the name, is to use a user- defined
key.
If you're mapping id to name it will be possible to create two entities
with
the same name. It's of course up to you to decide how important this is
to
defend against, but without the ability to provide your own id you
wouldn't
get to make this choice, and without the ability to provide your own
string
id you wouldn't be able to add some application-specific meaning to this
choice.

I totally agree with you WRT user-defined vs generated values, I just
don't see anything wrong with using the long id as a user-defined
value.  Just make sure you never ask for a generated one.  Seems
pretty straightforward.

Jeff

--
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.


--
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.


--
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 .


--
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