Si está almacenando sus registros en una base de datos, realmente debe buscar en las capacidades disponibles allí para generar claves únicas de sustitución. En SQLServer esto sería un campo IDENTITY y en Oracle sería un campo que usa un SEQUENCE para generar un nuevo valor.
Si hay una razón de peso por la que no puede utilizar su base de datos para generar una clave única, usted debe buscar en algo así como un Guid
- que tiene una probabilidad mucher más alta que la manipulación de fecha y hora para generar un valor único . Las guías se pueden convertir trivialmente en cadenas, por lo que su identificador sería una cadena en este caso.
Lo que está haciendo con hashes no es una buena idea - nada garantiza que los hashes serán únicos, y en muchos casos sí colisionan. Guides: no ofrecen una garantía del 100% de exclusividad en las máquinas, pero en una sola máquina siempre deben ser únicas. E incluso en todas las máquinas, sus posibilidades de colisión son extremadamente remotas. Además, usar el tiempo de la máquina como una forma de acumular el valor subyacente está sujeto a las condiciones de carrera (como las que Eric describe).
Las guías son valores de 128 bits, por lo que no puede representarlos como un simple int
o long
. Te solicitará que uses string como tus ID, lo que puede o no ser posible en tu caso, dependiendo de otras consideraciones (como si controlas o no el modelo de datos). Si puede usarlos, utilizando un GUID es muy fácil:
string customerId = Guid.NewGuid().ToString(); // fetch new guid and save as string
string orderNumber = Guid.NewGuid().ToString(); // same story here...
Si realmente debe utilizar un identificador numérico, y que está dispuesto a abandonar fácilmente escalar su aplicación a través de múltiples servidores, se puede utilizar un incremento automático número global para suministrar una clave única. Tendría que inicializar este número con el siguiente valor disponible (máximo + 1) de su base de datos cuando se inicia la aplicación. También debería proteger este valor del uso simultáneo de múltiples hilos.Me gustaría concluir esta responsabilidad en una clase:
class static UniqueIDGenerator
{
// reads Max+1 from DB on startup
private static long m_NextID = InitializeFromDatabase();
public static long GetNextID() { return Interlocked.Increment(ref m_NextID); }
}
EDIT:En este día y edad, razones de peso para la generación de identificadores únicos en su capa de aplicación en lugar de en la base de datos son muy poco frecuentes . Realmente debería usar las capacidades que proporciona la base de datos.
puramente teórica, los hashes pueden colisionar. –
Seguramente no es lo único que está buscando, solo el siguiente número secuencial ... Estoy de acuerdo con la gente a continuación que habla sobre el uso de una columna de identidad. – Paddy
@Developer Art: nada teórico al respecto. Hashes colisionan * todo el tiempo *. Solo hay unos cuatro mil millones disponibles, por lo que chocarán. –