MySQL提供了多种数据类型,主要包括数值型、字符串类型、日期和时间类型。

  1.数值类型

  • 整数类型:TINYINT(1字节)、SMALLINT(2字节)、MEDIUMINT(3字节)、INT(INTEGER)(4字节)、BIGINT(8字节)
  • 浮点类型:FLOAT(4字节)、DOUBLE(8字节)
  • 定点数类型:DEC(M,D)(M + 2字节)、DECIMAL(M,D)(M+2字节)
  • 位类型:BIT(M)(1~8字节)

  (1)整数类型

  MySQL支持在类型名称后面的小括号内指定显示宽度,例如int(5)表示当数值宽度小于5位的时候在数字前面填满宽度,如果指示显示宽度则默认为int(11)。一般配合zerofill使用,zerofill就是用‘0’填充的意思,也就是在数字位数不够的空间用字符‘0’填满。

  1. mysql> create table t1(id1 int, id2 int(5));
  2. Query OK, 0 rows affected (0.01 sec)
  3.  
  4. mysql> desc t1;
  5. +-------+---------+------+-----+---------+-------+
  6. | Field | Type | Null | Key | Default | Extra |
  7. +-------+---------+------+-----+---------+-------+
  8. | id1 | int(11) | YES | | NULL | |
  9. | id2 | int(5) | YES | | NULL | |
  10. +-------+---------+------+-----+---------+-------+
  11. 2 rows in set (0.00 sec)
  12.  
  13. mysql> insert into t1 values(1,1);
  14. Query OK, 1 row affected (0.01 sec)
  15.  
  16. mysql> select * from t1;
  17. +------+------+
  18. | id1 | id2 |
  19. +------+------+
  20. | 1 | 1 |
  21. +------+------+
  22. 1 row in set (0.00 sec)
  23.  
  24. mysql> alter table t1 modify id1 int zerofill;
  25. Query OK, 1 row affected (0.06 sec)
  26. Records: 1 Duplicates: 0 Warnings: 0
  27.  
  28. mysql> alter table t1 modify id2 int(5) zerofill;
  29. Query OK, 1 row affected (0.06 sec)
  30. Records: 1 Duplicates: 0 Warnings: 0
  31.  
  32. mysql> select * from t1;
  33. +------------+-------+
  34. | id1 | id2 |
  35. +------------+-------+
  36. | 0000000001 | 00001 |
  37. +------------+-------+
  38. 1 row in set (0.00 sec)
  39.  
  40. mysql> insert into t1 values(1,1111111);
  41. Query OK, 1 row affected (0.01 sec)
  42.  
  43. mysql> select * from t1;
  44. +------------+---------+
  45. | id1 | id2 |
  46. +------------+---------+
  47. | 0000000001 | 00001 |
  48. | 0000000001 | 1111111 |
  49. +------------+---------+
  50. 2 rows in set (0.00 sec)

