MySQL数据类型与操作
内容提要:
- 建表完整语法规范(create table 表格(字段名1 类型 (宽度) 约束条件)) 
- MySQL数据库数据类型(整型、浮点型、字符类型(char与varchar)、日期类型、枚举与集合) 
- 约束条件(primary key、unique key、not null、foreign key) 
一、创建表的完整语法
语法:
create table 表名(
字段名1 类型 (宽度) 约束条件,
字段名2 类型 (宽度) 约束条件,
字段名3 类型 (宽度) 约束条件);
特别注意:
- 在同一张表中,字段名不能相同
- 宽度和约束条件为可选项,但是字段名和类型必须有
- 最后一个字段添加完毕后后面不能加逗号!
补充:1、这里的宽度是对存储数据的一种限制,在不同MySQL版本里面可能会出现不同的结果,这里只是不同版本的默认约束条件不一样导致,在最新版本5,7中如果输入数据
宽度超出限制,则会报错。
2、类型与约束条件的区别:类型是限制字段必须以什么样的数据类型存储,二约束条件是在这一类型之上添加一种额外的限制。
二、MySQL基本数据类型
- 整型(int)- 分类:tinyint smallint mediumint int bigint
- 作用:储存年龄、等级、id、各种号码等
- 类型存储范围:
 
- 验证整型字段有无符号及范围 
 int类型默认是有符号的,也就是说默认支持输入负数到正数
 mysql> reate table t1(id tinyint);
 mysql> insert into t1 values(128),(-129);
 #结果:ERROR 1264 (22003): Out of range value for column 'id' at row 1
 # 因为tinyint类型最大正整数限制为127,输入128超出范围。报错 create table t2(id tinyint unsigned); # unsigned表示这里类型设置为无符号(无正负号)
 mysql> insert into t2 values (0),(255);
 #这里类型约束为无符号,所以输入负数就会报错,输入超过255的数也会报错。tinyint无符号范围是0-255。 以下同理:
 create table t3(id int unsigned);
 mysql> insert into t3 values (4294967296);
 ERROR 1264 (22003): Out of range value for column 'id' at row 1
 mysql> insert into t3 values (4294967295);
 Query OK, 1 row affected (0.01 sec) 强调:对于整型来说,数据类型之后的宽度并不是存储限制,而是现实宽度限制,所以在创建表的时候,
 如果字段采用的是整型类型,完全无需指定显示宽度,因为默认的显示宽度(11),一般情况下,就足够显示完整的数据。
 
- 浮点型(分为float、double、decimal)- 应用场景:身高、体重、薪资
- 字符限制特点(5,3),前一位表示所有的位数,后一位表示小数个数
- 区别对比:
# 存储限制 
 float(255,30)
 double(255,30)
 decimal(65,30) # 精确度验证
 mysql> create table t9(x float(255,30));
 mysql> create table t10(x double(255,30));
 mysql> create table t11(x decimal(65,30)); mysql> insert into t9 values(1.111111111111111111111111111111);
 mysql> insert into t10 values(1.111111111111111111111111111111);
 mysql> insert into t11 values(1.111111111111111111111111111111);
 mysql> select * from t9;
 +----------------------------------+
 | x |
 +----------------------------------+
 | 1.111111164093017600000000000000 |
 +----------------------------------+
 1 row in set (0.00 sec) mysql> select * from t10;
 +----------------------------------+
 | x |
 +----------------------------------+
 | 1.111111111111111200000000000000 |
 +----------------------------------+
 1 row in set (0.00 sec) mysql> select * from t11;
 +----------------------------------+
 | x |
 +----------------------------------+
 | 1.111111111111111111111111111111 |
 +----------------------------------+
 1 row in set (0.00 sec) 从上面的查询创建的表中数据可以看出:
 精度对比:decimal的精度最高,其次是double,最后是float,
 但是就算是精度最低的float它的精度也有16位,所以一般使用完全能够应付99%的数据场景。
 
