唯一ID是我們?cè)诰幋a的時(shí)候經(jīng)常需要解決的需求。以下是幾種常見的 ID 生成方式的實(shí)現(xiàn)示例:1. 基于 Snowflake 算法的 ID 生成器Snowflake 是 Twitter 開源的分布式 ID 生成算法,生成的是一個(gè) 64 位的整數(shù) 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); // 傳入機(jī)器 ID
long id = generator.GenerateId();
Console.WriteLine(id); // 輸出一個(gè) 64 位整數(shù)
- 優(yōu)點(diǎn):高性能,支持分布式。生成的 ID 有序。
2. 基于時(shí)間戳和隨機(jī)數(shù)的 ID 生成器結(jié)合時(shí)間戳和隨機(jī)數(shù)生成 ID,適合簡(jiǎn)單場(chǎng)景。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
- 優(yōu)點(diǎn):簡(jiǎn)單易實(shí)現(xiàn)。
- 缺點(diǎn):可能重復(fù)。無(wú)序。
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
- 優(yōu)點(diǎn):全局唯一。無(wú)需中心化生成。
- 缺點(diǎn):較長(zhǎng)(36 個(gè)字符)。無(wú)序。
使用 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
- 優(yōu)點(diǎn):高性能。適合分布式系統(tǒng)。
可以根據(jù)業(yè)務(wù)需求自定義 ID 生成規(guī)則。例如:
- 前綴 + 時(shí)間戳 + 隨機(jī)數(shù)。
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
- 優(yōu)點(diǎn):靈活,符合業(yè)務(wù)需求。
- 缺點(diǎn):需要自行實(shí)現(xiàn)。
MongoDB 使用 ObjectId 作為默認(rèn)的唯一標(biāo)識(shí)符,它是一個(gè) 12 字節(jié)的十六進(jìn)制字符串。using MongoDB.Bson;
ObjectId id = ObjectId.GenerateNewId();
Console.WriteLine(id); // 輸出類似:507f1f77bcf86cd799439011
- 優(yōu)點(diǎn):全局唯一。包含時(shí)間戳信息。
- 缺點(diǎn):較長(zhǎng)(24 個(gè)字符)。
該文章在 2025/2/12 10:48:23 編輯過(guò)