常用

存储空间

1 b(字节Byte)= 8 bit(位,存放一位二进制数,最小存储单元)
1 kb(千字节)= 1024 b(字节Byte)
1 mb(兆字节)= 1024 kb(千字节)
1 GB = 1024 mb
1 TB = 1024 GB

二进制常见平方数

2^7 -> 128
2^8 -> 256

2^15 -> 32768
2^16 -> 65536

2^31 -> 2147483648
2^32 -> 4294967296

字符编码

字符

字符可以划分为可见与不可见两种,字符可以是一个字母、数字、标点符号、汉字,表情等

// 可见字符
'a''b''我'
// 不可见字符
制表符、换行符
// 表情
😊😈

字符串

字符串由多个字符连接在一起

'abc''me, to'

字符集

字符集是一堆字符的集合,例如中文字符集由一堆汉字组成的、而英文字符集由一堆英文字母组成的

  • Unicode 字符集:Unicode 字符集被分成 17 个平面,每个平面 65536 个码位,共可容纳 110 万个字符,能够以单一的通用标准支持世界上所有的语言和文字。Unicode 已经成为现代所有操作系统、计算环境、编程语言和应用程序的字符编码的标准。

字符编码

在计算机中如果想表示字符,则需要将该字符与一个特定的二进制字节序列进行映射,这个映射的过程叫做字符编码。这种映射关系不唯一,因此存在多种编码格式。

mysql

  • 固定长度编码:不同字符的字节数量相同。例如 ASCII 采用 1 个字节编码一个字符、ucs2 采用 2 个字节编码一个字符。

  • 动态长度编码:不同字符的字节数量不同。例如 utf8 采用 1~3 个字节编码一个字符、gb2312 采用 1~2 个字节编码一个字符。

    utf8 在 mysql 中进行了阉割,正规 utf8 采用 1-4 个字节编码一个字符,是 Unicode 字符集最主流的编码方式,在 mysql 中称为 utf8mb4

    utf32 采用 4 字节固定长度编码、utf16 采用 2 字节和 4 字节动态长度编码,目前基本弃用

    // utf8 编码的字节序列
    11100110 10001000 10010001 // -> 3个字节编码字符 '我'
    

1.整数

在内存中直接存储每位整数,有符号整数采用第一位作为符号位

类型存储空间无符号范围有符号范围概念
TINYINT1b0 ~ 2^8-1-2^7 ~ 2^7-1最小整数
SMALLINT2b0 ~ 2^16-1-2^15 ~ 2^15-1小整数
MEDIUMINT3b0 ~ 2^24-1-2^23 ~ 2^23-1中整数
INT 或 INTEGER4b0 ~ 2^32-1-2^31 ~ 2^31-1整数
BIGINT8b0 ~ 2^64-1-2^63 ~ 2^63-1大整数

2.浮点数

非精准小数,在内存中按照符号位、指数位、尾数位存储浮点数

类型存储空间无符号范围有符号范围概念
FLOAT(M,D)4b±1.175494351E-38±3.402823466E+38单精度浮点数
DOUBLE(M,D)8b±2.2250738585072014E-308±1.7976931348623157E+308双精度浮点数
  • M:范围 1~255(默认为机器支持的最大值),该数十进制有效数字最大个数,-2.3 为 2、0.9 为 1

  • D:范围 0~30(默认为机器支持的最大值),该数小数部分的十进制数字个数,1.25 为 2,0.9 为 1

    FLOAT(4, 0) // 取值范围:-9999~9999
    FLOAT(4, 1) // 取值范围:-999.9~999.9
    FLOAT(4, 2) // 取值范围:-99.99~99.99
    

十进制转二进制

/**
 * 整数:除二取余法 + 逆序排列
 * 小数:乘二取整法 + 顺序排列
 */
9.875 = 1*2^3 + 0*2^2 + 0*2^1 + 1*2^0 + 1*2^-1 + 1*2^-2 + 1*2^-3 = 1001.111

计算机存储小数

计算机按科学计数法 a * 2^n 存储二进制数

/**
 * 符号位:1
 * 尾数位:001111
 * 指数位:3
 */
1001.111 = 1.001111 * (2 ^ 3)

浮点型存储结构

存储结构:符号位(1bit)+ 指数位(根据精度决定)+ 尾数位(根据精度决定)。浮点数使用字节越多,代表尾数和指数的范围越大。

缺陷:由于小数部分采用 乘二取整,例如 0.25、0.5 这种小数可以快速归 1 获取到准确结果,而 0.1、0.2 这种小数永远不能获取准确结果从而进入死循环,js 根据 IEEE 754 规范,对第 53 位尾数进行了 0 舍 1 入,这是计算机浮点数运算出现误差的本质(其他语言也一样)

解决方法:通常将小数转换为整数进行运算,再转换为小数。

image-20230604105539154

  • 单精度浮点数格式:符号位(1bit)+ 指数位(8bit)+ 尾数位(23bit)
  • 双精度浮点数格式:符号位(1bit)+ 指数位(11bit)+ 尾数位(52bit)

