Go sonyflake Sonyflake与UUID的存储形态有什么区别
Sonyflake与UUID的存储形态主要区别在于标识宽度和接口返回类型:本文使用的 Go Sonyflake v1.3.0 返回 uint64,适合按整数保存,也可自行编码为固定8字节;UUID是128位标识,完整二进制为16字节,常见带连字符文本为36字符。不能拿UUID文本长度去推断其二进制大小,也不能将完整UUID直接截成64位整数。
Sonyflake官方地址:https://github.com/sony/sonyflake
本文UUID库地址:https://github.com/google/uuid
接口对照固定采用 sonyflake v1.3.0 与 google/uuid v1.6.0,UUID格式依据RFC 9562;不将不同大版本接口混用,也不宣称这些版本最新。
先把生成结果和展示文本分开
假设已有服务用整数ID保存订单,另一个服务传来UUID。若只把数据库字段统一叫id,而不记录它是数值、原始字节还是展示字符串,读写双方可能采用完全不同的解释。先规定表示,再选择字段,比先改列宽更稳妥。
| 对照项 | Sonyflake v1.3.0 | UUID |
|---|---|---|
| 标识宽度与返回 | 该实现使用63位布局,NextID返回uint64和error | 128位;google/uuid表示为[16]byte |
| 完整二进制 | 可约定8字节整数编码 | 16字节 |
| 文本表示 | 十进制格式通常变长 | 常见标准形式为32个十六进制字符与4个连字符 |
| 数据库形态 | 兼容范围的整数列或约定的二进制列 | 原生UUID类型、二进制或文本,取决于数据库与驱动 |
这里的8字节来自uint64的编码宽度,不意味着原库强制某种文件格式;36字符则是UUID的一种标准文本表示,不是UUID本体占36字节二进制。内存对象、数据库行、索引和网络报文还可能有额外开销,不能把这些数值直接当成整套系统的空间占用。

为Sonyflake约定8字节编码
从NextID获得成功结果后,若协议要求固定字节,可用encoding/binary明确端序。以下采用大端,只是一项清楚的应用约定;读取端必须采用同样规则。生成错误应在调用方处理,不应把错误返回的零值当成一个正常的新ID继续入库。
package idformat
import (
"encoding/binary"
"fmt"
"strconv"
"github.com/google/uuid"
)
// EncodeSonyflake约定大端8字节,本函数不负责生成或判断ID来源。
func EncodeSonyflake(id uint64) [8]byte {
var raw [8]byte
binary.BigEndian.PutUint64(raw[:], id)
return raw
}
// DecodeSonyflake拒绝错误长度,不补零或截断输入。
func DecodeSonyflake(raw []byte) (uint64, error) {
if len(raw) != 8 {
return 0, fmt.Errorf("Sonyflake编码需要8字节,实际%d", len(raw))
}
return binary.BigEndian.Uint64(raw), nil
}
// EncodeUUID保留完整数组,不将128位标识压缩成uint64。
func EncodeUUID(id uuid.UUID) [16]byte {
return [16]byte(id)
}
// DecodeUUID只恢复16字节表示,业务可另行约束版本和空值。
func DecodeUUID(raw []byte) (uuid.UUID, error) {
id, err := uuid.FromBytes(raw)
if err != nil {
return uuid.Nil, fmt.Errorf("读取UUID: %w", err)
}
return id, nil
}
// SonyflakeText给跨语言接口提供十进制字符串,不经过浮点数。
func SonyflakeText(id uint64) string {
return strconv.FormatUint(id, 10)
}
这组原创辅助函数没有访问文件或数据库,也未作为实际运行结果展示。EncodeSonyflake只转换传入整数,不验证机器编号、时间配置、唯一性或业务存在性。DecodeSonyflake要求恰好8字节,避免把错误的文本字节静默解释成另一串数字。
若采用文件流,调用方负责文件打开、关闭、写入错误与短读处理;若采用数据库,则要核实驱动怎样绑定数值或字节。不要借助平台相关的内存布局或unsafe转换来省去端序约定。
UUID保留16字节,不截成整数
UUID对应的函数与Sonyflake函数故意分开命名。EncodeUUID保留完整16字节;DecodeUUID使用FromBytes恢复。需要标准文本时使用UUID对象的String方法,需要从文本恢复时使用对应Parse接口,而不是直接把36字符的字节传给二进制恢复函数。
8字节Sonyflake与16字节UUID不是可以互换的编码。给Sonyflake前面补8个零,只能得到自定义的16字节容器,不会自动赋予它标准UUID的版本、变体及生成语义;将UUID砍掉一半则会丢失信息。若系统同时接受两种ID,建议在协议或字段中携带明确类型,不靠长度猜业务身份。
UUID版本不同也不改变完整128位这一宽度。是否允许Nil UUID、哪些版本能进入某个业务字段,应由应用单独规定;二进制长度通过不等于已经满足全部业务规则。
数据库与JSON接口分别约定形态