- 字符类型(char定长与varchar变长)- 作用:姓名、地址、描述类信息
- 理解通过实际使用来描述:
char: 
 mysql> create table t12(name char(4));
 mysql> insert into t12 values ('hello');
 ERROR 1406 (22001): Data too long for column 'name' at row 1 # 超出限制范围会报错。
 mysql> insert into t12 values ('hell');
 Query OK, 1 row affected (0.01 sec)
 mysql> insert into t12 values ('he');
 Query OK, 1 row affected (0.00 sec)
 mysql> select * from t12;
 +------+
 | name |
 +------+
 | hell | # 4个字符正好填满
 | he | #不够4个字符空格补全
 +------+
 --------------------------------------------------------------
 varchar:
 mysql> create table t13(name varchar(4));
 mysql> insert into t13 values ('hello');
 ERROR 1406 (22001): Data too long for column 'name' at row 1 # 超出范围,报错
 mysql> insert into t13 values ('hell');
 Query OK, 1 row affected (0.00 sec)
 mysql> insert into t13 values ('he');
 Query OK, 1 row affected (0.01 sec)
 mysql> select * from t13;
 +------+
 | name |
 +------+
 | hell | # 正好4个,填满
 | he | # 不够4个,按实际宽度占位。(这里看不出来,但是一定要记住,varchar是变长,所以不够4个肯定按实际宽度存储) +------+
 #####
 TIP:
 select char_length(name) from t12
 select char_length(name) from t13 # 仍然无法查看到真正的结果 """首先应该肯定的是在硬盘上存的绝对是真正的数据,但显示的时候mysql会自动将末尾的空格取掉"""
 # 如果不想让mysql帮你做自动去除末尾空格的操作,需要再添加一个模式
 set global sql_mode="strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH";
 # 退出客户端重新登陆
 select char_length(x) from t12; #
 select char_length(y) from t13; # # 针对char类型,mysql在存储时会将数据用空格补全存放到硬盘中。但是会在读出结果的时候自动取掉末尾的空格
 ####
- char 与 varchar 的使用区别
- name char(5)
- 优点:浪费空间,每个name信息都是按照5个字符存,这样如果不够5个的也会用空格补全,造成存储空间浪费
- 缺点:存取速度很快,因为存储数据的结构固定,所以存取速度快。
- egon alex lxx jxx txx 存用5个字符5个字符存,取的话也是5个字符为一部分取,准确快捷
 
- name varchar(5)
- 缺点:存取速度慢,每个name信息按照可变长的形式去存,同时存的时候要在前面加入该字符长度的报头,一并存入,取的时候按照报头里的长度数据去取数据,比char多了好几步,所以存取数据相比较char会慢些。
- 优点:节省空间,通过可变长来存入,加上报头数据也不会造成空间的太多浪费
- 1bytes+egon 1bytes+alex 1bytes+lxx 1bytes+jxx 1bytes+txx
 
 
- name char(5)
 
- 时间类型- 分类:
- date:2019-05-13
- time:11:11:11
- datetime:2019-05-13 11:11:11
- year:2019
 
- 测试:
mysql> create table stu(id int,name char(16),birth_d date,study_time time,reg_time datetime); # 创建表 
 mysql> insert into stu values(1,'jason','2019-05-09','11:11:11','2019-11-11 11:11"11'); #插入表数据
 Query OK, 1 row affected (0.00 sec) mysql> select * from stu; # 显示表内容
 +------+-------+------------+------------+---------------------+
 | id | name | birth_d | study_time | reg_time |
 +------+-------+------------+------------+---------------------+
 | 1 | jason | 2019-05-09 | 11:11:11 | 2019-11-11 11:11:11 |
 +------+-------+------------+------------+---------------------+
 1 row in set (0.00 sec)
 
- 分类:
- 枚举与集合类型:- 分类
- 枚举enum 多选一
- 集合set 多选 一或多
 