3.定点数

精准小数,在内存中整数、小数都按照整数分组存储,其中一组为 9 个十进制数

类型存储空间无符号范围有符号范围概念
DECIMAL(M,D)根据 M、D 动态变化根据 M、D 动态变化根据 M、D 动态变化精准小数
  • M:范围 1~65(默认为 10),整数部分的十进制数字个数

  • D:范围 0~30(默认为 0),小数部分的十进制数字个数,D 不能大于 M

    /**
     * 整数:12位
     * 小数:4位
     * 存储空间:2b + 4b + 2b = 8b
     */
    DEMCIMAL(16, 4);
    // 1.将十进制数字划分为3组
    1234567890.1234 = 1 234567890 1234
    // 2.用二进制转换每一组数据进行存储
    1 = 00000000 00000001 // 2字节 16bit
    234567890 = ... // 4字节 32bit
    1234 = .... // 2字节 16bit
    // 3.对于正数需要将最高位设置为1,对于负数将每一个 bit 按位取反
    

存储空间

每组十进制位数存储空间
1 ~ 21b
3 ~ 42b
5 ~ 63b
7 ~ 94b

4.无符号数

对于确定的非负整数、浮点数、定点数,可以采用无符号数声明

# 语法
数值类型 UNSIGNED
# 示例
INT UNSIGNED
FLOAT UNSIGNED
DECIMAL UNSIGNED
  • 正数:通过 UNSIGNED 声明可以让正数范围扩大一倍
  • 浮点数、定点数:受限于存储格式,UNSIGNED 不会影响正数范围

5.日期时间

MySQL5.6.4 之后,TIMEDATETIMETIMESTAMP 添加了对毫秒、微秒的支持

类型存储空间取值范围概念
YEAR1b1901 ~ 2155
DATE3b'1000-01-01' ~ '9999-12-31'日期
TIME3b'-838:59:59' ~ '838:59:59'时间
DATETIME8b'1000-01-01 00:00:00' ~ '9999-12-31 23:59:59'日期 + 时间
TIMESTAMP4b'1970-01-01 00:00:01' ~ '2038-01-19 03:14:07'时间戳

FORMAT

# 语法
YYYY:年
MM:月
DD:日
hh:时
mm:分
ss:秒
uuuuuu:小数秒

对比

  • TIME:代表时间,格式 hh:mm:ss[.uuuuuu]
  • DATETIME:代表日期时间,格式 YYYY-MM-DD hh:mm:ss[.uuuuuu]
  • TIMESTAMP:代表时间戳,指某个时刻距离 1970-01-01 00:00:00 的秒数。该类型相对 DATETIME 的优点在于可以跟随时区的变化而变化

声明小数秒位

TIME(1) # '13:54:32.1'
DATETIME(1) # '2023-06-04 13:54:32.1'
TIMESTAMP(1)

额外存储空间

声明小数秒位额外需要的空间

小数秒位额外存储空间
00b
1 ~ 21b
3 ~ 42b
5 ~ 63b

6.字符串

类型存储空间取值范围概念
CHAR(M)L = M * W(不同编码格式一个字符所需字节)固定 M 个字符(0~255,默认 1)固定长度字符串
VARCHAR(M)L + 1 / 2最多 M 个字符(1~65535)可变长度字符串
TINYTEXTL + 12^8-1 个字符最小字符串
TEXTL + 22^16-1 个字符小字符串
MEDIUMTEXTL + 32^24-1 个字符中字符串
LONGTEXTL + 42^32-1 个字符大字符串

受限字符串

  • CHAR(M):如果 M 为 0,只能存储空字符串 ''NULL。若字符实际占用空间 < 声明存储空间,剩余部分用空字符串 '' 补齐

    占用字节数:M * W = L 字节
    
  • VARCHAR(M):包含占用字节数和字符串内容,MySQL 中某一行中每列存储的数据大小不得超过 65535 个字节,因此理论上 M 不会大于 65535,VARCHAR 占用字节数的临界值为 256

    占用字节数:L < 256 ? 1 : 2
    

不受限字符串

TINYTEXTTEXTMEDIUMTEXTLONGTEXT 不受 MySQL 中某一行中每列存储的数据大小不得超过 65535 个字节的限制

7.枚举

在给定的字符串列表里选择一个或多个

类型存储空间取值范围概念
ENUM(值, 值, ...)枚举单选
SET(值, 值 ...)枚举多选

8.二进制数据

对于图片、音频、文件这类二进制数据,一般采用文件系统存储,然后在数据库存储文件路径即可

类型存储空间取值范围概念
BIT(M)比特数据
BINARY(M)固定长度 binary 数据
VARBINARY(M)可变长度 binary 数据
TINYBLOB最小 blob 数据
BLOB小 blob 数据
MEDIUMBLOB中 blob 数据
LONGBLOB大 blob 数据
此文档贡献者: 嗷大张