本文主要讲mysql的时间类型在磁盘上的存储结构(innodb)
mysql时间类型主要有如下几种 (5.6.4之后的版本)
类型 | 占用空间 | 字节序 | 取值范围 |
---|---|---|---|
date | 3 | 大端 | '1000-01-01' to '9999-12-31' |
time(n) | 3+N | 大端 | '-838:59:59.000000' to '838:59:59.000000' |
datetime(n) | 5+N | 大端 | '1000-01-01 00:00:00.000000' to '9999-12-31 23:59:59.999999' |
timestamp(n) | 4+N | 大端 | '1970-01-01 00:00:01.000000' UTC to '2038-01-19 03:14:07.999999' |
N的取值来自于n(fractional-seconds), 关系如下
N = int((n+1)/2)
n | N |
---|---|
0 | 0 |
1,2 | 1 |
3.4 | 2 |
5,6 | 3 |
从左到右为:
1 bit sign
14 bit year
4 bit month
5 bit day
一共24bit, 就是3字节
怎么取出来呢? 这里使用python演示一下
year = ((date & ((1 << 14) - 1) << 9) >> 9)
# 构造出需要的长度14位的1. (1 << 14) - 1)
# 将构造好的数据移动到对于的位置,这里就是向左移动9位, 就是23<-->9
# 与目标数做与运算 得到 除了23<-->9 位的数不变外, 其它数均为0. 1与(1/0)得(1/0) 0与(1/0)得0
# 将与后的数据, 去掉后面的0, (右移9位, 就是刚才左移的9位).
从左到右为
1 bit sign
11 bit hour (实际上是10bit, 还有位是保留位, 不过不影响取值..)
6 bit minute
6 bit second
一共就是24bit, 3字节
1bit符号 year_month:17bit day:5 hour:5 minute:6 second:6
year = int(year_month/13)
month = int(year_month%13)
这个就是秒数(uint32), 直接取值即可
int.from_bytes(bdata[:4],'big')
如果固定时间类型后面还有数据,则是分秒(小数部分的秒fraction
)
大端,直接取值即可.比如:
fraction = int.from_bytes(bdata[4:],'big') if len(bdata)>4 else None
参考: https://dev.mysql.com/doc/refman/8.0/en/storage-requirements.html
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。