UnixNano与服务器ID连接在一起作为主键是否是一个好的选择?

huangapple go评论77阅读模式
英文:

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 (
        &quot;fmt&quot;
        &quot;sync&quot;
        &quot;time&quot;
        &quot;strconv&quot;
        &quot;github.com/OneOfOne/cmap&quot;
)

func main() {
        var wg sync.WaitGroup
        k := 1000
        wg.Add(k * 1000)
        coll := cmap.New()
        for z := 0; z &lt; 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(), &#39;Andromeda&#39;);

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.

huangapple
  • 本文由 发表于 2017年3月3日 12:19:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/42570585.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定