- 示例:
enum枚举: 
 mysql> create table usr(id int,name char(16),gender enum('male','female','others'));
 Query OK, 0 rows affected (0.05 sec)
 mysql> insert into usr values(1001,'jsson','xxx');
 ERROR 1265 (01000): Data truncated for column 'gender' at row 1
 mysql> insert into usr values(1001,'jsson','male');
 Query OK, 1 row affected (0.01 sec)
 mysql> insert into usr values(1002,'egon','female');
 Query OK, 1 row affected (0.01 sec)
 mysql> select * from usr;
 +------+-------+--------+
 | id | name | gender |
 +------+-------+--------+
 | 1001 | jsson | male |
 | 1002 | egon | female |
 +------+-------+--------+
 2 rows in set (0.00 sec)
 -----------------------------------------------------------------
 set集合:
 mysql> create table tea(id int,name char(16),gender enum('male','female','other'),hobby set('read','sleep','dbj'));
 Query OK, 0 rows affected (0.04 sec)
 mysql> insert into tea values(10011,'egon','female','read,dbj');
 Query OK, 1 row affected (0.01 sec)
 mysql> insert into tea values(10012,'alex','male','dbj');
 Query OK, 1 row affected (0.05 sec)
 mysql> select * from tea;
 +-------+------+--------+----------+
 | id | name | gender | hobby |
 +-------+------+--------+----------+
 | 10011 | egon | female | read,dbj |
 | 10012 | alex | male | dbj |
 +-------+------+--------+----------+
 2 rows in set (0.00 sec)
 
- 分类
- 约束条件- 类型
PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录 
 FOREIGN KEY (FK) 标识该字段为该表的外键
 NOT NULL 标识该字段不能为空
 UNIQUE KEY (UK) 标识该字段的值是唯一的
 AUTO_INCREMENT 标识该字段的值自动增长(整数类型,而且为主键)
 DEFAULT 为该字段设置默认值
 UNSIGNED 无符号
 ZEROFILL 使用0填充not null + defaultnot null:不为空- not null + default
- mysql> create table us(id int,name char(16)); 
 Query OK, 0 rows affected (0.05 sec) mysql> insert into us values (1,null);
 Query OK, 1 row affected (0.01 sec) mysql> desc us;
 +-------+----------+------+-----+---------+-------+
 | Field | Type | Null | Key | Default | Extra |
 +-------+----------+------+-----+---------+-------+
 | id | int(11) | YES | | NULL | |
 | name | char(16) | YES | | NULL | |
 +-------+----------+------+-----+---------+-------+ mysql> delete from us where id=1; # 先清空存入的null数据
 Query OK, 1 row affected (0.01 sec) mysql> alter table us modify name char(16) not null; # 将name输入的数据限制为非空
 Query OK, 0 rows affected (0.05 sec)
 Records: 0 Duplicates: 0 Warnings: 0 mysql> desc us; # 查看表格式:
 +-------+----------+------+-----+---------+-------+
 | Field | Type | Null | Key | Default | Extra |
 +-------+----------+------+-----+---------+-------+
 | id | int(11) | YES | | NULL | |
 | name | char(16) | NO | | NULL | |
 +-------+----------+------+-----+---------+-------+ mysql> insert into us values(002,null); # 此时再输入null就会报错了,因为我们限制了name必须输入未非空的字符。
 ERROR 1048 (23000): Column 'name' cannot be null
 default 默认值
 mysql> create table st(id int,name char(16) not null,gender enum('male','female') default 'male'); # 为gender字段设置默认值‘male,前面指定输入字段不包含gender时候,这时候的默认字段名就会生效。
 Query OK, 0 rows affected (0.03 sec) mysql> insert into st(id,name) values (1001,'lxx');
 Query OK, 1 row affected (0.01 sec) mysql> select * from st;
 +------+------+--------+
 | id | name | gender |
 +------+------+--------+
 | 1001 | lxx | male |
 +------+------+--------+
 1 row in set (0.00 sec)
