C#生成唯一ID的几种方式
|
admin
2024年11月15日 20:57
本文热度 1466
|
唯一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); // 传入机器 IDlong 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 编辑过