tags:

views:

47

answers:

3

I'm looking for a method of generating unique identifiers for a record class being created locally and then persisted in various formats (XML, SQL, etc.)

I've seen people using DateTime and GetHashCode, but that seems to lend itself to duplicate identifiers depending upon the sample size.

GUID is a bit overkill, as I don't need anything that unique (large) at the global level. I'm also aware of using GUIDs and GetHashCode to get the size down a bit, but duplicates tend to crop up here as well.

Can anyone suggest a best practice or method for generating simple unique identifiers?

+4  A: 

Guid or increasing counter.

Guid can be generated "from air" but takes more space

For counter you need to store the counter somewhere and you will need to make it thread safe if you use threads. But it is smaller in size.

Alex Reitbort
+1  A: 

GetHashCode is definitely not a very good choice.

How big do you want the identifier to be?

If you have persistent storage to remember the "last generated" identifier (e.g. a database) then simply incrementing a number each time would suffice. If you don't have persistent storage, then using a DateTime to get the number of milliseconds since some fixed date would also work. That would obviously limit you to only being able to generate one identifier per millisecond, but depending on your situation, that should be OK.

You could combine the timestamp with your process ID or something to avoid duplcates if you've got multiple processes generating identifiers at the same time.

Dean Harding
I was hoping to use an identifier between 5 and 8 characters long.I did consider the timestamp option, since I can practically guarantee no more than one record will be generated each millisecond, I just wasn't sure if that was considered a good practice or if perhaps there was a more commonly used method.
knslyr
The resolution of DateTime in .Net is about 10ms, so it is one unique number in 10ms not 1 ms.
Alex Reitbort
@Alex: yeah, that's a good point.
Dean Harding
+4  A: 

It is almost always a mistake to implement your own. Small unique numbers require a really reliable recording of the last used number. That is hard to come by, hard disks have head crashes, registries get corrupted occasionally. You'll need to organize it so there is a single point of failure. Similar to a dbase's auto-incrementing column. Make sure if there's a loss of the last number, there is also complete loss of data. That means, for one, that there shouldn't be a way for the user to copy the data without also copying the record of the last number. Or that you always have a reliable copy of all the data and can recover the last number from it. Quickly.

You'll also have a hard time ensuring that the number is incremented atomically. Just starting two instances of your program is typically enough to cause mayhem. Fixing that is tricky, you'll need an independent arbiter process that stores the number.

Then there's the burden of having to guess what's going to happen 10 or 20 years from now. Will your app scale to meet the demands by then? That's very rare, counting on machines getting faster is over and done with. What's a local unique number now needs to becomes a globally unique number. Very different kind of demands on that.

Don't screw around with this, 16 bytes is nothing. Use a Guid.

Hans Passant