MySQL数据类型

原则

1. 更小的通常更好

尽可能使用正确存储数据的最小数据类型,较小的内存、磁盘和CPU缓存,并且CPU时间更少

2. 简单就好

简单的数据类型占用更少的cpu周期。如:

  • 存储时间尽量用MySQL内置的datetime类型
  • 存储IP可以用整数

3. 尽量避免使用NULL

通常情况下最好指定列为Not NULL, 除非真的需要。

  • 查询中包含NULL的列,对MySQL来说,优化更难,因为可为NULL的列使索引、索引统计、值比较都更复杂
  • 如果计划对列加索引,应该避免设计成可为NULL的列
  • InnoDB存储引擎使用单独的位(bit)存储NULL值,对稀疏数据(很多值为NULL,只有少量非NULL值)具有很好的空间效率

SHOW CREATE TABLE shop_suborder

  • 显示创建shop_suborder的语句,字段类型均为基本类型

整数类型

INT(11) 对大多数应用是无意义的,不会限制值的范围,只是规定了一些交互工具(如客户端)显示字符的个数,即int(11) == int(20)

  • TINIINT

8 bit ,存储-2^7 ~ 2^7-1 ,即-128~127
加上UNSIGNED 属性 0~255

  • SMALLINT

16 bit

  • MEDIUMINT

24bit

  • INT

32bit 存储 -2147483648 ~ 21 4748 3647

  • BIGINT

64bit
存储 -9223372036854775808L ~ 922 3372 0368 5477 5807L


实数类型

DECIMAL

  • 尽量只在对小数点进行精确计算时才使用DECIMAL---如财务数据
  • 允许最多存储65个数字
  • 5.0以上MySQL版本DECIMAL 支持精确计算
  • 可指定小数点前后允许的最大位数
  • 数据量较大时,可用BIGINT代替,乘以相应倍数

FLOAT

  • 4个字节存储

DOUBLE

  • 8个字节存储,比DECIMAL更少的存储空间
  • 比FLOAT更高的精度,更大范围
  • MySQL内部 使用DOUBLE作为内部浮点计算的类型

字符串类型

  1. 每个 字符串列 可以定义自己的 字符串集合 和 排序规则(校验规则)
  2. VARCHAR、CHAR存储和具体的存储引擎有关

VARCHAR

  • 存储可变长字符串
  • 仅使用必要的空间,对性能有帮助(ROW_FORMAT=FIXED则每行都定长存储,浪费空间)
  • 在更新时若变长则需要额外工作
  • 需要1或2个额外字节记录字符串的长度,如VARCHAR(10) 需11字节存储空间
  • 以下情节使用VARCHAR合适:
    1. 字符串的 最长平均长度 大很多
    2. 列的更新很少,碎片不是问题
    3. 使用了utf-8这样复杂的字符集
  • 5.0以后,存储和检索会保留末尾空格
  • InnoDB把过长的VARCHAR存储为BLOB
  • VARCHAR(5) 和 VARCHAR(100)存储‘hello'是一样的,但是更长的列会消耗更多的内存,尤其是实用内存表进行排序或操作时会特别糟糕——只分配需要的空间

CHAR

  • 定长,MySQL分配足够的空间
  • 删除末尾空格
  • 非常适合存储密码的MD5值
  • 对于经常变更的数据,不易产生碎片
  • 如CHAR(1) 占1个字节,VARCHAR(1)占2个字节(记录长度的额外字节)
BINARY和VARBINARY
  • 二进制字符串
  • 存储的是字节码
  • 二进制 比 字符比较简单很多

BLOB

  • 二进制很大的字符串
  • MySQL把每个BLOB和TEXT当做一个独立的对象处理
  • 没有排序规则和字符集

TEXT

  • 有排序规则和字符集
  • 尽量避免使用TEXT 和 BLOB
TIPS:

EXPLAIN 执行计划的Extra列包含 Using temporary 说明查询使用了隐式临时表

枚举 ENUM

  • 有时可用枚举列代替常用的字符串类型
  • MySQL存储枚举时非常紧凑,内部将每个值在列表中的位置保存为整数
  • 在.frm 文件中保存‘数字--字符串’的映射关系
  • 排序时是按保存的整数排序,而非字符串
  • 在添加或删除字符串时必须使用ALTER TABLE
  • VARCHAR/CHAR ---关联--- ENUM 比 VARCHAR/CHAR ---关联-- VARCHAR/CHAR慢
  • 如果不是必须关联,则使用ENUM比较好

日期和时间

  • Mysql能存储的最小时间粒度--秒
  • BIGINT可用来存储微秒级别的时间戳,或者DECIMAL的小数部分

DATATIME

  • 1001年--9999年,精确到秒
  • 8个字节
  • 可排序、无歧义
  • UNIX_TIMESTAMP() 函数将日期转化成时间戳

TIMESTAMP

  • 4字节
  • 表示范围比DATETIME小很多:1970年-2038年
  • 时区相关
  • FROM_UNIXTIME() 函数将时间戳转化成日期
  • TIMESTAMP列默认Not NULL,与其他数据类型不同
  • 空间效率更高

位数据类型

BIT

  • 在一列中存储一个或多个true/false值
  • 行为与存储引擎有关
  • MySQL将BIT当作字符串类型,而非数字类型
  • 谨慎使用BIT类型
  • 存储一个true/false值可创建CHAR(0)列

SET

  • 保存很多true/false值可将这些列合并到一个SET数据类型
  • 打包的位的集合表示,有效利用存储空间
  • FIND_IN_SET()、FIELD()这样的函数方便在查询中使用
  • 改变列的代价高,需要ALTER TABLE
  • 可以将8个位包装到一个TINIINT中,按位操作来使用----保存权限的访问控制列表

为标识列选择数据类型

如关联查询的比较列、外键等

  • 应选择和关联表中对应列一样的数据类型,类型间需要精确匹配
  • 预留未来增长空间的前提下,选择最小的数据类型
  • 整数通常是标识列最好的选择--可用AUTO_INCREAMENT
  • 应避免用字符串类型作标识列,因为很消耗空间,并且比数字类型慢
  • MD5(), UUID(), SHA1()生成的字符串分布在很大空间,会导致INSERT以及一些SELECT很慢
    1. 插入随机写到索引的不同位置,所以INSERT慢,聚簇存储引擎会产生聚簇索引碎片
    2. SELECT语句慢,逻辑相邻的行会分布在磁盘和内存的不同地方
    3. 随机值导致霍村对所有类型的查询效果都差
  • 若存储UUID值,应移除“-”,用UNHEX()函数转换为16字节,并存储在BINARY(16)列中,检索是可通过HEX()函数格式化为十六进制格式
  • UUID虽然分布不均匀,但也还是有一定顺序的,但还不如递增的整数好用

特殊数据类型

IP存储

  • 经常使用VARCHAR(15)存储IP,然而:
  • IPV4实际上是32位无符号整数,不是字符串,应使用无符号整数存储IP
  • MySQL提供INET_ATON() 和 INET_NTOA()转换IP地址和整数
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容