Mysql关于timestamp 和 datetime
原视频 | 实际上 |
---|---|
timestamp占用四个字节 | timestamp占用四个字节 |
datetime占用八个字节 | datetime占用 5字节如果没有毫秒部分 6字节毫秒精度为 2 位 7字节毫秒精度为4位 8字节毫秒精度为6位 |
timestamp时间范围1000-9999年 | 至少公元1年-9999年(具体代码中有测试) |
datetime时间范围 | 1970-2038年 |
对于这个所谓的老师 还发过另一条错误的回答,具体原文找不到了也可能是他自己悄悄删除了,但是我当时的回答如下:
- timestamp 还是 datetime 在任意一种 sql 中都不可能存储的字符串, 而是存储的时间点, 不同的是 datetime 存储的是 5 个 byte, 而粒度是毫秒. 而 timestamp 存储的是时间戳, 即数字 0 等于 1970.1.1, 1970 以前的时间用负数, 以后的时间用正数, 最小粒度是秒, 是一个 32bit 4 字节长度的 int, 有符号整形.
- timestamp 的范围肯定不是 1970 起始, 因为负数也可以表示时间.
- 它们的使用方式在于需要时间的精度. 以秒为计的可以使用 timestamp. 而以毫秒为小粒度则需要以 datetime. 它们都可以精确的表示任意的一个时间. timestamp 是 utc 时间, 而 datetime 则使用的 gmt 格尼威治时间本地化需要加减时区*3600.
附测试代码
func TestSetTime(t *testing.T) {
zero := "1970-01-01 00:00:00"
negative := "1000-01-01 00:00:00"
positive := "2039-01-01 00:00:00"
max:="9999-12-31 23:59:59"
d0, t0 := Time2Data(zero)
r1 := new(model.Range)
r1.TimeStamp = t0
r1.Datatime = d0
r1.InsertOne()
d1, t1 := Time2Data(negative)
r2 := new(model.Range)
r2.TimeStamp = t1
r2.Datatime = d1.AddDate(-10, 0, 0)
r2.InsertOne()
d2, t2 := Time2Data(positive)
r3 := new(model.Range)
r3.TimeStamp = t2
r3.Datatime = d2
r3.InsertOne()
d3,t3:=Time2Data(max)
r4:=new(model.Range)
r4.TimeStamp=t3
r4.Datatime=d3
r4.InsertOne()
outofrange:=d3.AddDate(10,0,0)
r5:=new(model.Range)
r5.Datatime=outofrange
r5.TimeStamp=t3
r5.InsertOne()
}
func Time2Data(formatTime string) (time.Time, int64) {
loc, _ := time.LoadLocation("Local")
t, _ := time.ParseInLocation("2006-01-02 15:04:05", formatTime, loc)
timestamp := t.Unix()
return t, timestamp
}
张嘴闭嘴bitmap
然后故意忽略最重要一步
十亿个位图数据结构 用户信息表还得有十亿条关系记录?
我为什么不设置一个48小时过期的string?key是用户uid value是用户连续登录天数 如果用户uid不存在就创建一个新的key=1 如果用户uid存在value就INCR key?
因为
数据量
- bitmap:30 keys,根据所需天数确定,也可以每天新增,老的归档处理,最大支持2^32个用户
- id key:n keys,按2%算活跃用户,一亿就得2百万
查询效率 - bitmap:O(1)
- id key: O(1)
数据安全性 - bitmap:每天数据独立,旧数据可备份冗余
- id key:每个用户数据独立,但每天都有可能更新,备份冗余有同步问题要处理
业务灵活性 - bitmap:知道具体某一天在或不在
- id key:并不知道具体哪天在或不在