英文:
Is UnixNano concatenated with Server ID a good primary key?
问题
我尝试从Go的UnixNano生成10,000个整数,但没有显示任何冲突。
package main
import (
"fmt"
"sync"
"time"
"strconv"
"github.com/OneOfOne/cmap"
)
func main() {
var wg sync.WaitGroup
k := 1000
wg.Add(k * 1000)
coll := cmap.New()
for z := 0; z < k*1000; z++ {
go func() {
k := strconv.FormatInt(time.Now().UnixNano(),36)
if coll.Has(k) {
fmt.Println(`collision: `, k)
}
coll.Set(k,true)
defer wg.Done()
}()
}
wg.Wait()
}
该数据库最多只支持64位整数,并且不支持原子计数器/序列。
编辑于2017-03-06,它存在冲突
collision: bb70elvagvqu
collision: bb70elwbgk98
collision: bb70elwnxcm7
因此,如果我使用该数字创建一个主键,将其转换为基数36,并附加3位服务器键,就不可能发生冲突了,对吗?
一些示例:
0bb4snonc8nfc001(当前时间,第一个服务器)
1y2p0ij32e8e7zzz(最大值:2262-04-11 23:47:16.854775807,第46654个/最后一个服务器)
要求于2017-03-04
- 字典顺序正确
- 唯一
- 尽可能短
- 按创建时间排序
英文:
I've tried to generate 10k integer from Go's UnixNano, and it doesn't show any collision.
package main
import (
"fmt"
"sync"
"time"
"strconv"
"github.com/OneOfOne/cmap"
)
func main() {
var wg sync.WaitGroup
k := 1000
wg.Add(k * 1000)
coll := cmap.New()
for z := 0; z < k*1000; z++ {
go func() {
k := strconv.FormatInt(time.Now().UnixNano(),36)
if coll.Has(k) {
fmt.Println(`collision: `, k)
}
coll.Set(k,true)
defer wg.Done()
}()
}
wg.Wait()
}
The database only support 64-bit integer at maximum and doesn't support atomic counter/serial.
EDIT 2017-03-06 It has collision
collision: bb70elvagvqu
collision: bb70elwbgk98
collision: bb70elwnxcm7
So if I create a primary key using that number, converted to base-36, appended with 3 digit server key would it be no possible collision right?
Some example:
0bb4snonc8nfc001 (current time, 1st server)
1y2p0ij32e8e7zzz (maximum value: 2262-04-11 23:47:16.854775807, 46654th/last server)
Requirement 2017-03-04
- Lexicographically correct
- Unique
- As short as possible
- Ordered by creation time
答案1
得分: 1
你没有指定要使用哪个数据库,但我猜想你是指MySQL。目前我认为最好的唯一标识符是UUID,MySQL允许将其用作主键。
create table users(id varchar(36), name varchar(200));
insert into users values(uuid(), 'Andromeda');
它在任何情况下都提供了一个唯一的标识符。
当然,你也可以在其他任何数据库中使用它,因为Golang和支持它的数据库都可以。你可以在Github上找到许多用于Golang的UUID生成器。
英文:
You didn't specified which database you want to use, but I suppose to it is MySQL. The best unique ID currently I think is the UUID and the MySQL provide to use it as primary key.
create table users(id varchar(36), name varchar(200));
insert into users values(uuid(), 'Andromeda');
It is provide a unique ID in every cases.
Of course you can use it in every other database, because the Golang and databases supporting it either.
You can find many UUID generator on Github for Golang.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论