- unique 某个字段对应的值在当前表中是唯一的,不能重复- ###单列唯一: 
 mysql> create table user1(id int unique,name char(16));
 Query OK, 0 rows affected (0.04 sec) mysql> insert into user1 values (1,'js'),(1,'eg'); #报错
 ERROR 1062 (23000): Duplicate entry '' for key 'id'
 mysql> insert into user1 values (1,'js'),(2,'eg'); #不报错
 Query OK, 2 rows affected (0.00 sec)
 Records: 2 Duplicates: 0 Warnings: 0 ###联合唯一:多个字段如果同时有相同的输入时,会报错
 mysql> create table server(id int,ip char(16),port int,unique(ip,port));
 Query OK, 0 rows affected (0.04 sec) mysql> desc server;
 +-------+----------+------+-----+---------+-------+
 | Field | Type | Null | Key | Default | Extra |
 +-------+----------+------+-----+---------+-------+
 | id | int(11) | YES | | NULL | |
 | ip | char(16) | YES | MUL | NULL | |
 | port | int(11) | YES | | NULL | |
 +-------+----------+------+-----+---------+-------+
 3 rows in set (0.00 sec) mysql> insert into server values (1,'127.0.0.1',8080);
 Query OK, 1 row affected (0.01 sec) mysql> insert into server values (2,'127.0.0.1',8080); #ip和port都相同,报错
 ERROR 1062 (23000): Duplicate entry '127.0.0.1-8080' for key 'ip' mysql> insert into server values (2,'127.0.0.2',8080); # 仅仅是port相同不会报错
 Query OK, 1 row affected (0.00 sec) mysql> insert into server values (3,'127.0.0.1',8081); #仅仅是ip相同也不会报错
 Query OK, 1 row affected (0.00 sec) mysql> select * from server; 查看结果:
 +------+-----------+------+
 | id | ip | port |
 +------+-----------+------+
 | 1 | 127.0.0.1 | 8080 |
 | 2 | 127.0.0.2 | 8080 |
 | 3 | 127.0.0.1 | 8081 |
 +------+-----------+------+
 3 rows in set (0.00 sec)