数据库需要分别核对列类型、参数绑定、扫描目标与空值语义。Sonyflake v1.3.0的布局总共使用63位,不代表所有名字类似的生成器或后续接口都具有相同范围;不能仅因Go类型是uint64,就忽略目标数据库的有符号范围与驱动限制。
UUID有原生数据库类型时,是否自动使用它仍由驱动适配决定。将某个库对象直接作为参数,与显式传16字节或标准文本,不一定走同样的绑定逻辑。本文不假设某个数据库已经创建表,也不提供跨产品通用SQL声明。
JSON则有另一类问题:部分接收端会把数字放进IEEE 754双精度浮点数。RFC 8259指出,整数处于 [-(2^53-1), 2^53-1] 范围时,采用这类表示的实现可以就精确值达成一致;超过该范围的ID可能在消费端失去精度。因此跨语言Sonyflake接口可以明确使用十进制字符串,并在接收端按无损整数解析。
UUID通常以标准文本传输。若自行把字节切片交给JSON编码器,不应假定它会得到UUID标准字符串;先在DTO中明确字符串字段更容易控制协议。把数据库保存为二进制,并不要求HTTP接口也暴露二进制。
接入时怎样核对往返结果
可以用固定的整数值,例如258,分析上述大端编码:8字节末尾应为0x01、0x02,其余前导字节为零。恢复后应仍得到258。这个例子仅说明编码方式,不代表258是实际生成的Sonyflake,也不是本文的实测输出。
对UUID,采用自己控制的固定标识,比较编码前后对象相等,并确认标准文本还能解析回同一对象。另准备错误长度输入,要求恢复函数明确返回错误。迁移前要同时看正常往返和失败路径,而不是只查看界面上有没有显示一串ID。
8字节是不是说明Sonyflake一定比UUID快一倍?不能这样推断。字节宽度只是一项输入,数据库索引结构、生成方式、驱动和访问模式都会影响性能。本文没有性能测量。
整数ID转字符串,会改变ID本身吗?无损格式化并按同样规则解析不会改变值;但不要经过float64再转回整数,也不要引入截断或舍入。
切换标识类型只是改字段宽度吗?不是。还涉及生成规则、引用关系、外部接口和已有数据。两种表示可以在同一系统中各自使用,但不能把不同标识直接当成同一值替换。
参考资料:Sonyflake v1.3.0实现;google/uuid接口;RFC 9562 UUID格式;RFC 8259数值互操作边界;Go二进制编码文档。
Go beep 采样率转换与修改播放速度有什么区别
- 上一篇
- Go beep 采样率转换与修改播放速度有什么区别
- 下一篇
- Java XMLEventReader 的peek与nextEvent有什么区别
-
- Golang · Go问答 | 50分钟前 |
- Go rtreego 最近邻查询中的距离基于什么对象
- 250浏览 收藏
-
- Golang · Go问答 | 58分钟前 | go · Go 采样率 播放速度 Resample beep ResampleRatio
- Go beep 采样率转换与修改播放速度有什么区别
- 482浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go llrb 插入后修改排序字段为什么会破坏检索
- 288浏览 收藏
-
- Golang · Go问答 | 1小时前 | 数据结构 · Go问答 · Go Less LLRB ReplaceOrInsert 排序等价
- Go llrb ReplaceOrInsert怎样判断两个对象相同
- 412浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go rtreego 空间对象维数不一致会怎样
- 424浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go bloom 合并Bloom过滤器为什么要求参数一致
- 252浏览 收藏
-
- Golang · Go问答 | 2小时前 | go · 性能 · BLOOM Go 容量 误判率 Bloom Filter
- Go bloom 过滤器容量不足怎样影响误判率
- 109浏览 收藏
-
- Golang · Go问答 | 2小时前 |
- Go bloom Bloom命中为什么不能证明元素存在
- 386浏览 收藏
-
- Golang · Go问答 | 2小时前 |
- Go bitset Complement为何需要明确有效长度
- 169浏览 收藏
-
- Golang · Go问答 | 2小时前 |
- Go bitset NextSet返回的布尔值为何不能忽略
- 355浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 809次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 798次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 890次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 861次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 687次使用
-
- 用Nginx反向代理部署go写的网站。
- 2023-01-17 502浏览
-
- GoLand调式动态执行代码
- 2023-01-13 502浏览
-
- Go generate 未执行指令的注释与目录检查
- 2026-10-28 501浏览
-
- Go RWMutex 写锁等待过久的竞争分析
- 2026-10-28 501浏览
-
- Go os.File.ReadAt 为什么到文件末尾仍返回部分数据
- 2026-10-26 501浏览

