Re: Generating unique values for TEXT columns - Mailing list pgsql-general

From Pierre-Frédéric Caillaud
Subject Re: Generating unique values for TEXT columns
Date
Msg-id opsj1h4vwecq72hf@musicbox
Whole thread Raw
In response to Re: Generating unique values for TEXT columns  ("Frank D. Engel, Jr." <fde101@fjrhome.net>)
List pgsql-general

> If this is done as a stored procedure, won't transaction semantics
> prevent it from being a problem when two transactions attempt this
> simultaneously?  I'd thought that the output of one would become the
> input of the other (in essence, in terms of database state)?

    Well, for this you need to use a sequence somewhere, or be prepared to
retry on error.

    Same thing for :
- read key entered from user
- check if it's in the db
- if it's not, then insert

    Is not safe because somebody else may have entered the same key between
the check and the insert. So in a sense the check is useless : just insert
and see if it fails or not. However, the 'max' thingy is guaranteed to
step on other's toes if used concurrently. Which is a lot worse.

    Generally, when you design for concurrent systems, you have two choices :
- use a system primitive that supports concurrency and does almost what
you want, and add a thin layer of code on it (like, putting auto and user
generated keys in separate keyspaces by using different prefixes)
- try to design a primitive yourself ; which is generally complex because
you'll have to lock, unlock, and manage concurrency yourself. So unless
there is no other way, this is a slippy slope !

    That's why the 'max' solution looks nice, but in fact does not work ;
while the 'prefix' solution looks a bit uglier, but it works, and in fact
it's nicer because it also memorizes whereas the key was generated or not.

>
>
> On Jan 3, 2005, at 12:25 PM, Pierre-Frédéric Caillaud wrote:
>
>>
>> SELECT max, then treat the string as a sequence of characters and
>> increment the last character, rippling the carry if there is one :
>>
>> carry = 1
>> l = len(s)-1
>> while carry and l>=0:
>>     c = s[l]
>>     c += carry
>>     if c>max_allowed_char:
>>         c = min_allowed_char
>>         carry = 1
>>     else:
>>         carry = 0
>>     s[l] = c
>>
>> if carry:
>>     s = min_allowed_char + s
>>
>> If two transactions do the same at the same time, you're out of luck
>> though !
>>
>> *** Better solution :
>>
>> if the value was human-entered, prefix it with 'H',
>> if it's auto generated, use 'A' concatenated with the value from a
>> sequence
>>
>> thus the user-entered values can't clahs with the sequence values ; the
>> sequence values are by definition unique ; and all is well.
>>
>> or something like that...
>>
>> On Mon, 3 Jan 2005 11:53:44 -0500, Frank D. Engel, Jr.
>> <fde101@fjrhome.net> wrote:
>>
>>> -----BEGIN PGP SIGNED MESSAGE-----
>>> Hash: SHA1
>>>
>>> Is there any "convenient" way to generate (on request) a unique value
>>> for a TEXT column?  I have a situation in which I want users of my
>>> front-end program to be able to manually enter values for this column,
>>> but if they leave it blank (in the front-end), to have the database
>>> automatically fill in a unique value.  I would like to restrict the
>>> unique values to (for example) digits and uppercase letters (this is
>>> flexible, but the uniqueness of the values should be visually
>>> discernible, and all characters should be printable).
>>>
>>> I know how to do this with a numeric column (I can just SELECT MAX on
>>> the column and add one, for example), but how can this be done with a
>>> TEXT column?
>>>
>>> Thank you!
>>>
>>> - -----------------------------------------------------------
>>> Frank D. Engel, Jr.  <fde101@fjrhome.net>
>>>
>>> $ ln -s /usr/share/kjvbible /usr/manual
>>> $ true | cat /usr/manual | grep "John 3:16"
>>> John 3:16 For God so loved the world, that he gave his only begotten
>>> Son, that whosoever believeth in him should not perish, but have
>>> everlasting life.
>>> $ -----BEGIN PGP SIGNATURE-----
>>> Version: GnuPG v1.2.4 (Darwin)
>>>
>>> iD8DBQFB2XiY7aqtWrR9cZoRAqATAJ46xJ3bwsZVpIda0iMSSdcm3/8YKACePSC3
>>> 2JAngWmFOlkzC5fNE6HKYMU=
>>> =pblY
>>> -----END PGP SIGNATURE-----
>>>
>>>
>>>
>>> ___________________________________________________________
>>> $0 Web Hosting with up to 120MB web space, 1000 MB Transfer
>>> 10 Personalized POP and Web E-mail Accounts, and much more.
>>> Signup at www.doteasy.com
>>>
>>>
>>> ---------------------------(end of
>>> broadcast)---------------------------
>>> TIP 8: explain analyze is your friend
>>>
>>
>>
>>
>> ---------------------------(end of broadcast)---------------------------
>> TIP 9: the planner will ignore your desire to choose an index scan if
>> your
>>      joining column's datatypes do not match
>>
>>
> - -----------------------------------------------------------
> Frank D. Engel, Jr.  <fde101@fjrhome.net>
>
> $ ln -s /usr/share/kjvbible /usr/manual
> $ true | cat /usr/manual | grep "John 3:16"
> John 3:16 For God so loved the world, that he gave his only begotten
> Son, that whosoever believeth in him should not perish, but have
> everlasting life.
> $
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.4 (Darwin)
>
> iD8DBQFB2YZX7aqtWrR9cZoRAktzAJ0edjYBm7wS/fNtPUt7VIytdAcymACfWO2i
> arL1gXIctDZKeqjq6RoILOg=
> =BUlk
> -----END PGP SIGNATURE-----
>
>
>
> ___________________________________________________________
> $0 Web Hosting with up to 120MB web space, 1000 MB Transfer
> 10 Personalized POP and Web E-mail Accounts, and much more.
> Signup at www.doteasy.com
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
>       subscribe-nomail command to majordomo@postgresql.org so that your
>       message can get through to the mailing list cleanly
>



pgsql-general by date:

Previous
From: Lonni J Friedman
Date:
Subject: Re: Can't change password?
Next
From: Pierre-Frédéric Caillaud
Date:
Subject: Re: Large Objects