Indexes - Rolling your own Unique
I am working on a rather large database for work and I came upon a dilemma that I just could figure out. I had 3 tables, one was a user info table whose id was an auto increment and unique. The second table was a list of groups that the users would be put into. The third table was the group mapping where it would pair the user id with the group id.
The thought is that if the user was already present then inserting into the table with the group pairs wouldn’t be a big problem. The auto id would already be made and could easily be inserted into the group pair table. What would happen if the user didn’t exist? How would I then insert it into the group pair table without the id existing for the user. Auto increment only increments after the record is added.
I tried many methods starting with @@IDENTITY but that didn’t work, then I came across SCOPE_IDENTITY() and thought, okay, problem solved. Well, it was short lived. When I inserted the user record with my INSERT query and then immediately ran scope_identity I got the ID I would get the last inserted id. Was real cool.
I thought that scope_identity worked off the last session, but soon found that it didn’t work very well with multiple users on a non persistent data connection…ugh. Alrighty then, even though all the sql db admins I asked said it should work, my testing showed otherwise. It wasn’t consistent enough for me.
After some consideration I decided to roll my own index, so I asked around and got some ideas. Some of the ideas seemed a little bloated others were just so complex that they were hard to understand. I believe that in many cases the simple solution might be the best. This is the code I came up with.
Generate the random ID
$rID = md5(mt_rand(1, 2048));
$id = md5($rID . microtime());
Then do a select to see if it is unique
$result = mysql_query("SELECT UID FROM members WHERE UID = '" . $id . "' LIMIT 1");
$cnt = mysql_num_rows;
With this in mind, I created a class that would check the db for duplicates and then release a new ID if there were no dupes.
<?php
include('dbconnect.php');
$Basic = new r_id;
echo $Basic->Getcnt();
class r_id{
var $mid;
var $cnt = 1;
function Getid(){
$rID = md5(mt_rand(1, 2048));
$id = md5($rID . microtime());
return $id;
}
function Getcnt(){
while ($this->cnt > 0){
$this->mid = $this->Getid();
$result = mysql_query("SELECT UID FROM members WHERE UID = '" . $this->mid . "' LIMIT 1");
$this->cnt = mysql_num_rows($result);
}
return $this->mid;
}
}
?>
The ID will be a huge alphanumeric entry in this fashion - 47e509c01d97f7ee1df29ecf2b0a0e07; the chances of it ever being duplicated are slim. I’m sure someone could quantify its chance of being duplicated; don’t look at me to do it.