当需保证全局唯一的id,可以选用UUID或Snowflake(及其变种)
其中UUID 不依赖于任何第三方系统,性能和可用性上较好;
Snowflake生成的id具有单调递增性(可以拿到生成时的时间戳信息),能包含一定业务上的意义(如注册时间的长短),涉及到分表时用Snowflake更好。
从占用数据库空间来说,Snowflake是将64bit 的二进制数字分成若干部分,因此如果用int类型存储,其最大为9223372036854775807,不超过int64的上限,如 1628304129979846657
uuid的组成[1]
而UUID 是由 32 个 16 进制数字组成的字符串,如cd7460be-1593-41b1-9542-2b9a690f9dd2
snowflake算法 Demo:
package main
import (
"fmt"
"github.com/bwmarrin/snowflake"
)
func main() {
// Create a new Node with a Node number of 1
node, err := snowflake.NewNode(1)
if err != nil {
fmt.Println(err)
return
}
// Generate a snowflake ID.
id := node.Generate()
// Print out the ID in a few different ways.
fmt.Printf("Int64 ID: %d\n", id)
fmt.Printf("String ID: %s\n", id)
fmt.Printf("Base2 ID: %s\n", id.Base2())
fmt.Printf("Base64 ID: %s\n", id.Base64())
// Print out the ID's timestamp
fmt.Printf("ID Time : %d\n", id.Time())
// Print out the ID's node number
fmt.Printf("ID Node : %d\n", id.Node())
// Print out the ID's sequence number
fmt.Printf("ID Step : %d\n", id.Step())
// Generate and print, all in one.
fmt.Printf("ID : %d\n", node.Generate().Int64())
}
输出:
Int64 ID: 1628304129979846656
String ID: 1628304129979846656
Base2 ID: 1011010011000111001011111101010100101110000000001000000000000
Base64 ID: MTYyODMwNDEyOTk3OTg0NjY1Ng==
ID Time : 1677052931672
ID Node : 1
ID Step : 0
ID : 1628304129979846657
UUID Demo:
package main
import (
"fmt"
"github.com/satori/go.uuid"
)
func main() {
// Creating UUID Version 4
// panic on error
u1 := uuid.Must(uuid.NewV4(), nil)
fmt.Printf("UUIDv4: %s\n", u1)
// or error handling
u2 := uuid.NewV4()
fmt.Printf("UUIDv4: %s\n", u2)
// Parsing UUID from string input
u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
if err != nil {
fmt.Printf("Something went wrong: %s", err)
return
}
fmt.Printf("Successfully parsed: %s", u2)
}
输出:
UUIDv4: cd7460be-1593-41b1-9542-2b9a690f9dd2
UUIDv4: 2c598a64-e685-4ab2-9021-9aa352aaefad
Successfully parsed: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
通用唯一识别码(英语:Universally Unique Identifier,缩写:UUID)[2]
UUID是由开放软件基金会(OSF)定义的一种标准,而GUID是微软对UUID这个标准的实现,目前被广泛采用。UUID还有其它各种实现,不止GUID一种。
生成的uuid是由一组 32位数 的16进制数字所构成,故uuid理论上的总数为16的32次方, 即2的128次方,约等于3.4 x 10的38次方。也就是说若每纳秒(ns)产生1兆个UUID,要花100亿年才会将所有uuid用完。
UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的32个字符。示例:
550e8400-e29b-41d4-a716-446655440000
UUID的编码规则:
通过以上4种策略可以保证惟一性。在系统中需要用到随机数的地方都可以考虑采用UUID算法。
最知名的标准是RFC4122[3]
很有意思的是这个标准没有第二版[4]
uuid现在共有5个版本,版本1不够安全,版本4有可能发生重复,但概率极低.现在大多使用uuid4
UUID 不同版本的区别及选择[5]
UUID4发生碰撞的概率:
go版常用实现 uuid-rs/uuid[6]:
rust版常用实现 uuid-rs/uuid[7]:
[UUID和雪花(Snowflake)算法该如何选择?](https://cloud.tencent.com/developer/article/1766264 "UUID和雪花(Snowflake "UUID和雪花(Snowflake)算法该如何选择?")算法该如何选择?")
分布式ID生成方案--雪花算法和UUID对比[8]
几种分布式id生成方式[9]
图解各路分布式ID生成算法[10]
六种方式实现全局唯一发号器[11]
面试总被问分布式ID? 美团(Leaf)了解一下[12]
美团技术分享:深度解密美团的分布式ID生成算法[13]
面试总被问分布式ID怎么办? 滴滴(Tinyid)甩给他[14]
uuid的组成: https://www.google.com/search?q=uuid&newwindow=1&sxsrf=AJOqlzW1mf2ohYNWjOwjuSh70Di0-aYINg:1677053193032&source=lnms&tbm=isch&sa=X&ved=2ahUKEwii7Nv-1aj9AhVNNt4KHQ7rCmQQ_AUoAXoECAEQAw&biw=1920&bih=990&dpr=1.8
[2]通用唯一识别码(英语:Universally Unique Identifier,缩写:UUID): https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E5%94%AF%E4%B8%80%E8%AF%86%E5%88%AB%E7%A0%81
[3]RFC4122: https://segmentfault.com/a/1190000000484508
[4]没有第二版: https://docs.python.org/zh-cn/3.11/library/uuid.html
[5]UUID 不同版本的区别及选择: https://www.jianshu.com/p/76e3a75605ed
[6]uuid-rs/uuid: https://github.com/satori/go.uuid
[7]uuid-rs/uuid: https://github.com/uuid-rs/uuid
[8]分布式ID生成方案--雪花算法和UUID对比: https://blog.csdn.net/qq_40950903/article/details/108589837
[9]几种分布式id生成方式: https://www.cnblogs.com/kuotian/p/12869914.html
[10]图解各路分布式ID生成算法: https://i6448038.github.io/2019/09/28/snowflake/
[11]六种方式实现全局唯一发号器: https://blog.csdn.net/qq_20051535/article/details/120072174
[12]面试总被问分布式ID? 美团(Leaf)了解一下: https://juejin.im/post/5e61b4f26fb9a07cb83e2eee
[13]美团技术分享:深度解密美团的分布式ID生成算法: https://zhuanlan.zhihu.com/p/83753710
[14]面试总被问分布式ID怎么办? 滴滴(Tinyid)甩给他: https://cloud.tencent.com/developer/article/1598569
本文由 mdnice 多平台发布