Return-Path: Delivered-To: apmail-couchdb-user-archive@www.apache.org Received: (qmail 44476 invoked from network); 12 Nov 2009 23:19:31 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 12 Nov 2009 23:19:31 -0000 Received: (qmail 30451 invoked by uid 500); 12 Nov 2009 23:19:30 -0000 Delivered-To: apmail-couchdb-user-archive@couchdb.apache.org Received: (qmail 30368 invoked by uid 500); 12 Nov 2009 23:19:30 -0000 Mailing-List: contact user-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@couchdb.apache.org Delivered-To: mailing list user@couchdb.apache.org Received: (qmail 30358 invoked by uid 99); 12 Nov 2009 23:19:30 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 12 Nov 2009 23:19:30 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of jchris@gmail.com designates 209.85.216.178 as permitted sender) Received: from [209.85.216.178] (HELO mail-px0-f178.google.com) (209.85.216.178) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 12 Nov 2009 23:19:19 +0000 Received: by pxi8 with SMTP id 8so1916343pxi.27 for ; Thu, 12 Nov 2009 15:18:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:in-reply-to :references:date:x-google-sender-auth:message-id:subject:from:to :content-type:content-transfer-encoding; bh=WcKFyyWvjSZCYn45Xg+qHMZB0J2vNqabguGFofsLECY=; b=WTSFVFzZxhDxRtngjrobemnq/IuqyZ9uncG/9wegmZzGqFIWQEqZ7vLAkbYOhjc9SU W2wuPRcvPa2ARcKcwAyMgdSaB9p+mvSZ7MaMXOSTl2uE3YjxxJggGZm7SMRxt6ESDGlQ +HIQGls2X8X4wp/isegw4+U51WhVZDaDeYyiw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:content-type :content-transfer-encoding; b=u6KN4fZgp1O27Lo9NxM9Of353ULHnCjIR5E9XYv4L5gJ5jeR0hQarIfDYioKGy6TRy HcogCXQ6OwEv3xjaSqQ2GB/1yMdHjW/gSuFi+hV39HQXS2k38WsPJxQCOqL0GmIvzlq5 2dO2Wn97ZLpsPSBEtr4NZefYhdYtsakyzAeDE= MIME-Version: 1.0 Sender: jchris@gmail.com Received: by 10.142.62.12 with SMTP id k12mr409413wfa.138.1258067937475; Thu, 12 Nov 2009 15:18:57 -0800 (PST) In-Reply-To: <0AA4B724-EEF1-4959-8B67-420C6F1D298F@apache.org> References: <9b1d06140911111700k43d3f23eob40bf63fd1d43521@mail.gmail.com> <9b1d06140911111959g7f12f54fm853e14d15b6eb477@mail.gmail.com> <0AA4B724-EEF1-4959-8B67-420C6F1D298F@apache.org> Date: Thu, 12 Nov 2009 15:18:57 -0800 X-Google-Sender-Auth: 7ca5696fbdc2c981 Message-ID: Subject: Re: Ensuring unique attributes across documents? From: Chris Anderson To: user@couchdb.apache.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Virus-Checked: Checked by ClamAV on apache.org On Thu, Nov 12, 2009 at 3:06 PM, Jan Lehnardt wrote: > > On 12 Nov 2009, at 23:43, Zachary Zolton wrote: > >> Sure, you could even maintain a database just for uniqueness, with >> strings like "attr_name-attr_value" as the doc IDs. >> >> BUT, you still have problems: >> =A0* Writing multiple docs leaves an open window for race conditions >> (not so bad really) >> =A0* Any other server you replicate from may have already accepted a >> doc with that ID >> >> You can avoid this by only writing to a single master database, but >> you should be aware that you're introducing a Single Point of Failure. >> At that point you could even consider using a transactional RDBMS to >> allocate the unique values. > > or a lightweight redis store. If I'd go for the SPOF route, I'd build the > most lightweight solution possible. > > Cheers > Jan > -- > Let's remember that document ids are a great way to enforce uniqueness. You just have to remember when you use them, that you should namespace yourself so you aren't incompatible with data-merges (replication) with other systems. So something like com.example.user:jchris instead of just user:jchris Using docids will mean collisions are eventually detected on clusters, which is probably better than using uuids + secondary attributes in a view query. I know this doesn't solve the 2-values problem, but before people get carried away with uniqueness servers etc, do try to think about if you can model it with a single uniqueness constraint. Chris > > >> >> --Zach >> >> On Thu, Nov 12, 2009 at 3:46 PM, Adam Wolff wrote: >>> Put a separate document under the email address that refers to the user= name. >>> Use view collation to build the user record. >>> >>> A >>> >>> On Wed, Nov 11, 2009 at 7:59 PM, Cory Nelson wrote: >>> >>>> Indeed, that would be great if there were only one piece of data to >>>> keep unique. =A0In fact, I'm already doing that for the user name. =A0= But >>>> what about the email? >>>> >>>> I guess this could really be made into a more generic question: how do >>>> you create or alter one document only if pre-conditions are met in >>>> other documents, in a way that doesn't risk permanent inconsistencies >>>> if the database or client crash, or with partitioning? >>>> >>>> Or alternately: is this merely a design that worked in transactional >>>> dbs but doesn't translate to something like CouchDB? =A0If so, what's >>>> the recommended way to handle things like this? >>>> >>>> Thanks! >>>> >>>> On Wed, Nov 11, 2009 at 6:14 PM, Zachary Zolton >>>> wrote: >>>>> You COULD use the User document's ID to ensure uniqueness. The second >>>>> PUT to the same database URL would result in an HTTP 409 status code. >>>>> >>>>> Here it is on StackOverflow: >>>>> >>>> http://stackoverflow.com/questions/1058258/does-couchdb-support-unqiue= -key-constraint >>>>> >>>>> >>>>> On Wed, Nov 11, 2009 at 7:00 PM, Cory Nelson wrot= e: >>>>>> Hello, >>>>>> >>>>>> I'm trying to implement a typical user signup operation: when you >>>>>> finally add a user to the database, you want it to have both a uniqu= e >>>>>> user name, and a unique email. =A0In SQL I'd do something like: >>>>>> >>>>>> BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE >>>>>> >>>>>> count =3D SELECT COUNT(*) FROM t_users WHERE name=3D? OR email=3D? >>>>>> >>>>>> if(count =3D=3D 0) >>>>>> { >>>>>> INSERT INTO t_users VALUES(...) >>>>>> COMMIT >>>>>> } >>>>>> else >>>>>> { >>>>>> ROLLBACK >>>>>> } >>>>>> >>>>>> Can anyone give an example of how to achieve the same thing in Couch= DB? >>>>>> >>>>>> -- >>>>>> Cory Nelson >>>>>> >>>>> >>>> >>> >> > > --=20 Chris Anderson http://jchrisa.net http://couch.io