当前位置:首页 > 文章列表 > Golang > Go问答 > Go sonyflake Sonyflake与UUID的存储形态有什么区别

Go sonyflake Sonyflake与UUID的存储形态有什么区别

来源:17golang原创 2026-10-31 10:47:20 0浏览 收藏

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.0UUID
标识宽度与返回该实现使用63位布局,NextID返回uint64和error128位;google/uuid表示为[16]byte
完整二进制可约定8字节整数编码16字节
文本表示十进制格式通常变长常见标准形式为32个十六进制字符与4个连字符
数据库形态兼容范围的整数列或约定的二进制列原生UUID类型、二进制或文本,取决于数据库与驱动

这里的8字节来自uint64的编码宽度,不意味着原库强制某种文件格式;36字符则是UUID的一种标准文本表示,不是UUID本体占36字节二进制。内存对象、数据库行、索引和网络报文还可能有额外开销,不能把这些数值直接当成整套系统的空间占用。

Sonyflake和UUID的数值二进制文本关系
表示对照结构图:先区分标识本体与编码形式,再讨论存储位置。

为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接口分别约定形态

内部ID数据库绑定和JSON传输形态
接口边界结构图:数据库和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二进制编码文档。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go beep 采样率转换与修改播放速度有什么区别Go beep 采样率转换与修改播放速度有什么区别
上一篇
Go beep 采样率转换与修改播放速度有什么区别
Java XMLEventReader 的peek与nextEvent有什么区别
下一篇
Java XMLEventReader 的peek与nextEvent有什么区别
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    809次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    798次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    890次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    861次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    687次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码