2017-03-03 116 views
2

我试图从Go的UnixNano生成10k整数,并且不显示任何冲突。UnixNano与服务器ID串联在一起是一个很好的主键吗?

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位整数,不支持原子计数器/串行。

EDIT 2017年3月6日,具有碰撞

collision: bb70elvagvqu 
collision: bb70elwbgk98 
collision: bb70elwnxcm7 

所以,如果我创建使用该号码的主键,转换到基座-36,用3位的服务器密钥所附这将是没有可能的碰撞吧?

一些示例:

0bb4snonc8nfc001 (current time, 1st server) 
    1y2p0ij32e8e7zzz (maximum value: 2262-04-11 23:47:16.854775807, 46654th/last server) 

要求2017年3月4日

  • 字典顺序正确
  • 独特
  • 尽可能短
  • 下令创建时间
+0

当闰秒或只是计算机时钟被ntp调整时会发生什么? – ymonad

+1

你可以使用UUID而不是自己滚动吗? http://stackoverflow.com/questions/15130321/is-there-a-method-to-generate-a-uuid-with-go-language – stderr

+1

这看起来像一个半实施雪花想法给我。查看https://github.com/bwmarrin/snowflake – tsdtsdtsd

回答

1

您没有指定要使用哪个数据库,但我认为它是MySQL。目前我认为最好的唯一ID是UUID,MySQL提供将它用作主键。

create table users(id varchar(36), name varchar(200)); 
insert into users values(uuid(), 'Andromeda'); 

它在每种情况下都提供一个唯一的ID。

当然,您可以在其他数据库中使用它,因为Golang和数据库都支持它。 你可以在Gitub上找到许多用于Golang的UUID生成器。

相关问题