显示宽度与ZEROFILL

  如果插入大于宽度限制的值,例如int(5)的属性值插入为1111111,那么此时显示宽度将没有意义,而是按照实际的精度进行保存。

  UNSIGNED:所有的整数类型都有一个可选属性UNSIGNED(无符号),如果需要在字段里面保存非负数或者较大的上限值时,可以使用此选项。例如,tinyint(1字节)的有符号的范围是-128~+127,而无符号的范围就是0~255。如果一个列指定为zerofill,则MySQL自动为该列添加UNSIGNED属性。

  AUTO_INCREMENT:在需要产生唯一标识符或顺序值时,可以使用此属性,这个属性只用于整数类型。AUTO_INCREMENT值一般从1开始,每行增加1。一个表中最多只能有一个AUTO_INCREMENT列,同时该列应该定义为NOT NULL,并定义为PRIMARY KEY或者UNIQUE键。

  1. CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL PRIMARY KEY);
  2. CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(ID));
  3. CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL, UNIQUE(ID));

  (2)小数类型:浮点数和定点数

  浮点数包括float(单精度)、double(双精度),

  定点数则只有decimal一种表示,顶点数在MySQL内部是以字符串形式存放,比浮点数更精确,适合用来表示货币等精度高的数据。

  浮点数和定点数都可以用类型名称后加“(M,D)”来表示该值一共显示M位数字(整数位+小数位),其中D位位于小数点后面,M和D又称为精度和标度。

  例如,定义为float(7,4)的一个列可以显示为-999.9999,而如果要插入999.00009,则会四舍五入近似结果为999.0001

  float和double在不指定精度时,默认会按照实际的精度来显示,而decimal在不指定精度时,默认的整数位为10,默认的小数位为0

  假设在float,double,decimal中插入1.234,1.234,1.234,则前两个会按照实际精度值显示成1.234,而由于最后一个默认decimal(10,0)就会显示成1

  假设在float(5,2),double(5,2),decimal(5,2)中插入1.234,1.234,1.234,则前两个数会四舍五入为1.23,最后一个虽然会报警,然而还是按照实际精度四舍五入后插入。

  假设在float(10,2),decimal(10,2)中插入131072.32,131072.32后前一个数会插入131072.31,后一个数会插入131072.32,这是因为使用单精度浮点数产生了误差。

  如何选择合适的数据类型:

  使用浮点型数据保存小数时,会有可能产生误差。在精度要求比较高的应用中(比如货币)要使用定点数而不是浮点数来保存数据。

  (3)位类型

  位类型可以用于存放字段值,BIT(M)可以用来存放多位二进制数,M范围从1~64,如果不写则默认为1位。对于位字段,直接使用select命令将不会看到结果,可以用bin()显示为二进制格式或者hex()显示为十六进制格式函数进行读取。

  数据插入bit类型字段时,首先转换为二进制,如果位数允许,将成功插入;如果位数超过定义的位数,则插入失败。例如bit默认类型插入2会插入失败,因为2转换成二进制后是“10”,而bit默认位数为1,将bit修改成bit(2)即可插入。

  1. mysql> create table t3(id bit);
  2. Query OK, 0 rows affected (0.02 sec)
  3.  
  4. mysql> insert into t3 values(1);
  5. Query OK, 1 row affected (0.01 sec)
  6.  
  7. mysql> select * from t3;
  8. +------+
  9. | id |
  10. +------+
  11. | |
  12. +------+
  13. 1 row in set (0.00 sec)
  14.  
  15. mysql> select bin(id),hex(id) from t3;
  16. +---------+---------+
  17. | bin(id) | hex(id) |
  18. +---------+---------+
  19. | 1 | 1 |
  20. +---------+---------+
  21. 1 row in set (0.00 sec)
  22.  
  23. mysql> insert into t3 value(2);
  24. ERROR 1406 (22001): Data too long for column 'id' at row 1
  25. mysql> desc t3;
  26. +-------+--------+------+-----+---------+-------+
  27. | Field | Type | Null | Key | Default | Extra |
  28. +-------+--------+------+-----+---------+-------+
  29. | id | bit(1) | YES | | NULL | |
  30. +-------+--------+------+-----+---------+-------+
  31. 1 row in set (0.00 sec)
  32.  
  33. mysql> alter table t3 modify id bit(2);
  34. Query OK, 1 row affected (0.07 sec)
  35. Records: 1 Duplicates: 0 Warnings: 0
  36.  
  37. mysql> insert into t3 value(2);
  38. Query OK, 1 row affected (0.01 sec)
  39.  
  40. mysql> select bin(id),hex(id) from t3;
  41. +---------+---------+
  42. | bin(id) | hex(id) |
  43. +---------+---------+
  44. | 1 | 1 |
  45. | 10 | 2 |
  46. +---------+---------+
  47. 2 rows in set (0.00 sec)

