tags:

views:

1380

answers:

8

I'm programming a script using PHP and MySQL and I want to get a unique id (consisting of a string: capitals and small letters with numbers) like: gHYtUUi5b. I found many functions in PHP that can generate such numbers but I'm afraid about how to ensure the id is unique!

UPDATE: uuid is long, I mean such id like: (P5Dc) an 11 alphanumeric char.

A: 

Is it not possible to just use an auto_increment in a database table?

contagious
Not if he wants to have unique strings(see his example).
André Hoffmann
+4  A: 

I use UUID() to create a unique value.

example:

insert into Companies (CompanyID, CompanyName) Values(UUID(), "TestUUID");
CSharpAtl
thanx but uuid is long, imean such id like: (P5Dc) a 11 alphanumeric char.
assaqqaf
It is long because it has to assure uniqueness :) generate it progragmatically if you really need to have it short, see my post
AlberT
+2  A: 

A programmatic way can be to:

  • add a UNIQUE INDEX to the field
  • generate a random string in PHP
  • loop in PHP ( while( ! DO_THE_INSERT ) )
    • generate another string

Note:

  • This can be dirty, but has the advantage to be DBMS-agnostic
  • Even if you choose to use a DBMS specific unique ID generator function (UUID, etc) it is a best practice to assure the field HAS to be UNIQUE, using the index
  • the loop is statistically not executed at all, it is entered only on insert failure
AlberT
this the only solution in my mind, even before i post my question. is the way use resources. and at the same time isn't scientific.
assaqqaf
It is instead. If well implemented it is as safe as the DBMS based approach, resources are not a matter as if you generate a random string the probability of an INSERT fail is very very low (depending on the table dimension of course), so you loop is actually a single operation.
AlberT
Unless of course your random number generator isn't completely random. Written race conditions are usually a Bad Idea ^TM
Billy ONeal
Rather than looping on failed insert (which can be caused by other reasons thus causing infinite loop), I'd loop the ID generation on finding the same ID, then insert and throw an exception on insert fail. You have the same statistic of only one loop, it's safer and provide information when the insert fails (for other reasons).
streetpc
this way you are using 2 DB operations, being no more atomic. Better to check the reason of the failure inside the loop, once the failure is already occurred.
AlberT
A: 

Use UUID function.

I don't know the source of your procedures in PHP that generates unique values. If it is library function they should guarantee that your value is really unique. Check in documentation. You should, hovewer, use this function all the time. If you, for example, use PHP function to generate unique value, and then you decide to use MySQL function, you can generate value that already exist. In this case putting UNIQUE INDEX on the column is also a good idea.

Lukasz Lysik
A: 

Does it need to be random? Or can you maybe base the unique id off other information in the row you are inserting?

You could do something like first few letters of field 1, followed by a few letters from field 2 and then an integer.

So you would generate the first part of the ID in PHP (The first few letters, without the integer.)

You could then check the database for similar ids by executing:

SELECT UniqueID FROM someTable WHERE UniqueID LIKE 'generatedString%' ORDER BY UniqueID DESC;

Then you would grab the first row, grab the integer off the end, increment it by one, and append that integer to the end of your generated string and insert.

TJMonk15
A: 

For uniqueness what I do is I take the Unix timestamp and append a random string to it and use that.

Sabeen Malik
u can use microtime and convert it to hex to get the string effect or atleast in most cases , this would work ok if u dont have high volume traffic / insertions in db.
Sabeen Malik
"i use it to access recourse through url, if i use auto_increment it will be easy to suggest" .. keeping that in mind...if insertions are high .. you can do it the other way around .. use auto increment to add normal ids in the DB .. on the site , where you display the links , have the id encrypted with a known key and then decrypt it back with that key before making the DB query.
Sabeen Malik
that what I actually use... but I look for best solution..
assaqqaf
if u are already using this .. i would suggest keep it this way .. i have no idea how much traffic u have or the db size .. but keep in mind that varchar type look ups are slower than integer look ups and re-indexing on inserts/updates is costly as well. ideally to avoid calculating the hash each time .. just create another field in the db which stores this hash .. show that hash to the user from there..atleast that would avoid the encryption part each time the link needs to be displayed. i personally prefer putting more load on the php end rather than mysql.
Sabeen Malik
i agree with you 80%, but i think there are other solution used by large site like: youtube to keep id simple and short..
assaqqaf
youtube stores its data on CDNs , no one really know how they generate the unique ID .. but my guess is that unique ID contains not only the record ID but the server/cluster/CDN addressing as well .. so that unique ID is basically a composite of more than 1 values, which is decrypted into a more meaningful and fuller explanation of the record and its location.
Sabeen Malik
A: 

Below is just for reference of numeric unique random id...

it may help you...

$query=mysql_query("select * from collectors_repair");
$row=mysql_num_rows($query);
$ind=0;
if($row>0)
{
while($rowids=mysql_fetch_array($query))
{
  $already_exists[$ind]=$rowids['collector_repair_reportid'];
}
}
else
{
  $already_exists[0]="nothing";
}
    $break='false';
    while($break=='false'){
      $rand=mt_rand(10000,999999);

      if(array_search($rand,$alredy_exists)===false){
          $break='stop';
      }else{

      }
    }

 echo "random number is : ".$echo;

and you can add char with the code like -> $rand=mt_rand(10000,999999) .$randomchar; // assume $radomchar contains char;

Aravinth
A: 

You might also consider using crypt()* to generate a [nearly-guaranteed] unique ID inside your contraints.

warren