十二、表的创建、数据的插入删除
12.1 建表的语法格式:
回顾一下,建表属于DDL语句,DDL包括:create drop alter
create table 表名 (
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型,
);
注意:
- 表名:建议以
t_
或者tbl_
开始,可读性会更强 - 字段名:见明知意
- 表名和字段名都属于标识符。
12.2 关于MySQL中的数据类型
有很多数据类型,我们只需要掌握一些常见的数据类型即可。
- varchar(最长255)
- 可变长度的字符串
- 比较智能,节省空间
- 会根据实际的数据长度动态分配空间
- 优点:节省空间
- 缺点:需要动态分配空间,速度慢
- char(最长255)
- 定长字符串
- 不管实际的数据长度是多少
- 分配固定长度的空间去存储数据
- 使用不恰当的时候,可能会导致空间的浪费
- 优点:不需要动态分配空间,速度更快
- 缺点:使用不当时会导致空间的浪费
varchar 和 char 怎么选择?
如性别字段,因为性别是固定长度的字符串,所以选择char
如姓名字段,每个人的名字长度不同,所以选择varchar
- int(最长11)
- 数字中的整数型。等同于java中的int
- bigint
- 数字中的长整型。等同于java中的long
- float
- 单精度浮点型数据
- double
- 双精度浮点型数据
- date
- 短日期类型
- datatime
- 长日期类型
- clob
- 字符大对象
- 最多可以存储4G的字符串
- 如:存储一篇文章,存储一个说明
- 超过255个字符的都要采用CLOB字符大对象来进行存储
- Character Large OBject ~ CLOB
- blob
- 二进制大对象
- Binary Large OBject
- 专门用来存储图片、声音、视频等流媒体数据
- 往BLOB类型的字段上插入数据的时候,如插入一张图片、视频等时,你需要使用IO流才行
示例,一个名为 t_movie 的电影表(专门用来存储电影信息)
编号 名字 故事情节 上映日期 时长 海报 类型
no(bigint) name(varchar) history(clob) playtime(date) time(double) image(blob) type(char)
------------------------------------------------------------------------------------------------------------------
10000 哪吒 ........... 2020-11-11 2.5 .... '1'
10001 林正英之娘娘 ........... 2021-11-11 1.5 .... '2'
....
12.3 案例–创建 / 删除表
创建一个学生表,需要有学号、姓名、年龄、性别、邮箱地址:
mysql> create table t_student(
-> no int,
-> name varchar(32),
-> sex char(1),
-> age int(3),
-> email varchar(255)
-> );
Query OK, 0 rows affected (0.01 sec)
删除表:
drop table t_student; # 当这张表不存在的时候会报错!
drop table if exists t_student; # 如果这张表存在,就删除
12.4 insert–插入数据(DML)
语法格式:
insert into 表名(字段名1, 字段名2, 字段名3...) values(值1, 值2, 值3...);
# 注意:字段名和值要一一对应
示例,
# 插入数据
mysql> insert into t_student(no, name, sex, age, email) values(1, 'zhangsan', 'm', 20, '[email protected]');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t_student(email, name, sex, age, no) values('[email protected]', 'lisi', 'f', 20, 2);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t_student(no) values(3);
Query OK, 1 row affected (0.00 sec)
# 查看表单
mysql> select * from t_student;
+------+----------+------+------+------------------+
| no | name | sex | age | email |
+------+----------+------+------+------------------+
| 1 | zhangsan | m | 20 | zhangsan@123.com |
| 2 | lisi | f | 20 | lisi@qq.com |
| 3 | NULL | NULL | NULL | NULL |
+------+----------+------+------+------------------+
3 rows in set (0.00 sec)
# 插入数据
mysql> insert into t_student values(4);
ERROR 1136 (21S01): Column count doesn’t match value count at row 1
mysql> insert into t_student values(4, 'kaka', 's', 22, '[email protected]');
Query OK, 1 row affected (0.00 sec)
# 查看表单
mysql> select * from t_student;
+------+----------+------+------+------------------+
| no | name | sex | age | email |
+------+----------+------+------+------------------+
| 1 | zhangsan | m | 20 | zhangsan@123.com |
| 2 | lisi | f | 20 | lisi@qq.com |
| 3 | NULL | NULL | NULL | NULL |
| 4 | kaka | s | 22 | kaka@123.com |
+------+----------+------+------+------------------+
4 rows in set (0.00 sec)
注意:
- insert语句但凡是执行成功了,必然会多一条记录。
- 没有给其他字段指定值的话,默认值是NULL
- insert语句中的 “字段名” 可以省略,当字段名全部省略时 <==> 都写上 ==> 所以值也要都写上。
12.5 insert–插入日期
12.5.1 数字格式化
数字格式化关键字:
format(数字字段名, '格式')
mysql> select ename, sal from emp;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| ALLEN | 1600.00 |
| WARD | 1250.00 |
| JONES | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
| TURNER | 1500.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| FORD | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+
14 rows in set (0.00 sec)
mysql> select ename, format(sal, '$999,999') as 'format sal' from emp;
+--------+------------+
| ename | format sal |
+--------+------------+
| SMITH | 800 |
| ALLEN | 1,600 |
| WARD | 1,250 |
| JONES | 2,975 |
| MARTIN | 1,250 |
| BLAKE | 2,850 |
| CLARK | 2,450 |
| SCOTT | 3,000 |
| KING | 5,000 |
| TURNER | 1,500 |
| ADAMS | 1,100 |
| JAMES | 950 |
| FORD | 3,000 |
| MILLER | 1,300 |
+--------+------------+
14 rows in set, 14 warnings (0.00 sec)
12.5.2 有关varchar 和 date类型的转换
str_to_date: 将字符串varchar类型转换成date类型
语法格式:str_to_date('字符串日期', '日期格式')
date_format: 将date类型转换成具有一定格式的varchar字符串类型
语法格式:date_format(日期类型数据, '日期格式')
# 这个函数通常使用在查询日期方面,设置展示的日期格式
mysql的日期格式:
%Y 年
%m 月
%d 日
%h 时
%i 分
%s 秒
注意:数据库中有一条命名规范 ~ 所有的标识符全部小写,单词和单词之间使用下划线进行衔接
示例见下面12.5.3插入数据 案例,
12.5.3 插入数据
先创建一个名为 t_user 的表单,包含ID,名字,生日等信息:
# 法1
mysql> create table t_user(
-> id int,
-> name varchar(32),
-> birth date # 生日可以使用date日期类型
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> desc t_user;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| birth | date | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
# 法2
mysql> create table t_user(
-> id int,
-> name varchar(32),
-> birth char(10) # 生日也可以使用字符串类型(1999-09-09 ---> 十个字符)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> desc t_user;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| birth | char(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
向 “法1” 的表单中插入数据:
str_to_date 的应用
# date类型不匹配,需要转换
mysql> insert into t_user(id, name, birth) values(1, 'zhangsan', '01-10-1999');
ERROR 1292 (22007): Incorrect date value: '01-10-1999' for column 'birth' at row 1
# 插入数据
mysql> insert into t_user(id, name, birth) values(1, 'zhangsan', str_to_date('01-10-1999', '%d-%m-%Y')); # 需要str_to_date进行字符串转换
Query OK, 1 row affected (0.00 sec)
# 查看表单
mysql> select * from t_user;
+------+----------+------------+
| id | name | birth |
+------+----------+------------+
| 1 | zhangsan | 1999-10-01 |
+------+----------+------------+
1 row in set (0.00 sec)
# 再插入数据
mysql> insert into t_user(id, name, birth) values(2, 'lisi', '2000-11-11'); # 这里的日期格式是%Y-%m-%d,就不需要str_to_date
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+------+----------+------------+
| id | name | birth |
+------+----------+------------+
| 1 | zhangsan | 1999-10-01 |
| 2 | lisi | 2000-11-11 |
+------+----------+------------+
2 rows in set (0.00 sec)
date_format
mysql> select id, name, date_format(birth, '%m/%d/%Y') as birth from t_user;
+------+----------+------------+
| id | name | birth |
+------+----------+------------+
| 1 | zhangsan | 10/01/1999 |
| 2 | lisi | 11/11/2000 |
+------+----------+------------+
2 rows in set (0.00 sec)
12.6 date和datetime类型的区别
- date是短日期:只包含 年月日 信息
默认格式:%Y-%m-%d
- datetime是长日期:包含 年月日时分秒 信息
默认格式:%Y-%m-%d %h:%i:%s
mysql> drop table if exists t_user;
Query OK, 0 rows affected (0.00 sec)
mysql> create table t_user(
-> id int,
-> name varchar(32),
-> birth date,
-> create_time datetime # 注意这里
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t_user(id, name, birth, create_time) values(1, 'lisi', '1999-12-12', '2021-11-13 23:29:34');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+------+------+------------+---------------------+
| id | name | birth | create_time |
+------+------+------------+---------------------+
| 1 | lisi | 1999-12-12 | 2021-11-13 23:29:34 |
+------+------+------------+---------------------+
1 row in set (0.00 sec)
在mysql中如何获取系统当前时间?
- now() 函数,并且获取的时间带有:时分秒 信息!是 datetime类型。
mysql> insert into t_user(id, name, birth, create_time) values(2, 'wangwu', '2050-01-01', now()); # 注意now()
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+------+--------+------------+---------------------+
| id | name | birth | create_time |
+------+--------+------------+---------------------+
| 1 | lisi | 1999-12-12 | 2021-11-13 23:29:34 |
| 2 | wangwu | 2050-01-01 | 2021-11-13 23:33:23 |
+------+--------+------------+---------------------+
2 rows in set (0.00 sec)
12.7 修改update(DML)
语法格式:
update 表名 set 字段名1 = 值1, set 字段名2 = 值2, set 字段名3 = 值3... where 条件;
# 注意!没有条件限制会导致所有数据全部更新
# 更新id = 2的数据
mysql> update t_user set name = 'jack', birth = '2000-12-30', create_time = now() where id = 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t_user;
+------+------+------------+---------------------+
| id | name | birth | create_time |
+------+------+------------+---------------------+
| 1 | lisi | 1999-12-12 | 2021-11-13 23:29:34 |
| 2 | jack | 2000-12-30 | 2021-11-13 23:37:29 |
+------+------+------------+---------------------+
2 rows in set (0.00 sec)
# 更新全部数据
mysql> update t_user set name = 'abc';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from t_user;
+------+------+------------+---------------------+
| id | name | birth | create_time |
+------+------+------------+---------------------+
| 1 | abc | 1999-12-12 | 2021-11-13 23:29:34 |
| 2 | abc | 2000-12-30 | 2021-11-13 23:37:29 |
+------+------+------------+---------------------+
2 rows in set (0.00 sec)
12.8 删除数据delete(DML)
语法格式:
delete from 表名 where 条件;
# 注意!没有条件,整张表会全部删除
# 删除id = 2的数据
mysql> delete from t_user where id = 2;
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+------+------+------------+---------------------+
| id | name | birth | create_time |
+------+------+------------+---------------------+
| 1 | abc | 1999-12-12 | 2021-11-13 23:29:34 |
+------+------+------------+---------------------+
1 row in set (0.00 sec)
mysql> insert into t_user(id) values(2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+------+------+------------+---------------------+
| id | name | birth | create_time |
+------+------+------------+---------------------+
| 1 | abc | 1999-12-12 | 2021-11-13 23:29:34 |
| 2 | NULL | NULL | NULL |
+------+------+------------+---------------------+
2 rows in set (0.00 sec)
# 删除所有数据
mysql> delete from t_user;
Query OK, 2 rows affected (0.01 sec)
mysql> select * from t_user;
Empty set (0.00 sec)
*下面是补充内容
12.9 插入多条数据
mysql> insert into t_user(id, name, birth, create_time) values
-> (1, 'zs', '1992-12-02', now()),
-> (2, 'lili', '1298-09-08', now()),
-> (3, 'www', '2121-08-08', now());
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from t_user;
+------+------+------------+---------------------+
| id | name | birth | create_time |
+------+------+------------+---------------------+
| 1 | zs | 1992-12-02 | 2021-11-14 09:00:23 |
| 2 | lili | 1298-09-08 | 2021-11-14 09:00:23 |
| 3 | www | 2121-08-08 | 2021-11-14 09:00:23 |
+------+------+------------+---------------------+
3 rows in set (0.00 sec)
12.10 快速创建表(了解)
原理:
- 当一个查询结果当作一张表新建,这个可以完成表的快速复制,表创建出来后同时表中的数据也存在了。
mysql> create table mytable as select empno, ename from emp where job = 'MANAGER';
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> show tables;
+----------------------+
| Tables_in_bjpowernod |
+----------------------+
| dept |
| emp |
| emp2 |
| mytable |
| salgrade |
| t_user |
+----------------------+
6 rows in set (0.00 sec)
12.11 将查询结果插到一张表中(了解)
mysql> create table dept_bak as select * from dept;
Query OK, 4 rows affected (0.06 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from dept_bak;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
4 rows in set (0.00 sec)
# 将查询结果插入到一张表当中,,,很少用到
mysql> insert into dept_bak select * from dept;
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from dept_bak;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
8 rows in set (0.00 sec)
12.12 truncate–快速删除表中的数据(★★★★)
注意!删除的是表中的数据,表还在!
删除表的操作:
drop table 表名;
delete语句删除数据的原理?(delete属于DML语句)
- 表中的数据被删除了,但这个数据在硬盘上的真实存储空间不会被释放
- 缺点:删除效率低
- 优点:支持回滚,后悔了可以再恢复数据
truncate语句删除数据的原理?(DDL语句)
- 删除效率比较高,表被一次截断,物理删除
- 缺点:不支持回滚
- 优点:快速
- 用法:
truncate table 表名;
举例,大表非常大时,可能有上亿条记录:
如果选择使用delete,也许需要执行1个小时才能删除完,效率比较低!
可以选择使用truncate删除表中的数据,只需要不到1秒钟就删除结束,效率较高!但是在使用truncate之前,一定要仔细询问客户是否真的要删除,并警告删除之后不可恢复!
mysql> delete from dept_bak; # 这种删除数据的方式比较慢
Query OK, 8 rows affected (0.00 sec)
mysql> select * from dept_bak;
Empty set (0.00 sec)
mysql> truncate table emp2; # 快
Query OK, 0 rows affected (0.01 sec)
mysql> select * from emp2;
Empty set (0.00 sec)
mysql> show tables;
+----------------------+
| Tables_in_bjpowernod |
+----------------------+
| dept |
| dept_bak |
| emp |
| emp2 |
| mytable |
| salgrade |
| t_user |
+----------------------+
7 rows in set (0.00 sec)
12.13 对表结构的增删改
什么是对表结构的修改?
- 添加一个字段,删除一个字段,修改一个字段
对表结构的修改需要使用alter
,属于DDL语句。
DDL包括:create drop alter
第一:在实际的开发中,需求一旦确定后,表一旦设计好,很少进行表结构的修改。因为在开发中进行修改表结构,成本是比较高的。
修改表的结构后,对应的 Java/Go/C++ 代码就需要进行大量的修改。这个责任将由设计人员来承担!第二:由于修改表结构的操作需要很少,无需掌握,若有一天真的需要修改表结构,可以使用工具。