- primary key+auto_increment(mysql数据类型及约束条件的重点内容,必须要掌握)- # 单从约束角度来说 primary key 等价于not null + unique 
 mysql> create table tt1(id int primary key); # 设置id主键唯一
 Query OK, 0 rows affected (0.04 sec) mysql> desc tt1;
 +-------+---------+------+-----+---------+-------+
 | Field | Type | Null | Key | Default | Extra |
 +-------+---------+------+-----+---------+-------+
 | id | int(11) | NO | PRI | NULL | |
 +-------+---------+------+-----+---------+-------+
 1 row in set (0.00 sec) mysql> insert into tt1 values (1),(1); # 主键不唯一,报错
 ERROR 1062 (23000): Duplicate entry '' for key 'PRIMARY'
 mysql> insert into tt1 values (1),(2); #唯一,不报错
 Query OK, 2 rows affected (0.00 sec)
 Records: 2 Duplicates: 0 Warnings: 0
 ------------------------------------------------------------------ 重点内容: 
 一、一张表中必须有且只有一个主键,如果你没有设置主键,那么会从上到下搜索直到遇到一个非null且unique的字段自动将其设为主键。
 mysql> create table ts1(id int,name char(16),age int not null unique,addr char(16) not null unique)engine=innodb;
 Query OK, 0 rows affected (0.04 sec) mysql> desc ts1;
 +-------+----------+------+-----+---------+-------+
 | Field | Type | Null | Key | Default | Extra |
 +-------+----------+------+-----+---------+-------+
 | id | int(11) | YES | | NULL | |
 | name | char(16) | YES | | NULL | |
 | age | int(11) | NO | PRI | NULL | |
 | addr | char(16) | NO | UNI | NULL | |
 +-------+----------+------+-----+---------+-------+
 ------------------------------------------------------------------
 二、如果表里面没有指定的任何可以设置的主键字段,那么innodb存储引擎会采用自己的默认的一个隐藏的字段作为主键,隐藏意味着你在查询的时候无法根据主键字段加速查询了
 ------------------------------------------------------------------
 三、一张表中通常都应该有一个id字段,并且通常将id字段设为主键
 ------------------------------------------------------------------
 额外知识点:
 #联合主键:与联合唯一字段一个道理,即多个字段联合起来作为表的主键,本质上将多个字段总体看为一个主键
 mysql> create table ts2(ip char(16),port int,primary key(ip,port));
 Query OK, 0 rows affected (0.04 sec) mysql> desc ts2; # 2个字段合为一个主键。
 +-------+----------+------+-----+---------+-------+
 | Field | Type | Null | Key | Default | Extra |
 +-------+----------+------+-----+---------+-------+
 | ip | char(16) | NO | PRI | NULL | |
 | port | int(11) | NO | PRI | NULL | |
 +-------+----------+------+-----+---------+-------+- auto_increment 自增约束 
 mysql> create table ts3(id int primary key auto_increment,name char(16));
 Query OK, 0 rows affected (0.05 sec) mysql> insert into ts3(name) values ('jason'),('alex'),('lxx'); #只输入name字段信息
 Query OK, 3 rows affected (0.01 sec)
 Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from ts3; # 查看自增结果
 +----+-------+
 | id | name |
 +----+-------+
 | 1 | jason |
 | 2 | alex |
 | 3 | lxx |
 +----+-------+
 ------------------------------------------------------------------
 补充:
 接着上面的例子,如果我将其中一个字段比如lxx,删除后再添加字段,会出现:
 mysql> delete from ts3 where id=3;
 Query OK, 1 row affected (0.01 sec) mysql> insert into ts3(name) values ('xxxx');
 Query OK, 1 row affected (0.01 sec) mysql> select * from ts3;
 +----+-------+
 | id | name |
 +----+-------+
 | 1 | jason |
 | 2 | alex |
 | 4 | xxxx | # 此时序号居然还是接着自增。
 +----+-------+
 3 rows in set (0.00 sec) tip:如果要清楚继续自增,从头开始的话,就必须清空表,才行。
 mysql> truncate ts3; # 将整张表重置,id重新从0开始记录。
 Query OK, 0 rows affected (0.03 sec) mysql> insert into ts3(name) values ('eeeee');
 Query OK, 1 row affected (0.01 sec) mysql> select * from ts3;
 +----+-------+
 | id | name |
 +----+-------+
 | 1 | eeeee |
 +----+-------+
 
 
- 类型
-------------------------------------------------------------------------------------------------------------------------------------------
- 严格模式补充
我们刚刚在上面设置了char,tinyint,存储数据时超过它们的最大存储长度,发现数据也能正常存储进去,只是mysql帮我们自动截取了最大长度。但在实际情况下,我们应该尽量减少数据库的操作,缓解数据库的压力,让它仅仅只管理数据即可,这样的情况下就需要设置安全模式
show variables like "%mode%"; # 查看数据库配置中变量名包含mode的配置参数
# 修改安全模式
set session # 只在当前操作界面有效
set global # 全局有效 set global sql_mode ='STRICT_TRANS_TABLES'
# 修改完之后退出当前客户端重新登陆即可
MySQL数据类型与操作的更多相关文章
- MySQL数据类型操作(char与varchar)
		目录 一:MySQL数据类型之整型 1.整型 2.验证不同类型的int是否会空出一个存储正负号 3.增加约束条件 去除正负号(unsigned) 二:浮点型 1.浮点型 2.验证浮点型精确度 三:字符 ... 
