有一个简单的使用场景,即用户在一个设备上,会反复添加条目,例如一个 TODO 项。除了自增 ID 之外,我还想加上另外一个唯一标识。由于同一时间,用户只能添加一条记录,所以不会出现并发冲突的问题。

能想到的最简单方案就是使用时间戳。于是调研了一下可行性。

golang int 的值范围

  • int32: -2147483648 到 2147483647。大概 21 亿
  • int64: -9223372036854775808 到 9223372036854775807

以秒为单位的时间戳的数值大小

但是用时间戳,会遇到 2038 问题,即 2038 后,时间戳会超出 int32 的存储范围。虽然距离 2038 年还很遥远。。。但是我觉得还是严谨一点比较好。

The Year 2038 problem (also called Y2038 or Y2k38 or Unix Y2K) relates to representing time in many digital systems as the number of seconds passed since 00:00:00 UTC on 1 January 1970 and storing it as a signed 32-bit integer. Such implementations cannot encode times after 03:14:07 UTC on 19 January 2038. Similar to the Y2K problem, the Year 2038 problem is caused by insufficient capacity used to represent time.The latest time since 1 January 1970 that can be stored using a signed 32-bit integer is 03:14:07 on Tuesday, 19 January 2038 (231-1 = 2,147,483,647 seconds after 1 January 1970).

package main

import (
	"fmt"
	"time"
)

func main() {
	t := int32(time.Now().Unix())
	fmt.Println(t)
}

> 1257894000

不如用 datetime 的可读格式 200816220256精确到秒,这样可读性好,且不容易重复。不行,超了 Int32 的范围。

结论

哎,还是用自增 id 吧,从 -1 开始加到 -N 吧。

tags: 时间戳 2038 问题