03 数据增删改
MySQL中的标识符命名规则
- 数据库名,表明不得超过30个字符,变量名限制为29个
- 必须只能包含A-Z,a-z,0-9,_ 共63个字符
- 数据库名,表名,字段名等对象名中间不要包含空格
- 同一个MySQL软件中,数据库不能同名,表明不能重复,同一个表中列名不能重复
- 必须保证字段名不和保留关键字冲突
- 保持字段名和类型的一致性
MySQL中的数据类型
类型 | 类型举例 |
---|---|
整数类型 | INT、TINYINT、SMALLINT、MEDIUMINT、BIGINT |
浮点累心 | FLOAT, DOUBLE |
定点数类型 | DECLMAL |
位类型 | BIT |
日期时间类型 | YEAR, TIME, DATE, DATETIME, TIMESTAMP |
文本字符串类型 | CHAR, VARCHAR, TINYEXT, TEXT, MEDIUMTEXT, LONGTEXT |
枚举类型 | ENUM |
集合类型 | SET |
二进制字符串类型 | BINARY, VARBINARY, TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB |
JSON类型 | JSON对象,JSON数组 |
空间数据类型 | 单值:GEOMETRY, POINT, LINESTRING, POLYGON 集合:MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION |
常用类型介绍
数据类型 | 描述 |
---|---|
INT | 从-2^31到2^31-1的整数数据。存储大小为4个字节 |
CHAR(size) | 定长字符数据。若未指定,默认为1个字符,最大长度255 |
VARCHAR(size) | 可变长字符数据,根据字符串实际长度保存,必须指定长度 |
FLOAT(M,D) | 单精度,占用4个字节,m=整数位+小数位,d=小数位。d<=m<=255,0<=d<=30,默认m+d<=6 |
DOUBLE(M,D) | 双精度,占用8个字节,D<=M<=255,0<=D<=30,默认M+D<=15 |
DECLMAL(M,D) | 高精度小数,占用M+2个字节,D<=M<=65,0<=D<=30,最大取值范围与DOUBLE相同。 |
DATE | 日期型数据,格式’YYYY-MM-DD |
BLOB | 二进制形式的长文本数据,最大可达4G |
TEXT | 长文本数据,最大可达4G |
数据类型属性
关键字 | 含义 |
---|---|
NULL | 数据列可包含null值 |
NOT NULL | 数据列不允许包含null值 |
DEFFAULT | 默认值 |
PRIMARY KEY | 主键 |
AUTO_INCREMENT | 自动递增,适用于整数类型 |
UNSIGNED | 无符号 |
CHARACTER SET name | 指定一个字符集 |
数据库操作
创建数据库
新创建一个 mysqltest2
数据库,使用 IF NOT EXISTS
如果数据库不存在就创建,如果存在则不会创建
1 | CREATE DATABASE IF NOT EXISTS mysqltest2; |
查询已有数据库
1 | SHOW DATABASES; |
查询当前正在使用的数据库
1 | SELECT DATABASE(); |
查询指定库下面所有的表
1 | SHOW TABLES FROM atguigudb; |
查看数据库的创建信息
1 | SHOW CREATE DATABASE mysqltest1; |
修改数据库的字符集
1 | ALTER DATABASE mysqltest1 CHARACTER SET utf8; |
删除指定数据库
1 | DROP DATABASE IF EXISTS mysqltest2; |
创建表的两种方式
方式一
1 | CREATE TABLE IF NOT EXISTS myemp1( |
方式二,基于已有表
基于现有表创建新的表,查询出来的结果会保存到新表中
1 | CREATE TABLE IF NOT EXISTS myemp2 |
查看表结构
1 | DESC myemp2 |
查看建表语句
1 | SHOW CREATE TABLE myemp2; |
练习一:复制 employees 表的结构和数据
1 | CREATE TABLE IF NOT EXISTS myemp3 |
练习二:只复制 employees 表的结构
1 | CREATE TABLE IF NOT EXISTS myemp4 |
修改表
追加一个列
语法:ALTER TABLE 表名 ADD 列名 数据类型;
1 | ALTER TABLE myemp1 ADD salary DOUBLE(10,2); |
修改一个列
可以修改列的数据类型,长度,默认值和位置
语法:ALTER TABLE 表名 MODIFY 列名 数据类型 DEFAULT 默认值;
1 | ALTER TABLE myemp1 MODIFY last_name VARCHAR(25) DEFAULT '张三'; |
重命名一个列
语法:ALTER TABLE 表名 CHANGE 旧列名 新列名 数据类型;
1 | ALTER TABLE myemp1 CHANGE `name` user_name VARCHAR(30); |
删除一个列
语法:ALTER TABLE 表名 DROP 列名;
1 | ALTER TABLE myemp1 DROP salary; |
重命名表
语法:RENAME TABLE 旧表名 TO 新表名;
1 | RENAME TABLE myemp1 TO newmyemp1; |
删除表
语法:DROP TABLE IF EXISTS 表名;
1 | DROP TABLE IF EXISTS myemp2; |
清空表
保留表中字段,只清空数据
语法:TRUNCATE TABLE 表名;
1 | TRUNCATE TABLE myemp3; |
TRUNCATE 和 DELETE对比
- DELETE 可以回滚数据,但是 TRUNCATE 不能回滚
- TRUNCATE 效率高,DELETE 效率低
DDL 和 DML 的说明
- DDL的操作一旦执行,就不可回滚。指令 SET autocommit = FALSE 对 DDL 操作失效,因为在执行完 DDL 操作之后,一定会执行一次 COMMIT。二次 COMMIT 操作不收 SET autocommit = FALSE 影响
- DML的操作默认情况,一旦执行,也不可以回滚,但是如果在执行DML操作之前,执行了 SET autocommit = FALSE,则执行的DML操作就可以实现回滚
- 数据的回滚只能回滚到最近一次commit 时的结果
演示,执行 DELETE FROM
后并对数据进行回滚
1 | -- 1.执行前先执行一次commit |
执行 TRUNCATE
清空表
1 | -- 1.执行前先执行一次commit |
MySQL8.0 DDL的原子化
如果一个删除语句执行失败,则会回滚数据
示例
1 | CREATE TABLE bool1 ( |
上面的代码依次执行后 book1 表不会被删除。
添加数据
首先新建表
1 | USE atguigudb; |
单行逐条插入
默认插入的顺序要和建表时的字段顺序一致
1 | INSERT INTO emp01 |
指明字段顺序
在表名后面指明要插入的字段顺序,在添加数据时也要和指明的顺序一致
1 | INSERT INTO emp01(id,hire_date,last_name,salary) |
批量插入数据
1 | INSERT INTO emp01(id,hire_date,last_name,salary) |
将查询结果插入到表中
我们也可以将一个查询语句查询出来的结果全部插入到表中,但是查询的字段显示要和插入表的顺序一致。
1 | INSERT INTO emp01 ( id, hire_date, last_name, salary ) |
更新数据
修改 id 等于 1 的员工工资为6000
1 | UPDATE emp01 SET salary=6000 WHERE id = 1; |
批量修改,名字中包含a的人员工资提升百分之20
1 | UPDATE emp01 SET salary = salary * 1.2 WHERE last_name LIKE '%a%'; |
删除数据
删除 id 等于 2 的数据
1 | DELETE FROM emp01 WHERE id = 2; |
批量删除数据
1 | DELETE FROM emp01 WHERE id < 100; |
删除操作如果没有加 WHERE 条件限制则会删除表中的全部内容
MySQL8 新特性:计算列
当某一列的数据是依赖于其他列数据计算而得时,我们可以吧这个列设置为计算列。在添加数据时不需要设置计算列的值,计算列会自动计算并赋值
创建表, c 是计算列
1 | CREATE TABLE testsql( |
添加数据
1 | INSERT INTO testsql(a,b) VALUES(10,20); |
修改数据
1 | UPDATE testsql SET a = 120 WHERE a = '10' |
上面两个操作,c 列数据都会自动发生改变。
数据增删改练习
1 | -- 练习一: |
数据类型
整数类型
UNSIGNED 无符号限制
创建表时如果添加了这个属性,则表示这个字段不能出现符号。例如当一个字段是 int 类型时,并且声明了 UNSIGNED 属性,则这个字段必须存储一个大于等于0的整数
1 | CREATE TABLE test1( |
ZEROFILL
这个属性只有指明了字段长度然后再添加这个属性才有意义。例如设置 int(5) ,当添加的整数不足5位时,会在前面用 0 补齐五位
1 | CREATE TABLE test1( |
浮点类型
FLOAT
FLOAT 表示单精度浮点数
1 | CREATE TABLE test2( |
DOUBLE
DOUBLE 表示双精度浮点数
1 | CREATE TABLE test3( |
当设置小数点位数后,如果小数点的个数超过设定的数量,则小数点自动四舍五入
问题1:FLOAT 和 DOUBLE 这两种数据类型的区别是啥呢?
- FLOAT 占用字节数少,取值范围小;DOUBLE 占用字节数多,取值范围也大。
问题2:为什么浮点数类型的无符号数取值范围,只相当于有符号数取值范围的一半,也就是只相当于有符号数取值范围大于等于零的部分呢?
- MySQL 存储浮点数的格式为: 符号(S) 、 尾数(M) 和 阶码(E) 。因此,无论有没有符号,MySQL 的浮点数都会存储表示符号的部分。因此, 所谓的无符号数取值范围,其实就是有符号数取值范围大于等于零的部分。
定点数类型
上面的两个浮点类型都会有精度丢失问题,例如如下:
1 | CREATE TABLE test4( |
我们往两个浮点类型的列中分别插入了 1.3 和 1.6,然后计算两个列的和,我们希望得到的是2.9,但是结果返回是无限接近2.9的一个数,这种我们称之为精度丢失问题。面对这种情况我们如何解决呢?那么就是采用定点数类型:DECIMAL
DECIMAL
数据类型 | 默认值 | 字节数 | 含义 |
---|---|---|---|
DECIMAL(M,D) | DECIMAL(10,0) | M + 2 | 有效范围由M和D决定 |
DECIMAL(M,D) 表示高精度小数。其中,M被称为精度,D被称为标度。0<=M<=65, 0<=D<=30,D<M。例如,定义DECIMAL(5,2)的类型,表示该列取值范围是-999.99~999.99。
现在我们使用 DECIMAL 类型来解决上面的问题
1 | CREATE TABLE test5( |
由于默认 DECIMAL(10,0) 表示0位小数点,所以动态设置2位小数点,现在查看效果
可见精度没有丢失。因为 DECIMAL 底层采用的是字符串存储的,不会有精度丢失问题
日期和时间类型
DATE
存储年月日
TIME
存储时分秒
DATETIME
存储年月日时分秒
1 | CREATE TABLE test6( |
分别设置列的类型为 DATE, TIME, DATETIME,然后插入当前时分秒,查询插入结果:
字符串格式类型
CHAR 和 VARCHAR
VARCHAR 必须指定长度,指定的是字符长度,表示字符串的长度不能超过几个
1 | CREATE TABLE test7( |
ENUM 枚举类型
设置一个字段为枚举类型后只能插入枚举的值,同时一次只能插入一个数据
1 | CREATE TABLE test8( |
SET 类型
设置 SET 类型后可以同时插入多条数据,如果有重复的数据会自动去重
1 | CREATE TABLE test9( |
JSON
1 | CREATE TABLE test10( |