bit位类型使用示例

  2.日期时间类型

  • DATE(4字节):表示年月日,1000-01-01  ~ 9999-12-31
  • DATETIME(8字节):表示年月日时分秒,1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
  • TIME(3字节):表示时分秒,-838:59:59 ~ 838:59:59
  • TIMESTAMP(4字节):需要经常插入或者更新日期为当前系统时间,19700101080001 ~ 2038年的某个时刻,但是查询显示的结果是类似“0000-00-00 00:00:00”的字符串
  • YEAR(1字节):表示年份,默认是4位格式,1901 ~ 2155

  TIMESTAMP和DATETIME的区别:

  • TIMESTAMP支持的时间范围很小,DATATIME范围更大。
  • 表中的第一个TIMESTAMP列自动设置为系统时间,如果在一个TIMESTAMP中插入null,则该列值也会自动设置该列的值为当前的时间;在插入或更新一行但不明确给TIMESTAMP赋值时也会自动设置该列的值为当前的日期和时间,当插入的值超出取值范围时,用“0000-00-00 00:00:00”填充。
  • TIMESTAMP的插入和查询都受当地时区的影响,更能反映出实际的日期,而DATATIME则只能反映出插入时当地的时区。

  日期类型的插入格式有很多种,下面的几种都是可以的(假设create table t6(dt datetime);):

  • 严格语法的字符串:insert into t6 values('2007-9-3 12:10:10');
  • 不严格语法的字符串:insert into t6 value('2007!9@3 12$10%10');
  • 没有间隔的数字字符串:insert into t6 value('20070903121010');
  • 纯数字:insert into t6 value(20070903121010);
  • 函数返回的结果:insert into t6 value(now());

  3.字符串类型

  MySQL中提供了多种对字符数据的存储类型

  (1)CHAR和VARCHAR类型

  都用来保存MySQL中较短的字符串,二者的主要区别在于存储方式的不同:

  CHAR列的长度固定位创建表时声明的长度,长度可以从0~255的任何值;而VARCHAR列中的值为可变长字符串,长度可以指定为0~255或者65536之间的值。

  在检索的时候,CHAR列删除了尾部的空格,而VARCHAR则保留了这些空格。

  如何选择合适的数据类型:

  CHAR属于固定长度的字符类型,而VARCHAR属于可变长度的字符类型。

  由于CHAR是固定长度的,所以它的处理速度比VARCHAR快得多,但是其缺点是浪费存储空间,程序需要对行尾空格进行处理,所以对于那些长度变化不大并且对查询速度有较高要求的数据可以考虑使用CHAR类型来存储。

  对于不同类型的存储引擎来说:

  • MyISAM和MEMORY:使用固定长度的数据列代替可变长度的数据列
  • InnoDB:使用VARCHAR类型。(行存储格式不区分固定和可变,并且存储容量和磁盘I/O比较好)

  (2)BINARY和VARBINARY类型

  它们包含二进制字符串而不包含非二进制字符串。在保存BINARY值时,在值的最后通过填充“0x00”以达到指定的字段定义长度。

  (3)ENUM类型

  它的值范围需要在创建表时通过枚举方式显示指定,对1~255个成员的枚举需要1个字节存储;对于255~65535个成员,需要2个字节存储。最多允许65535个成员。

  创建测试表t,定义gender字段为枚举类型,成员为'M'和'F',由结果可以看到,ENUM是忽略大小写的,当插入在'M'和'F'中间的某个值('M')和('f')时,可以成功插入,而插入一个不在ENUM成员中的值时,并没有返回警告也不会报错,而是插入了ENUM中的第一个值'M'。

  1. mysql> create table t(gender enum('M','F'));
  2. Query OK, 0 rows affected (0.01 sec)
  3.  
  4. mysql> select * from t;
  5. Empty set (0.00 sec)
  6.  
  7. mysql> insert into t values('M'),(''),('f'),(NULL);
  8. Query OK, 4 rows affected (0.00 sec)
  9. Records: 4 Duplicates: 0 Warnings: 0
  10.  
  11. mysql> select * from t;
  12. +--------+
  13. | gender |
  14. +--------+
  15. | M |
  16. | M |
  17. | F |
  18. | NULL |
  19. +--------+
  20. 4 rows in set (0.00 sec)

ENUM类型使用示例

  (4)SET类型

  SET和ENUM类型非常类似,也是一个字符串对象,里面可以包含0~64个成员。

  根据成员数量的不同,分为1~8(1字节)、9~16(2字节)、17~24(3字节)、25~32(4字节)、33~64(8字节)

  SET和ENUM最主要的区别就是SET类型一次可以选取多个成员,而ENUM只能选取一个。

  对于在set中的值,都可以被成功地插入,如果不在,就会报错;对于重复的对象,例如('a,d,a')在插入之后会去重变成“a,d”。

  1. mysql> create table setTest(col set('a','b','c','d'));
  2. Query OK, 0 rows affected (0.03 sec)
  3.  
  4. mysql> insert into setTest values('a,b'),('a,d,a'),('a,b'),('a,c'),('a'),('a,e'),('e');
  5. ERROR 1265 (01000): Data truncated for column 'col' at row 6
  6. mysql> insert into setTest values('a,b'),('a,d,a'),('a,b'),('a,c'),('a'),('a,e');
  7. ERROR 1265 (01000): Data truncated for column 'col' at row 6
  8. mysql> insert into setTest values('a,b'),('a,d,a'),('a,b'),('a,c'),('a');
  9. Query OK, 5 rows affected (0.01 sec)
  10. Records: 5 Duplicates: 0 Warnings: 0
  11.  
  12. mysql> select * from setTest;
  13. +------+
  14. | col |
  15. +------+
  16. | a,b |
  17. | a,d |
  18. | a,b |
  19. | a,c |
  20. | a |
  21. +------+
  22. 5 rows in set (0.00 sec)

SET类型使用示例

  (5)TEXT与BLOB

  一般在保存少量字符串的时候,会选择CHAR或者VARCHAR;而在保存较大文本时,通常会选择使用TEXT或BLOB。

  区别就是BLOB可以用来保存二进制数据,比如照片;而TEXT只能保存字符数据,比如一篇文章或者日记。

  TEXT又分为TEXT、MEDIUMTEXT、LONGTEXT,BLOB又分为BLOB、MEDIUMBLOB、LONGBLOB。有一些常见问题:

  • BLOB和TEXT值会引起一些性能问题,特别是在执行了大量的删除操作时。删除操作会在数据表中留下很大的“空洞”,以后填入这些“空洞”的记录在插入的性能上会有影响。为了提高性能,建议定期使用[OPTIMIZE TABLE 表名]功能对这类表进行碎片整理,避免因为“空洞”导致性能问题。
  • 可以使用合成的(Synthetic)索引来提高BLOB或TEXT的查询性能。合成索引就是根据大文本字段的内容建立一个散列值,并把这个值存储在单独的数据列中,查询的时候就可以通过检索散列值定位到数据了。这种技术只能用于精确匹配,在一定从程度上减少了I/O,提高了查询效率。如果需要对BLOB字段进行模糊查询,就可以使用前缀索引,也就是只为字段的前n列创建索引,例如create index idx on t(context(100))就是为字段的前100个字符创建索引,然后使用like进行模糊查询即可。
    1. mysql> create table t(id varchar(100), context blob, hash_value varchar(40));
    2. Query OK, 0 rows affected (0.05 sec)
    3.  
    4. mysql> insert into t values(1,repeat('beijing',2),md5(context));
    5. Query OK, 1 row affected (0.03 sec)
    6.  
    7. mysql> insert into t values(2,repeat('beijing',2),md5(context));
    8. Query OK, 1 row affected (0.01 sec)
    9.  
    10. mysql> insert into t values(3,repeat('beijing_2008',2),md5(context));
    11. Query OK, 1 row affected (0.03 sec)
    12.  
    13. mysql> select * from t;
    14. +------+--------------------------+----------------------------------+
    15. | id | context | hash_value |
    16. +------+--------------------------+----------------------------------+
    17. | 1 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 |
    18. | 2 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 |
    19. | 3 | beijing_2008beijing_2008 | ab35be94cba8e0d4c51740c5d21640d4 |
    20. +------+--------------------------+----------------------------------+
    21. 3 rows in set (0.00 sec)
    22.  
    23. mysql> select * from t where hash_value=md5(repeat('beijing_2008',2));
    24. +------+--------------------------+----------------------------------+
    25. | id | context | hash_value |
    26. +------+--------------------------+----------------------------------+
    27. | 3 | beijing_2008beijing_2008 | ab35be94cba8e0d4c51740c5d21640d4 |
    28. +------+--------------------------+----------------------------------+
    29. 1 row in set (0.00 sec)

    合成索引举例

  1. mysql> create index idx_blob on t(context(100));
  2. Query OK, 0 rows affected (0.02 sec)
  3. Records: 0 Duplicates: 0 Warnings: 0
  4.  
  5. mysql> select * from t where context like 'beijing%';
  6. +------+--------------------------+----------------------------------+
  7. | id | context | hash_value |
  8. +------+--------------------------+----------------------------------+
  9. | 1 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 |
  10. | 2 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 |
  11. | 3 | beijing_2008beijing_2008 | ab35be94cba8e0d4c51740c5d21640d4 |
  12. +------+--------------------------+----------------------------------+
  13. 3 rows in set (0.00 sec)
  14.  
  15. mysql> desc select * from t where context like 'beijing%' \G
  16. *************************** 1. row ***************************
  17. id: 1
  18. select_type: SIMPLE
  19. table: t
  20. partitions: NULL
  21. type: ALL
  22. possible_keys: idx_blob
  23. key: NULL
  24. key_len: NULL
  25. ref: NULL
  26. rows: 3
  27. filtered: 100.00
  28. Extra: Using where
  29. 1 row in set, 1 warning (0.00 sec)

前缀索引举例

  • 在不必要的时候避免检索大型的BLOB或TEXT值。select * 直接查询就不是很好的想法,除非能够确定作为约束条件的WHERE字句只会找到所需要的数据行。
  • 把BLOB或TEXT列分离到单独的表中。如果把数据列移动到第二章数据表中,可以把原数据表中的数据列转换成固定长度的数据行格式,这会减少主表中的碎片,可以得到固定长度数据行的性能优势,还可以是主数据表在执行select * 查询的时候不会通过网络传输大量的BLOB或TEXT值。

MySQL基础篇(2)数据类型的更多相关文章

  1. 【目录】mysql 基础篇系列

    随笔分类 - mysql 基础篇系列 mysql 开发基础系列22 SQL Model(带迁移事项) 摘要: 一.概述 与其它数据库不同,mysql 可以运行不同的sql model 下, sql m ...

  2. mysql基础之基本数据类型

    原文:mysql基础之基本数据类型 列类型学习 mysql三大列类型 整型 Tinyint/ smallint/ mediumint/int/ bigint(M) unsigned zerofill ...

  3. delphi基础篇之数据类型概论

    delphi基础篇之数据类型概论 Object Pascal 语言提供了非常丰富的数据类型,即简单类型(Simple).字符串类型(String).结构类型(Struct).指针类型(Pointer) ...

  4. 重新整理 mysql 基础篇————— 介绍mysql[一]

    前言 准备整理mysql的基础篇了,前面整理了sql语句序列的的<sql 语句系列(八百章)>,感觉很多用不上,就停下来了,后续还是会继续整理. mysql 基础篇主要是对一些基础进行整理 ...

  5. mysql基础篇 - 数据库及表的修改和删除

    基础篇 - 数据库及表的修改和删除         修改和删除 一.实验简介 本节实验中,我们将学习并实践如何对数据库的内容做修改,删除,重命名等操作. 二.实验准备 在正式开始本实验内容之前,需要先 ...

  6. mysql基础篇 - SELECT 语句详解

    基础篇 - SELECT 语句详解         SELECT语句详解 一.实验简介 SQL 中最常用的 SELECT 语句,用来在表中选取数据,本节实验中将通过一系列的动手操作详细学习 SELEC ...

  7. MySQL基础篇(02):从五个维度出发,审视表结构设计

    本文源码:GitHub·点这里 || GitEE·点这里 一.数据场景 1.表结构简介 任何工具类的东西都是为了解决某个场景下的问题,比如Redis缓存系统热点数据,ClickHouse解决海量数据的 ...

  8. MySQL基础篇(一)

    本文主要内容为MySQL的基础语句以及正则表达式等内容. 本文操作的数据库内容存在个人github:https://github.com/YuanGao-1/blog_demo.git init_sc ...

  9. 有评论就是我最大的动力~MySQL基础篇完结(存储引擎和图形化管理工具)

    hi 今天登上来,发现竟然有了3个评论~~加油吧! 这周的计划其实远远没有达到,然后下周还有一大堆事情...那么...周末好好玩吧~ 今天试图完结MySQL的基础篇知识,小白变为大白? 1.MySQL ...

随机推荐

  1. 代码审计之SQL注入及修复

    在新手入门web安全的时候,sql注入往往是最先上手的一个漏洞,它也是危害相当大的一个漏洞,存在此漏洞的话,将有被脱裤的风险. 以下所有代码都是我自己写的,可能有不美观,代码错误等等问题,希望大家可以 ...

  2. Docker service endpoint with name xxx already exist问题

    这是因为利用docker compose启的容器再用docker rm命令删除后,网络仍然被占用,需要手动清理 解决办法: 先用docker rm -f xxx删除容器 再输入docker netwo ...

  3. grep 命令使用

    grep是Linux中最常用的"文本处理工具"之一,用于在文本中查找指定的字符串. 语法: grep [OPTION]... PATTERN [FILE]... 参数: -i:在搜 ...

  4. springboot启动报错 Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

    新建了一个springboot项目报一下错误: Failed to configure a DataSource: 'url' attribute is not specified and no em ...

  5. 快学Scala 第十二课 (抽象类, 抽象字段, 提前定义)

    抽象类: Scala 抽象类中,抽象方法不需要使用abstract. 在子类中重写超类抽象方法时,不需要使用override. abstract class Person { def say(s: S ...

  6. SpringBoot2+Netty打造通俗简版RPC通信框架

    2019-07-19:完成基本RPC通信! 2019-07-22:优化此框架,实现单一长连接! 2019-07-24:继续优化此框架:1.增加服务提供注解(带版本号),然后利用Spring框架的在启动 ...

  7. 【流畅的python】16.1 - 生成器如何进化成协程

    在生成器中加入yield关键字后,生成器调用方可以向生成器传入值,只需要使用.send(...)方法就可以传送数据.发送的数据会成为生成器函数中yield表达式的值.所以生成器可以作为协程使用. 协程 ...

  8. 最新打赏正版V15微信视频打赏源码 带(百倍)暗雷 N秒试看 自动切换域名 自动防封

    免签支付域名防封随机跳转盒子推广设置试看N秒百倍 平台搭建:乌龟-源码科技QQ:64430146 全新版本 V15打赏版本功能介绍: 特别注意: 新增加功能!!!! 1.包括V14所有功能(除个别因优 ...

  9. scipy.misc.toimage()出现toimage报错

    scipy.misc.toimage()出现toimage报错 自己被这个问题困扰了许久,其实最后发现其实toimage这个函数已经被取消了,或者说是没有这个函数了.有了新得函数与之代替,那就是Ima ...

  10. 权限维持-wmi事件

    0x01 前言 WMIC扩展WMI(Windows Management Instrumentation,Windows管理工具),提供了从命令行接口和批命令脚本执行系统管理的支持. 在2015年的b ...