唯一ID是我們在編碼的時候經(jīng)常需要解決的需求。以下是幾種常見的 ID 生成方式的實現(xiàn)示例:1. 基于 Snowflake 算法的 ID 生成器Snowflake 是 Twitter 開源的分布式 ID 生成算法,生成的是一個 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); // 傳入機器 IDlong id = generator.GenerateId();Console.WriteLine(id); // 輸出一個 64 位整數(shù)
- 優(yōu)點:高性能,支持分布式。生成的 ID 有序。
2. 基于時間戳和隨機數(shù)的 ID 生成器結(jié)合時間戳和隨機數(shù)生成 ID,適合簡單場景。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
- 優(yōu)點:高性能。適合分布式系統(tǒng)。
可以根據(jù)業(yè)務需求自定義 ID 生成規(guī)則。例如:
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 字節(jié)的十六進制字符串。using MongoDB.Bson;
ObjectId id = ObjectId.GenerateNewId();Console.WriteLine(id); // 輸出類似:507f1f77bcf86cd799439011
該文章在 2025/2/12 10:48:23 編輯過