- MySQL数据类型——数值类型
		1.1.1 整型 整型 占用字节 范围 范围 tinyint 1 -27~27-1 -128~127 smallint 2 -215~215-1 -32768~32767 mediumint 3 -2 ... 
- mysql之常用操作
		1. 数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数 ... 
- Java数据类型和MySql数据类型对应一览
		类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述 VARCHAR L+N VARCHAR java.lang.String 12 CHAR N ... 
- java mysql 数据类型对照
		java mysql 数据类型对照 类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述 VARCHAR L+N VARCHAR java.lang. ... 
- MySQL之表操作
		1 创建表 2 查看表结构 3 数据类型 4 表完整性约束 5 修改表 6 复制表 7 删除表 一创建表 语法: create table 表名( 字段名1 类型[(宽度) 约束条件], 字段名2 ... 
- 谈谈如何选择合适的MySQL数据类型
		MySQL数据类型选择 一 .选择原则 更小的通常更好:一般情况下选择可以正确存储数据的最小数据类型.越小的数据类型通常更快,占用磁盘,内存和CPU缓存更小. 简单就好:简单的数据类型的操作通常需要更 ... 
- MySQL数据类型2
		一.MySQL的数据类型 主要包括以下五大类: 整数类型:BIT.BOOL.TINY INT.SMALL INT.MEDIUM INT. INT. BIG INT 浮点数类型:FLOAT.DOUBLE ... 
- Database学习 - mysql 数据库 表操作
		mysql 数据库 表操作 创建数据表 基本语法格式: 创建数据表: create table 表名( 字段名 datatype 约束, 字段名 datatype 约束, ...... ) 修改表名 ... 
随机推荐
- Luogu P1613跑路【倍增】By cellur925
			题目传送门 开始的思路:直接跑一遍最短路,得到最短路的那个值.然后把那个值进行一下二进制拆分,看能拆几次.(可能是受到了刚做过的题影响) ;i>=;i--) { <<i)>qw ... 
- Oracle 查询约束信息
			select * from user_constraints where table_name=''; select * from user_cons_columns; 
- background-size属性
			background-size:属性有 auto:length :百分比 length 如:10px 20px 固定的 或者是写成一个 ,10px 另外一个就默认为 auto; 写成百分比的形式 是 ... 
- Qt容器类之二:迭代器
			一.介绍 遍历一个容器可以使用迭代器(iterators)来完成,迭代器提供了一个统一的方法来访问容器中的项目.Qt的容器类提供了两种类型的迭代器:Java风格迭代器和STL风格迭代器.如果只是想按顺 ... 
- 【loj10061】最短母串
			#10061. 「一本通 2.4 练习 4」最短母串 内存限制:512 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 1bentong 提交 提交 ... 
- 记录两个python itchat的用法博客网址
			http://www.tuicool.com/articles/VJZRRfn https://itchat.readthedocs.io/zh/latest/ 
- Jquery 中使用String.Format
			第一种方法: String.format = function() { if (arguments.length == 0) return null; var str = arguments[0]; ... 
- 获取第三方软件的包名、入口Activity的类名
			要启动指定的第三方软件,需要知道第三方软件的包名.类名. 获取第三方软件包名.类名的两种方法: 1.使用aapt aapt是sdk自带一个工具,在 Sdk\builds-tools 目录下 .如果没有 ... 
- 一份最贴近真实面试的Java基础面试题
			这是一份Java基础知识的面试题.在网上的关于Java的面试题数不胜数,但认真看过感觉大多数都没有实用性,有很多是面试官根本就不会问到的,那些已经脱离了实际开发的技术问题.而这份资料来源自一份个人觉得 ... 
- 一个Java编写的小玩意儿---多人在线聊天工具
			这个在线聊天工具小项目使用JAVA编写,用JAVA来做图形界面本来就是出了名的低效和丑陋.不过这不是重点.写这个小项目的目的在于串一串J2SE的知识,把当时写这个项目的时候的思路梳理一下.时间有点久了 ... 
