On Oct 19, 2008, at 11:34 PM, Antony Blakey wrote:
3. Use couchdb in a single-writer multiple-reader scenario. If you
only do that for those activities that require uniqueness then you
have consistency issues to deal with because replication is
asynchronous. One way to do that is to switch a session to the
writable server as soon as you need uniqueness. The single writer
becomes a bottleneck, but this is what I'm doing because it matches
my information architecture.
4. Use a central specialized server to check uniqueness and generate
an opaque userid token that you would subsequently use as a key (you
shouldn't use the username as a key). An ldap server or something
like it. Equivalent to the option above, but the single server only
needs to deal with the particular operations requiring uniqueness.
It's still a single point of failure, but I don't think you can get
around that if you want synchronous global uniqueness testing.
you know, thinking about this further is causing me to wonder if even
that'd do it. consider a single write master an attempting to check
if a given login is unique, with couch there no way to ensure that two
keys are unique other than using said key as the _id for the doc.
it's possible that'd work in some cases, but consider
user
login : string (unique)
password : string
email: string (unique)
and it suddenly becomes difficult again - we cannot ensure both are
unique with an atomic test/set. we cannot simply combine them as a
key because
login: foo
email: [EMAIL PROTECTED]
and
login: bar
emai: [EMAIL PROTECTED]
would become a unique pair. rather we'd have to do something like
keep a master index of all docs - or perhaps just a blank doc (index)
mapping emails to users and bulk update the pair of them together.
so there are probably solutions lurking, but all of them seem very
complicated to allow something as simple as allowing a user to have a
simple piece of memorable information to enter and have an application
respond by mapping that directly to the user's data.
obviously we can solve the issue with multiple writes and reads
combined, but that's not particularly good if other applications might
be using this data actively (which is of course the case with a single
writer).
to summarize the problem - what's the preferred method of ensuring
that a field of a couchdb doc is unique across all docs if that key
cannot be the _id itself? is the only method to write it, process a
view to find all docs which might have a duplicate field, and then
possibly to delete the original? it's all i imagine now but that's
pretty tricky in a high concurrency situation because of the mutually
destructive race condition what proceeds:
a - write doc with foo=bar
b - write doc with foo=bar
a - read list of all docs where foo==bar
b - read list of all docs where foo==bar
a - decide ours was a dup. destroy it. report error to user
b - decode ours was a dup. destroy it. report error to user.
which is full of messiness if the network or db goes down but, most
importantly, can fail even when it's up.
what am i missing when it comes to attempting to model a doc field
which should contain a unique value?
cheers.
a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama