Mysql的数据类型

MySQL数据类型
数据类型是数据的一种属性,其可以决定数据的存储格式,有效范围和相应的限制。mysql的数据类型包括整数类型,浮点数类型,日期和时间类型,字符串类型和二进制类型。
为什么定义数据类型?为什么要数据分类?
1、使系统能够根据数据类型来操作数据。
2、预防数据运算时出错。
例:通过强大的数据分类把每个类型与特定的行为联系在一起,执行这些行为时,数据分类可以预防错误。最长见的错误是字符与数字相加。
3、更有效的利用空间。数据分类,可以使用最少的存储来存放数据,同时提高性能。
数据类型解释
MySQL中定义数据字段的类型对你数据库的优化是非常重要的。
MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。
数值类型

充分利用空间,
日期和时间类型

字符串类型

在MySQL中支持的5个主要整数类型是 TINYINT,SMALLINT,MEDIUMINT,INT和BIGINT。这些类型在很大程度是相同的,只有他们存储的值的大小是不同的。
数据类型的测试
mysql> create database test_db;
Query OK, 1 row affected (0.00 sec)
mysql> use test_db;
Database changed
测试取值范围
mysql> create table kdata ( fti tinyint,fsi smallint,fmi mediumint ,fi int, fbi bigint);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into kdata values (123456789,123456789,123456789,123456789,123456789);
ERROR 1264 (22003): Out of range value for column ‘fti’ at row 1
错误1264(22003):第1行“fti”列的值超出范围,对于不符合的数据报错
mysql> insert into kdata values (123,12345,1234567,123456789,123456789);
Query OK, 1 row affected (0.00 sec)
mysql> select * from kdata;

插入错误的值
mysql> create table kdata2 (age int) ;
Query OK, 0 rows affected (0.06 sec)
mysql> insert into kdata2 values (‘hello’ );
ERROR 1366 (HY000): Incorrect integer value: ‘hello’ for column ‘age’ at row 1
int类型修饰符
unsigned 无符号整数,修饰符: 规定字段只能保存正的数据。它可以增大这个字段的正数支持的范围。
zerofill 修饰符: 规定0(不是空格 ) 填补输出的值。 使用这个值可以防止 mysql存储负值。
unsgined和zerofill使用方法
mysql> create table kdata3 (fi int,fiu int unsigned, fiz int zerofill,fiuz int unsigned zerofill);
Query OK, 0 rows affected (0.01 sec)
查看表结构:
mysql> desc kdata3;

注意:发现fiz和fiuz字段值是一样的。
查看原因:
mysql> show create table kdata3;

测试:
mysql> insert into kdata3 values (10,10,10,10);
Query OK, 1 row affected (0.00 sec)
mysql> insert into kdata3 values (-10,-10,-10,-10);
ERROR 1264 (22003): Out of range value for column ‘fiu’ at row 1
mysql> insert into kdata3 values (-10,10,-10,-10);
ERROR 1264 (22003): Out of range value for column ‘fiz’ at row 1
mysql> insert into kdata3 values (-10,10,100,-10);
ERROR 1264 (22003): Out of range value for column ‘fiuz’ at row 1
mysql> insert into kdata3 values (-10,10,100,1000);
Query OK, 1 row affected (0.00 sec)
可以看见在fiu,fiz和fiuz中存储负数,直接报错,因为unsgined和zerofill不允许使用负值,zerofill会自动添加unsgined,并且在数值前面补0

注意:
int(M) 在 integer 数据类型中,M 表示最大显示宽度。
在 int(M) 中,M 的值跟 int(M) 所占多少存储空间并无任何关系。 int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。其实,除了显示给用户的方式有点不同外,int(M) 跟 int 数据类型是相同的。
如int的值为10
int(10)显示结果为0000000010
int(3)显示结果为010
就是显示的长度不一样而已 都是占用四个字节的空间,可以使用的空间也一样。当我们生成固定长度的序列号时,可以使用zerofill。
如:卡号,默认使用空格填充,不方便显示出来。现在以0来填充,查看一下显示的内容
mysql> create table azerofill (fi int(3), fiz int(3) zerofill,fiuz int(4) unsigned zerofill);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into azerofill values(11,11,11);
Query OK, 1 row affected (0.00 sec)
mysql> select * from azerofill;
±-----±-----±-----+
| fi | fiz | fiuz |
±-----±-----±-----+
| 11 | 011 | 0011 |
±-----±-----±-----+
1 row in set (0.00 sec)
测试,插入超过显示范围的值。
mysql> insert into azerofill values(123456,123456,123456);
Query OK, 1 row affected (0.01 sec)
mysql> select * from azerofill;

发现位数不够用0补齐,超过设定值,正常显示。
浮点型数据类型
float数值类型用于表示单精度浮点数值,而double数值类型用于表示双精度浮点数值,float和double都是浮点型,而decimal是定点型;
MySQL浮点型和定点型可以用类型名称后加(M,D)来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度,如float(7,4)表示总长度是7位,小数点后面的长度是4,可显示为999.9999,MySQL保存值时进行四舍五入,如果插入999.00009,则结果为999.0001。
float:单精度浮点型,占字节数为4,用32位二进制描述,有符号是7个有效位,无符号是8个有效位
double:双精度浮点型,占字节数为8,用64位二进制描述,有符号是15个有效位,无符号是16个有效位
decimal:数字型,用128位二进制描述,不存在精度损失,常用于银行帐目计算。(28个有效位)
解释:单精度和双精度
精度是指计算机表达小数近似值的一种方式,单精度32位二进制,4个字节;双精度64位二进制,8个字节。
float数值类型
例如:float(3,1) :表示此字段有效位数为3位,小数点后面1位数字。
小数点后超过1位,mysql自动给四舍五入。
例如:
mysql> create database db1;
mysql> use db1;
mysql> create table kdata6(test float(3,1)) engine=innodb default charset=utf8;
mysql> insert into kdata6 values (123.455);
ERROR 1264 (22003): Out of range value for column ‘test’ at row 1
mysql> insert into kdata6 values (23.5);
Query OK, 1 row affected (0.00 sec)
mysql> insert into kdata6 values (3.455);
Query OK, 1 row affected (0.00 sec)
mysql> insert into kdata6 values (23.455);
Query OK, 1 row affected (0.00 sec)
mysql> select * from kdata6;

发现整数+小数一共只能有3位,整数2位,小数1位,小数点后超过1位自动四舍五入。
存储精确的小数: double和decimal数值类型
decimal、double要比float存储小数更精确。
mysql> create table ckdata4(tf float(5,2),td double(5,2),tdc decimal(5,2));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into ckdata4 values(56.346,56.346,56.346);
Query OK, 1 row affected, 1 warning (0.01 sec)
注意:数据也插入成功,但是有一个警告提示:
mysql> select * from ckdata4;

mysql> create table ckdata6(tf float(10,2),td double(10,2),tdc decimal(10,2));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into ckdata6 values(1234567.89,1234567.89,1234567.89);
Query OK, 1 row affected (0.00 sec)
mysql> select * from ckdata6;

这里丢失数据的原因是因为单精度类型float和双精度类型double在计算机中存储的时候,由于计算机只能存储二进制,所以浮点型数据在存储的时候,必须转化成二进制。我们知道对于float类型的数据,只分配了32位的存储空间,对于double类型值分配了64位,但是并不是所有的小数都能转成32位或者64位的二进制形式,如果超过了,就会出现截断,这就是误差的来源。
针对float情况,至少我们可以得出结论:

  1. 如果一个float型数据转成二进制后的第32位之后都是0,那么数据是准的
  2. 如果一个float型数据转成二进制后的第32位之后不全为0,则数据就会存在误差
    float和double类型的区别和误差来源。但是decimal类型是MySQL官方唯一指定能精确存储的类型,也是DBA强烈推荐和金钱相关的类型都要存储为decimal类型。
    选择float或者double或者decimal有时候也要看场景,比如我们可以用double存储一个小商铺的季度营业额(几千万),单独用double存储的时候没有问题,当多个季度,多个年份,算总营业额时,就可能出现问题,再也算不出一个准确的答案。所以,如果考虑情况没那么有把握的情况下,推荐使用decimal。
    字符串类型
    char 和 varchar
    char
    char :后面括号中必须有数值,来确认字符串的范围。大小范围 :0-255.
    char(10) ; 指定了一个长度为10的字符值。
    旧版本小于长度,空格自动补齐,大于长度 ,自动截短。
    新版本超过长度自动报错。
    mysql> create table kdata8 (aaa char(10));
    Query OK, 0 rows affected (0.01 sec)
    mysql> insert into kdata8 values (‘1234567890111’);
    ERROR 1406 (22001): Data too long for column ‘aaa’ at row 1
    mysql> insert into kdata8 values (‘abcdefghijklmn’);
    ERROR 1406 (22001): Data too long for column ‘aaa’ at row 1
    mysql> insert into kdata8 values (‘1234567890’);
    Query OK, 1 row affected (0.00 sec)
    mysql> insert into kdata8 values (‘abc’);
    Query OK, 1 row affected (0.01 sec)
    mysql> select * from kdata8;

binary 修饰符: 区分字符大小写
mysql> alter table kdata8 modify aaa char(10) binary;
Query OK, 4 rows affected (0.02 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> insert into kdata8 values (‘ABC’);
Query OK, 1 row affected (0.01 sec)
mysql> select * from kdata8 where aaa=‘abc’;

mysql> select * from kdata8 where aaa=‘ABC’;

varchar : 字符串可变长
在 MySQL5.0以上的版本中,varchar数据类型的长度支持到了65535,也就是说可以存放65532个字节的数据,起始位和结束位占去了3个字节。
mysql> create table kdata88 (aaa varchar(4));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into kdata88 values ("");
Query OK, 1 row affected (0.00 sec)
mysql> insert into kdata88 values (“ab”);
Query OK, 1 row affected (0.00 sec)
mysql> insert into kdata88 values (“abcd”);
Query OK, 1 row affected (0.01 sec)
mysql> insert into kdata88 values (“abcdefg”);
ERROR 1406 (22001): Data too long for column ‘aaa’ at row 1
超过长度自动报错,最大支持长度65535.
char和varchar区别
CHAR(M)定义的列的长度为固定的,M取值可以为0~255之间,当保存CHAR值时,在它们的右边填充空格以达到指定的长度。当检索到CHAR值时,尾部的空格被删除掉。
空格=1B

VARCHAR(M)定义的列的长度为可变长字符串,M取值可以为0~65535之间。
VARCHAR值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则使用两个字节)。VARCHAR值保存时不进行填充。
varchar存储变长数据,但存储效率没有CHAR高。如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么"+1"呢?这一个字节用于保存实际使用了多大的长度。
从空间上考虑,用varchar合适;从效率上考虑,用char合适。
字符串使用总结
1、VARCHAR型字段比CHAR型字段占用更少的内存和硬盘空间。当你的数据库很大时,这种内存和磁盘空间的节省会变得非常重要.
2、虽然VARCHAR使用起来较为灵活,但是从整个系统的性能角度来说,CHAR数据类型的处理速度更快,有时甚至可以超出VARCHAR处理速度的50%。
所以在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡。

日期和时间类型
date 日期
mysql> create table kdata10 (birthday date);
mysql> insert into kdata10 values (‘2018-01-23’) ,(20190304);
mysql> select * from kdata10;

time时间
mysql> create table kdata11(showtime time);
mysql> insert into kdata11 values (‘11:10:23’),(‘11:23’),(112456);
mysql> select * from kdata11;

Year
year : 00-69自动转为: 2000-2069 , 70-99自动转为1970-1999
mysql> create table kdata13 (test year);
mysql> insert into kdata13 values (2018),(04),(9),(69),(70);
mysql> select * from kdata13;

datatime 或 timestamp
datetime类型能保存的最大范围的值为1001年到9999年,精度为秒,它把日期和时间封装到格式为YYYY-MM-DD HH:MM:SS的整数中,与时区无关,使用8个字节的存储空间。
timestamp类型保存了从1970年1月1日(格林尼治时间)以来的秒数,它和linux的时间戳相同,只是用了4个字节的存储空间,因此它的范围比datetime的范围小了很多,只能表示从1970年到2038年,我们可以使用它提高空间利用率。
mysql> create table kdata14 ( f_datatime datetime,f_timestamp timestamp);
mysql> insert into kdata14 values (‘1999-11-12 23:23:45’,19991112232345);
mysql> select * from kdata14;

如果为空,直接报错:
mysql> insert into kdata14 values (now(),null);
不报错
复合类型
它们字段的值,必须从预先定义好的字符串集合中选取。
ENUM(枚举):只能取一个,用于互斥。男人,女人。
set : 能取多个。
枚举
mysql> create table kdata16(sex enum(‘M’,‘F’));
mysql> insert into kdata16 values ( ‘M’),(‘m’),(‘F’),(‘yy’),(‘null’);
ERROR 1265 (01000): Data truncated for column ‘sex’ at row 4
填写不是M,F的数据会报错
mysql> insert into kdata16 values ( ‘M’),(‘m’),(‘F’);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from kdata16;

Set
mysql> create table kdata17 ( type set(‘a’,‘b’,‘c’,‘d’,‘f’));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into kdata17 values (‘a’);
Query OK, 1 row affected (0.01 sec)
mysql> insert into kdata17 values (‘a,b’);
Query OK, 1 row affected (0.01 sec)
mysql> insert into kdata17 values (‘a,a,a,b’); #不能写重复选项,不然无效并且自动去重
Query OK, 1 row affected (0.00 sec)
mysql> select * from kdata17;

mysql> insert into kdata17 values (‘e’); #如果写不存在选项,直接报错
ERROR 1265 (01000): Data truncated for column ‘type’ at row 1
注意:set 类型: 最大包含64类项。在set中,相同的元素不能同时存在。
Msyql语句进阶
Mysql基础命令语句
修改数据表
添加字段:
alter table 表名 add 字段名 列类型
[not null|null][primary key][unique][auto_increment][default value]
alter table 表名 add 字段定义 after ar_id;
解释:
not null | null:非空约束(NOT NULL)可以通过 CREATE TABLE 或 ALTER TABLE 语句实现。在表中某个列的定义后加上关键字 NOT NULL 作为限定词,来约束该列的取值不能为空。对于使用了非空约束的字段,如果用户在添加数据时没有指定值,数据库系统就会报错。Null表示该列可以为空,用户在插入数据时如果没有指定值,该列用NULL填充。
mysql> create table db01.t1(id int auto_increment primary key,name varchar(30) not null,sex enum(“M”,“F”) default “M”,phone_call char(11) default “11111111111”,id_card char(18) unique);
查看表结构

向表中插入数据
mysql> insert into db01.t1(name,sex,phone_call,id_card) values(‘lisi’,‘M’,‘13523415687’,‘520321200310101352’);
Query OK, 1 row affected (0.01 sec)
查询数据

继续插入数据
mysql> insert into db01.t1(name,sex,phone_call,id_card) values(‘lisi’,‘F’,‘13523415487’,‘520321200310101342’);
Query OK, 1 row affected (0.01 sec)
查询数据

继续插入数据
mysql> insert into db01.t1(name,sex,phone_call,id_card) values(‘zhangsan’,‘F’,‘13623415487’,‘520321200310101342’);
ERROR 1062 (23000): Duplicate entry ‘520321200310101342’ for key ‘id_card’
继续插入数据
mysql> insert into db01.t1(name,sex,phone_call,id_card) values(‘zhangsan’,‘F’,‘13623415487’,‘52032120031010134x’);
Query OK, 1 row affected (0.00 sec)
查询数据

删除字段:
alter table 表名 drop 字段名
修改字段:
alter table 表名 modify 字段名 字段新类型
完整修改字段:
alter table 表名 change 旧字段名称 新字段定义
修改表名称
alter table 表名 rename 新名字
删除表
drop table [if (not) exists] 表名;

2021-01-16相关推荐

  1. 2021,至过去一年(2021.01.16 22:07:52)

    过去的一年,算是逆流而上的一年.经历了裁员离职,重新找工作的路. 总结一下在新的公司度过了一年 .总体来说对自身的发展路线确定下来.业务+技术的发展路线. 在项目中,主要在写后端,对接第三方系统,开发 ...

  2. 2021.07.16 总结

    2021.07.16 总结 ​ 今天状态不怎么好,几道那么容易的题就只有140分,毕竟也就打了前两道 T1 花生采摘 题目描述 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小路散步,突然 ...

  3. 2021.07.16【普及组】模拟赛C组

    2021.07.16[普及组]模拟赛C组 文章目录 2021.07.16[普及组]模拟赛C组 前言 花生采摘 题目 解析 代码 FBI树 题目 解析 代码 火星人 题目 解析 代码 麦森数 题目 解析 ...

  4. 2021.7.16模拟赛C组总结(转载XJY)

    2021.7.16模拟赛C组总结 这次比赛,题虽然不难,但丝毫不影响我打挂-唉- 0+100+50+0=150 题解 T1 题目描述: ​ 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小 ...

  5. 2013.01.16 Python的面向对象编程

    看起来貌似我的接收能力貌似很差劲,看了一个多星期才看到Python简明教程的第十三章(面向对象编程).回想一下前面看的内容,大部分都已经忘了,随便写几句代码还得回过头去翻教程,怎么办?是好还是坏?求指 ...

  6. 微软必应(Bing)打不开解决方案(2021.12.16)

    2021.12.19 0:10更新:现在Bing已修复,可直接通过https://cn.bing.com/访问~ 问题描述 2021.12.16开始必应就打不开了.. 解决方案 1. 打开主页 将原先 ...

  7. 《安富莱嵌入式周报》第248期:2022.01.10--2022.01.16

    往期周报汇总地址:链接 目录 本周发布了两期视频教程: 视频版 图文版 1.ARM第一款采用新安全分区架构的Morello评估板现已交付给研究人员 2.三星实现基于MRAM的内存计算设备 3.Qt6. ...

  8. PowerBI视觉对象共计271组,2021.01.20日更新

    PowerBI视觉对象共计271组,2021.01.20日更新 内容包含导入文件和图标.预览图.文件名一致,在预览图内找到合适的可以直接在视觉对象文件夹搜索 下载地址:点击下载 超便宜 或者复制链接打 ...

  9. Leetcode刷题 2021.01.22

    Leetcode刷题 2021.01.22 Leetcode1042 不邻接植花 Leetcode1010 总持续时间可被 60 整除的歌曲 Leetcode1091 二进制矩阵中的最短路径 Leet ...

  10. 嬴群的Python程序设计基础学期总结 2021.01.04

    Python程序设计基础学期总结 ## 时光像水中的倒影,一晃大一上学期就过去了.昨日那埋怨时间太慢的情愫似乎还游离在脑际,而今大一下学期生活正向我们走来,蓦然回首,感慨颇多.刚迈入大学的时候对一切似 ...

最新文章

  1. web编程速度大比拼(nodejs go python)(非专业对比)
  2. R语言普通最小二乘(OLS)回归说明、以及构建普通最小二乘(OLS)回归需要满足的四个假设(Normality(正态性)、Independence(独立性)、Linearity(线性度)、方差齐性)
  3. Activity缓存方法。
  4. docker 安装nginx_Docker18安装Nginx和Apache实验
  5. 自学大数据:用以生产环境的Hadoop版本比较
  6. LintCode: Hash Function
  7. getparameter方法中文显示问号解决方法_电脑显示器花屏怎么办 电脑显示器花屏解决方法【原因分析】...
  8. tomcat ---- web.xml
  9. SpringBoot 解决“不支持发行版本xx”的问题
  10. 力扣-414 第三大的数
  11. html元素拖动互换位置原理,HTML5 元素拖动 - 实现元素左右拖动, 或更改自身排序...
  12. 平稳时间序列的相关概念
  13. [iOS] 通知详解: iOS 10 UserNotifications -- 附加包Media Attachments
  14. 【有限元分析】有限元仿真分析与解析解的结果对比——以阶梯轴的静力分析为例
  15. 2017年2月22日-----------乱码新手自学.net 之Entity Framework 增删改
  16. 3DoF+ Video简介
  17. 从山景城看,Android看起来像什么? 关于Google I / O的见解
  18. 西雅图Oracle公寓租赁,在西雅图租房必须知道的那些事
  19. 2022年茶艺师(中级)考试题模拟考试题库及答案
  20. vue webapp之music(六)利用axios与后端接口代理请求歌单推荐数据

热门文章

  1. 2019年长安杯 第一届电子数据取证竞赛 wp
  2. 2020年中国互联网数据中心行业现状及发展趋势分析
  3. 保持hlist_node内存的紧凑性连续性以提高遍历性能
  4. OpenCV4学习笔记(59)——高动态范围(HDR)成像
  5. hiveserver2连接报错:“User: xxx is not allowed to impersonate yyy (state=08S01,code=0)”
  6. 武汉互联网公司和生活成本
  7. 拉格朗日/柯西中值定理与高考数学计算
  8. 最新发布!2021软科中国大学排名
  9. 如何快速切换各种pip源
  10. 2021总结:万千热爱,初心不负,三餐烟火暖,四季皆安然。