唯一ID是我們在編碼的時候經常需要解決的需求。以下是幾種常見的 ID 生成方式的實現示例:1. 基于 Snowflake 算法的 ID 生成器Snowflake 是 Twitter 開源的分布式 ID 生成算法,生成的是一個 64 位的整數 ID。using System;
using System.Threading;
public class SnowflakeIdGenerator
{
private const int TimestampBits = 41;
private const int MachineIdBits = 10;
private const int SequenceBits = 12;
private const long MaxMachineId = (1L << MachineIdBits) - 1;
private const long MaxSequence = (1L << SequenceBits) - 1;
private static readonly DateTime Epoch = new DateTime(2023, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private readonly long _machineId;
private long _sequence = 0L;
private long _lastTimestamp = -1L;
private readonly object _lock = new object();
public SnowflakeIdGenerator(long machineId)
{
if (machineId < 0 || machineId > MaxMachineId)
throw new ArgumentException($"Machine ID must be between 0 and {MaxMachineId}.");
_machineId = machineId;
}
public long GenerateId()
{
lock (_lock)
{
long timestamp = GetCurrentTimestamp();
if (timestamp < _lastTimestamp)
throw new InvalidOperationException("Clock moved backwards.");
if (timestamp == _lastTimestamp)
{
_sequence = (_sequence + 1) & MaxSequence;
if (_sequence == 0)
timestamp = WaitNextMillis(_lastTimestamp);
}
else
{
_sequence = 0L;
}
_lastTimestamp = timestamp;
return (timestamp << (MachineIdBits + SequenceBits))
| (_machineId << SequenceBits)
| _sequence;
}
}
private long GetCurrentTimestamp()
{
return (long)(DateTime.UtcNow - Epoch).TotalMilliseconds;
}
private long WaitNextMillis(long lastTimestamp)
{
long timestamp = GetCurrentTimestamp();
while (timestamp <= lastTimestamp)
{
timestamp = GetCurrentTimestamp();
}
return timestamp;
}
}
var generator = new SnowflakeIdGenerator(1); // 傳入機器 ID
long id = generator.GenerateId();
Console.WriteLine(id); // 輸出一個 64 位整數
using System;
public class TimestampIdGenerator
{
private static readonly Random Random = new Random();
public string GenerateId(string prefix = "")
{
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
int random = Random.Next(1000, 9999);
return $"{prefix}{timestamp}{random}";
}
}
var generator = new TimestampIdGenerator();
string id = generator.GenerateId("ORDER-");
Console.WriteLine(id); // 輸出類似:ORDER-16970496000001234
using System;
public class GuidIdGenerator
{
public string GenerateId()
{
return Guid.NewGuid().ToString();
}
}
var generator = new GuidIdGenerator();
string id = generator.GenerateId();
Console.WriteLine(id); // 輸出類似:550e8400-e29b-41d4-a716-446655440000
使用 Redis 的 INCR 命令生成全局唯一的自增 ID。using StackExchange.Redis;
public class RedisIdGenerator
{
private readonly IDatabase _redisDb;
public RedisIdGenerator(string connectionString)
{
var redis = ConnectionMultiplexer.Connect(connectionString);
_redisDb = redis.GetDatabase();
}
public long GenerateId(string key = "global:id")
{
return _redisDb.StringIncrement(key);
}
}
var generator = new RedisIdGenerator("localhost");
long id = generator.GenerateId();
Console.WriteLine(id); // 輸出自增的 ID
using System;
public class CustomIdGenerator
{
private static readonly Random Random = new Random();
public string GenerateId(string prefix)
{
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
int random = Random.Next(1000, 9999);
return $"{prefix}-{timestamp}-{random}";
}
}
var generator = new CustomIdGenerator();
string id = generator.GenerateId("USER");
Console.WriteLine(id); // 輸出類似:USER-1697049600000-1234
MongoDB 使用 ObjectId 作為默認的唯一標識符,它是一個 12 字節的十六進制字符串。using MongoDB.Bson;
ObjectId id = ObjectId.GenerateNewId();
Console.WriteLine(id); // 輸出類似:507f1f77bcf86cd799439011
該文章在 2025/2/12 10:48:23 編輯過