本帖最后由 快表帝国客服01 于 2026-4-2 15:39 编辑
在通常情况下,我们使用快表自动编号以及GUID全球唯一码实现业务场景中的唯一编码要求,而在一些特定的场合下,需要兼顾唯一性、可读性与便捷性的原则来生成唯一编码。下面分享一个千万级数据不重复的编码方案。编码采用年月日时分秒加随机码的方式产生,可以实现在生成1000万行数据0重复。其中年月日时分秒通过定长字母加数字base36的映射方案实现:
更新的版本见:http://bbs.kuaibiao.cn/thread-6002-1-1.html
1、年份 (1位):设定一个基准年份(如 2025年 为 0,2026 为 1 ... 到 2034 为 9, 2035 为 A等)。1个字符可表示 36 年。
2、月份 (1位):1-9月用 1-9,10-12月用 A, B, C。
3、日期 (1位):1-9日用 1-9,10-31日用 A-V。
4、时 (1位):1点起为 A,B,C...23点为 W,0点为 X
5、分秒 (4位):保留2位分和2位秒,便于排查。
6、极强防重哈希 (10位):截取 MD5 转换的高精 16 进制码。
- CREATE FUNCTION [dbo].[ShortCode](
- @Str VARCHAR(50)
- )
- RETURNS VARCHAR(50)
- AS
- BEGIN
- -- 1. 使用高精度时间
- DECLARE @Now DATETIME2 = SYSDATETIME();
- DECLARE @ShortCode VARCHAR(50);
- DECLARE @Hash VARBINARY(16);
-
- -- 2. 使用 MD5 生成防重哈希
- SET @Hash = HASHBYTES('MD5',
- CONVERT(VARCHAR(27), @Now, 121) +
- CAST(@@SPID AS VARCHAR(10)) +
- CAST(ISNULL(@Str, '') AS VARCHAR(50))
- );
-
- -- 3. 提取各个时间部分
- DECLARE @Y INT = YEAR(@Now) - 2025; -- 基准 2025年=0
- DECLARE @M INT = MONTH(@Now);
- DECLARE @D INT = DAY(@Now);
- DECLARE @H INT = DATEPART(HOUR, @Now);
-
- -- 4. 组装极简易读且高防重唯一的 16 位短码
- SET @ShortCode =
- -- 【年】 1位 (0-9, A-Z)
- CHAR(CASE WHEN @Y < 10 THEN 48 + @Y ELSE 55 + @Y END) +
-
- -- 【月】 1位 (1-9, A-C)
- CHAR(CASE WHEN @M < 10 THEN 48 + @M ELSE 55 + @M END) +
-
- -- 【日】 1位 (1-26 用 A-Z, 27-31 用 1-5)
- CHAR(CASE WHEN @D <= 26 THEN 64 + @D ELSE 22 + @D END) +
-
- -- 【时】 1位 (1点起为 A,B,C...23点为 W,0点为 X)
- CHAR(CASE WHEN @H = 0 THEN 88 ELSE 64 + @H END) +
-
- -- 【分与秒保留】 直观明了(4位)
- RIGHT('0' + CAST(DATEPART(MINUTE, @Now) AS VARCHAR(2)), 2) +
- RIGHT('0' + CAST(DATEPART(SECOND, @Now) AS VARCHAR(2)), 2) +
-
- -- 【防重哈希】 10位 (保留底层最高效的二进制转16进制,天然数字与字母混合)
- CONVERT(VARCHAR(10), SUBSTRING(@Hash, 1, 5), 2);
-
- RETURN @ShortCode;
- END
复制代码
运行:
- SELECT dbo.ShortCode(NewID())
复制代码
效果:
上面结果为2026年3月31日11点58分13秒 后面加10位哈希值
|
|
快表帝国客服01