Mysql关于timestamp 和 datetime

原视频 实际上
timestamp占用四个字节 timestamp占用四个字节
datetime占用八个字节 datetime占用
5字节如果没有毫秒部分
6字节毫秒精度为 2 位
7字节毫秒精度为4位
8字节毫秒精度为6位
timestamp时间范围1000-9999年 至少公元1年-9999年(具体代码中有测试)
datetime时间范围 1970-2038年

对于这个所谓的老师 还发过另一条错误的回答,具体原文找不到了也可能是他自己悄悄删除了,但是我当时的回答如下:

  1. timestamp 还是 datetime 在任意一种 sql 中都不可能存储的字符串, 而是存储的时间点, 不同的是 datetime 存储的是 5 个 byte, 而粒度是毫秒. 而 timestamp 存储的是时间戳, 即数字 0 等于 1970.1.1, 1970 以前的时间用负数, 以后的时间用正数, 最小粒度是秒, 是一个 32bit 4 字节长度的 int, 有符号整形.
  2. timestamp 的范围肯定不是 1970 起始, 因为负数也可以表示时间.
  3. 它们的使用方式在于需要时间的精度. 以秒为计的可以使用 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:并不知道具体哪天在或不在