数据库建表时才知道我多菜

最近建库设计表,弄得有点不自信了,好久没干过这种细活了,真是家狗吃不了细糠不是; 下面咱就说道说道这个编码格式及所需字节数之间的关系,一起坐好,上课;

(以下内容均来自于网络学习及ai回答,没深入细节,没深入细节,没深入细节,不对的地方,大佬们一定要指正)

数据库编码格式

首先说下,咱们目前常用的数据库编码格式,其他字符咱没用过也没见过就不瞎说了。 ISO 8859-1 GB2312 GBK GB18030 UTF8 UTF16 UTF32 还有个啥UTF8mb4;太多了,是不是,先过滤下。 看下u8家族的,当我们在设计数据库时,Unicode码与我们的数据库并不是一一对应的,直接看结果:

UTF8

数据库中UTF8(实际叫utf8mb3)不等于UTF-8,"utf8"只支持每个字符最多3个字节, 对于超过3个字节的字符就会出错,而我们的汉字虽然通常在utf8的情况下占三个字节,但是存在占用四个字节的情况,且某些特殊符号也是四个字节,所以utf8淘汰。

UTF-8

UTF-8支持1-4个字节,其最小单元是1个字节,也有说它支持最大6个字节

utf16

utf16的每个字符必须是2个字节或者4个字节,而UTF编码在最小单元为多字节中存在字节顺序的问题, 所以UTF-8没这个困扰,但是utf16最小是2字节,所以我们也pass掉吧,费神不是;

utf32

utf32呢直接一个字符四个字节,但是呢我们的库表并不需要简单粗暴的定长,而是尽量最优使用存储空间(可以参考oracle);

utf8mb4

数据库里的utf8mb4有说他就是纯正的UTF-8,特性类似于UTF-8;(我以前根本不懂这玩意,就在哪看过说utf8mb4支持emoj我就用它了,没想到是对的); 那最终我们mysql层面u8家族的就剩一个utf8mb4能打了。 再说一下我们的utf8mb4什么时候是一个字节呢,就是内容在ASCII编码范围内(就是128个字母数字符号)的时候是一个字符;

下面这几个一般在oracle上用了(如果mysql也用就当我没说过这句话)

ISO 8859-1

占用一个字节,不支持汉字等其他字符,所以直接淘汰

GB2312(国标)

汉字占用2个字节,非汉字字符(如字母、数字、标点符号等)占用1个字节主要覆盖简体汉字,(对汉字支持不够全面)所以直接淘汰;

GBK(国标扩展)

兼容GB2312,所需字节数与GB2312一样,GB2312中的字符在GBK中有相同的编码,相对于GB2312添加了繁体字,生僻字,东亚其他文字的支持;(有时我们会使用它)

GB18030

ai给的评价是基本覆盖了中国所有的汉字(包括少数民族文字)和常用字符需求;(我的想法是正常普通业务不需要这么大的,如果你喜欢当我没说)

好了,不同编码格式存储数据所需要的字节数我们差不多知道了吧,下面我们再看看mysql那些讨人厌的字段类型各自的字节数。

数据库字段类型

我直接复制网上一份过来 MySQL 字段类型可以简单分为三大类

  • 数值类型:整型(TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT)、浮点型(FLOAT 和 DOUBLE)、定点型(DECIMAL)
  • 字符串类型:CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB 等,最常用的是 CHAR 和 VARCHAR。
  • 日期时间类型:YEAR、TIME、DATE、DATETIME 和 TIMESTAMP 等。

DATETIME 和 TIMESTAMP

先捡简单的说:日期类型其实我们常用的就两个DATETIME 和 TIMESTAMP,其他三个就是字面意思年份、时间、日期; 这两个说实话大差不差哈,平时我们都用,整体区别就是DATETIME占八个字节,而 TIMESTAMP占四个字节,DATETIME表示的时间范围更广,TIMESTAMP能表示到2038年,但其可以随时区变化; 接着看我们的字符串类型,我此处捡常用的说

char 和 varchar

简单说就是char是不可变长度,但是varchar是可变长度,这么看好像没啥区别,比如说我们数字类型的字典,那我给varchar(1)岂不是更方便,然后我一顿捣鼓,终于发现存储的区别,varchar会用字节空间来记录字符长度 ,而char是定长的,不需要记录,这就会让mysql在sql优化的时候会考虑这种情况,所以总能看到前人的总结,固定字符数的用char,字符数不固定就用varchar,有人说char属性的字段如果字符不够会空格填充,又有人说填充仅限于oracle;注意哈,虽然char(1)表示一个字符空间,但是存储依然只能存储一个值哈,简单理解就是它叫字符个数,varchar同理一样;总结下哈,定长(char),可变长(varchar);

整型

这里TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT我就不拆开说了,下图简单看就是一个字节能存储范围是255,那两个就是255*255,依次类推

数据类型 存储大小(字节) 有符号取值范围 无符号取值范围
TINYINT 1 -128 到 127 0 到 255
SMALLINT 2 -32768 到 32767 0 到 65535
MEDIUMINT 3 -8388608 到 8388607 0 到 16777215
INT 4 -2147483648 到 2147483647 0 到 4294967295
BIGINT 8 -9223372036854775808 到 9223372036854775807 0 到 18446744073709551615

那我们经常定义整型字段后面那个位数是啥比如int(M)的M是啥,怎么说呢,你就当它毫无用处吧,因为有说他们表示的是显示宽度,但是mysql8又不推荐了,所以咱们就当不存在,总结就是这里选择的话看你要表示的范围选取合适的,不用管数据库建表时的长度配置;

浮点型

给我说我就是不推荐,反驳的理由就是精度无法保证,想要精度就别用他,不在乎精度更没必要用它,当然,如果你就说普通的精度控制其实也可以用,但是给我我不会废这个脑子去思考,其实这两个的精度控制在mysql中我欣赏不来,可能是我navicat问题,我还是喜欢在plsql上操作oracle中double的感觉。举例double(M,D)中 M=整数位+小数位,D=小数位;

DECIMAL

我也是第一次知道这个叫定点数,DECIMAL(M,D)表示M是最大位数(精度)(整数位+小数位+小数点),范围是1到65。可不指定,默认值是10。 D是小数点右边的位数(小数位)。范围是0到30,并且不能大于M,可不指定,默认值是0,

相关推荐
未秃头的程序猿13 分钟前
Java 26正式发布!这3个新特性,让代码量直接减半
java·后端·面试
小旭Coding35 分钟前
卧靠!Go 传给前端的 int64 竟然变成了这个?
后端
用户2986985301436 分钟前
Word 文档文本查找与替换的 Java 实现方案
java·后端
kunge201339 分钟前
深度剖析Claude Code 的CLAUDE.md加载逻辑
后端·vibecoding
米沙AI40 分钟前
MSYS2 快速使用版本
后端
Csvn1 小时前
Docker 进阶 — 网络模型、数据持久化与多阶段构建
后端
用户4279254051711 小时前
《微博开放平台官方CLI开源了:70+API一行搞定,AI Agent原生支持》
后端
Csvn1 小时前
文本处理三剑客 — grep、sed、awk 实战精讲
后端
sarasuki1 小时前
JavaScript的对象、new的机制与原型包装类
javascript·后端