# 介绍
## 数据库的概念
* 数据库:存储数据的仓库
* 数据库类型:【层次式数据库,网络式数据库】,关系型数据库
## 关系型数据库
* 常用的关模型来存储的数据的数据库叫做关系型数据库
* 常见数据库
* 商业数据库
* Oracle
* SQL Server
* DB2
* Sybase
* 开源数据库
* MySQL
* SQL Lite
## 登陆MySQL
* 方式一:搜索mysql命令窗口,然后直接点击输入密码
* 方式二:打开cmd命令提示符窗口,然后输入命令
* `mysql -u root -p`—回车
* `enter password:`—输入密码123456
~~~
C:\Users\Administrator>mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.7.27 MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
~~~
* * *
# database基本命令
## 创建一个数据库
1. 默认字符集utf8
> 默认字符集情况下,大小写不敏感
`create database test01;`
2. 设置字符集为gbk
> `character set`:指定数据库采用的字符集
`create database test02 character set gbk;`
3. 大小写敏感问题: A=a 是相等的吗??
> `collate`校对规则
>
> `utf8_general_ci` :大小写不敏感
>
> `utf8_bin`:大小写敏感
* 大小写不敏感:`create database test02 character set utf8 collate utf8_general_ci;`
* 大小写敏感:`create database javaweb02 character set utf8 collate utf8_bin;`
4. 判断是否存在,存在不创建,不存在则创建
> `if not exists`
`create database if not exists javaweb;`
~~~
mysql> create database test01;
Query OK, 1 row affected (0.03 sec)
mysql> create database test02 character set gbk;
Query OK, 1 row affected (0.01 sec)
mysql> create database test03 character set utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.07 sec)
~~~
* * *
## 获取所有的数据的配置文件路径
1. 模糊查询
> `like(%con%)`
>
> * like:模糊查询,匹配字符
>
> * %%:之间写要匹配的内容,任意一对匹配即可
>
~~~
show variables like '%con%';# variables:变量
show variables like '%dir%';
~~~
* * *
## 显示、删除数据库
* 显示所有的数据库
> `show database;`
~~~
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
~~~
* 显示数据库创建语句
> `show create database test01;`
* 数据库删除语句
* 正常删除
`drop database test01;`
* 扩展:
> 在没有test08库下,删除test08
> `mysql> drop database test08;`//报错
>
> `mysql> drop database if exists test08;`//警告
>
> \==加if exists后就不会报错==
~~~
mysql> drop database if exists test08;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> drop database if exists test08;
Query OK, 0 rows affected, 1 warning (0.00 sec)
~~~
* * *
## 修改数据库
> 改变数据库的字符集以及字符集的检对规则
>
> `mysql> alter database test01 character set gbk;`
~~~
mysql> alter database test01 character set gbk;
Query OK, 1 row affected (0.00 sec)
~~~
* * *
## 选择/使用数据库
> `use xxx;`
~~~
mysql> use test
Database changed
~~~
## 查看当前使用的数据库
> `select database();`
~~~
mysql> select database();
+------------+
| database() |
+------------+
| test |
+------------+
1 row in set (0.00 sec)
~~~
* * *
## 退出命令
> `ctrl+c`键盘组合按键 `exit;` `quit;`
~~~
mysql> exit
Bye
mysql> quit
Bye
~~~
* * *
# table基本命令
> MySQL常用的数据类型
>
> * 字符串型
>
> * varchar、char
>
> * 大数据类型
>
> * blob、text
>
> * 数值型
>
> * tinyint、smallint、int、bigint、float、double
>
> * 逻辑型
>
> * bit(1:true/0:false)
>
> * 日期型
>
> * date、time、datetime、timestamp
>
## 创建表
> 必须先使用一个数据库才能创建表
>
> \==语法格式==:`create table 表名();`
~~~
create table db_user
(
id int(10),
name varchar(20),
password varchar(20),
birthday date
);
~~~
## 查看表结构
> 查看一个表的表结构
>
> \==语法格式==:`desc 表名;`
~~~
desc employee;
~~~
## 查看所有表
> 查看当前使用的库中的所有表
>
> \==语法格式==:`show tables;`
~~~
show tables;
~~~
## 查看表的创建 语句
> 查看创建该表的sql语句
>
> \==语法格式==:`show create table 表名;`
~~~
show create table user;
~~~
## 表单字段的约束
> * 定义==主键约束==
>
> * `primary key`:主键,不允许为空,不允许重复;
>
> * 删除主键:`alter table table_name drop primary key;`
>
> * 主键自增:`auto_increment`
>
> * \==一个表中可以有多个主键,称为联合主键==
>
> * 定义==唯一约束==
>
> * `unique`
>
> * 例如:`name varchar(20) unique`:表明name不能重复
>
> * 定义==非空约束==
>
> * `not null`
>
> * 例如:`salary double not null`:表明salary字段不能为空
>
~~~
create table employee
(
id int primary key auto_increment,/*主键、自增*/
name varchar(200) unique not null ,/*not null不能为空 unique:不可重复*/
gender char(1) not null ,
birthday date,
entry_date date,
job varchar(10),
salary double not null ,
resume text/*文本类型:可以存放篇幅较长的纯文本*/
);
~~~
## 修改表
> * 添加:==add==
>
> `alter table table_name add column_name column_type;`
>
> * 修改:==modify==
>
> `alter table table_name modify column_name column_type;`
>
> * 删除:==drop==
>
> `alter table table_name drop column_name ;`
>
> * 修改表名:==rename==
>
> `rename table old_table_name to new_table_name;`
>
> * 修改字段名
>
> `alter table table_name change column_name new_column_name column_type;`
>
1. 添加实例
> 在员工表的基础上添加一个 image 列,类型为:blob
~~~
alter table employee add image blob;#二进制形式存储,大类型
~~~
2. 修改实例
> 修改job列,使其长度为60
~~~
alter table javaweb.employee modify job varchar(60);
~~~
3. 删除实例
> 删除gender列
~~~
alter table javaweb.employee drop gender;
~~~
4. 修改表名实例
> 表名改为employee1
~~~
rename table javaweb.employee to employee1;
~~~
5. 修改表中字段名实例
> 列名name修改为username
~~~
alter table employee change name username varchar(30);
~~~
## 删除表
> 删除选定的表以及表中的所有数据
>
> \==语法格式==:`drop table table_name;`
~~~
drop table user;
~~~
* * *
# 数据库的CRUD
> 数据库表记录CRUD语句
>
> * Insert语句(增加数据)
>
> * Update语句(更新数据)
>
> * Delete语句(删除数据)
>
> * Select语句(查找数据)
>
## mysql中文乱码
> * mysql有六处使用了字符集,分别为:
>
> * clinet、connection、database、results、server、system
>
> * client是客户端使用的字符集
>
> * connection是连接数据库的字符集设置类型,如果程序没有指明连接数据库使用的字符集类型,就按照服务器端默认的字符集设置
>
> * database是数据服务器中某个库使用的字符集设定,如果建库时没有指明,将使用服务器安装时指定的字符集设置
>
> * results是数据库给客户端返回时使用的字符集设定,如果没有指明,使用服务器默认的字符集
>
> * server是服务器安装时指定的默认字符集设定
>
> * system是数据库系统使用的字符集设定(utf-8不可修改)
>
> * `show variables like 'character%';`
>
> * `set names gbk;`临时修改当前cmd窗口和mysql的通信编码字符集
>
> * 通过修改my.ini 修改字符集编码
>
> > 修改此文件时,先停止mysql服务,完成后重新启动
> >
> > 停止:`net stop mysql`
> >
> > 启动:`net start mysql`
>
>
> ~~~
> [mysql]
> # 设置mysql客户端默认字符集
> default-character-set=utf8
> [mysqld]
> #设置3306端口
> port = 3306
> # 设置mysql的安装目录
> basedir=D:\mysql\mysql-5.7.27-winx64
> # 设置mysql数据库的数据的存放目录
> datadir=D:\mysql\data
> # 允许最大连接数
> max_connections=200
> # 服务端使用的字符集默认为8比特编码的latin1字符集
> character-set-server=utf8
> # 创建新表时将使用的默认存储引擎
> default-storage-engine=INNODB
>
> ~~~
* * *
## Insert语句
\==语法格式==:
~~~
insert into table_name[参数列表,.......]
values(column_value,column_value.....);
~~~
> 向表中插入一条数据
>
> * 插入的数据应与字段的数据类型相同;
>
> * 字符串是数值类型时/数值是字符串类型时:mysql会根据类型自动转换再插入
>
> * 日期:必须符合日期格式
>
> * 数据的大小应该在列的定义范围内,例如:不能将一个长度为80的字符串加入到长度为40的列中。
>
> * 在values中列出的数据位置必须与被加入的列的排列位置相对应。
>
> * \==字符和日期型数据应包含在单引号中。==
>
> * 插入空值:不指定或`insert into table value(null)`
>
> * 如果要插入所有字段可以省写列列表,直接按表中字段顺序写值列表
>
> * 数据尝试插入数据库失败时,这条记录也会使用一个自增索引,如果插入失败,也会占用一个主键
>
* 向employee表中插入员工信息
~~~
insert into javaweb.employee values
(
default,'卤岩','2010-01-01','2019-01-01','掏粪工',100,'这是一个gou信息',null
);
~~~
* * *
## Update语句
\==语法格式:==
~~~
update 表名
set 列名=值 [,col2_name=expr2]
[where 条件语句];
~~~
`where`:表示有条件的关键字,可以在这个关键字之后添加条件内容,sql语句只会影响满足条件的行。
> 作用:
>
> * update语法可以用新值更新原有表行中的各列
>
> * set子句指示要修改哪些列和要赋予哪些值
>
> * where子句指定应用更新哪些行。如果没有where,则更新所有的行
>
* 将所有员工的薪水修改为5000元
~~~
update employee
set salary = 5000;
~~~
* 将姓名为“李帅”的员工的薪水修改为3000元
~~~
update employee
set salary = 3000
where username = '李帅';
~~~
* 将姓名为“曹洋”的员工薪水修改为4000元,job改为ccc
~~~
update employee
set salary = 4000,
job = 'ccc'
where username = '曹洋';
~~~
* 将“李帅”的薪水在原有基础上加1000元
~~~
update employee
set salary = salary + 1000
where username = '李帅';
~~~
## Delete语句
\==语法格式:==
~~~
delete from table_name [where where_definition]
~~~
> 作用:
>
> * 删除表中的数据
>
> * 如果不使用where子句,将删除表中所有数据
>
> * delete只能删除行,不能删除列。可用update
>
> `update table_name set 字段名='';`
>
> * delete语句仅删除记录,不删除表本身。如要删除表,使用`drop table`语句
>
> `drop table table_name;`
>
> * 同inset和update一样,从一个表中删除记录将引起其他表的参照完整性问题,在修改数据库数据时,始终不能忘记一个潜在的问题:==外键约束==
>
> * 删除表中数据也可使用`truncate table`语句
>
> * truncate:删除整张表然后再重建
>
>
> delete和truncate的比较:
>
> * `truncate`:删除效率高,但是可能会摧毁表于表之间的关系。单表可以使用,多表不要使用
>
> * `delete from`:逐条删除表中记录,效率较低,但是不会摧毁表,能维护表结构和表关系。适用于单表和双表
>
* 删除表中id为73的记录
~~~
delete
from employee
where id = 10;
~~~
* 删除表中所有的记录
~~~
delete
from employee;
~~~
* 使用truncate删除表中记录
~~~
truncate employee;
~~~
## Select语句
> 关键字的执行优先级:
>
> `from > where > select > order by`
### 基本select语句
\==语法格式==:
~~~
select [distinct] *|{col1,col2,.....}
from 表名;
~~~
> 作用:
>
> * 查询数据
>
> * `select`:指定查询哪些列的数据
>
> * `col`:指定列名
>
> * `*`:代表查询所有列
>
> * `from`:指定查询哪张表
>
> * `distinct`:可选,指显示结果时,是否提出重复数据
>
* 查询表中所有学生的信息
~~~
select *
from exam;
~~~
* 查询表中所有的学生的姓名和对应的英语成绩
~~~
select name, english
from exam;
~~~
* 过滤表中重复数据:`distinct`去重
> 只要一行中有一个数据与其他行数据不一样,就不算是重复数据
~~~
select distinct *
from exam;
~~~
* 过滤英语成绩相同的数据
~~~
select distinct english
from exam;
~~~
* * *
### 含有表达式
\==语法格式==
~~~
select * | {col1 | expression, col2 | expression....}
from 表名
~~~
\==as别名==
> 使用别名时,`as`可省略,直接用空格隔开即可
~~~
select 列名 as 别名
from 表名
~~~
* 在所有的学生分数上加特长分10分,并显示
~~~
#别名带有as
select name,
chinese + 10 as chHight,
math + 10 as mathHight,
english + 10 as enHight
from exam;
#别名,省略as
select name,
chinese + 10 chHight,
math + 10 mathHight,
english + 10 enHight
from exam;
~~~
* 统计每个学生的总分
~~~
select name, chinese + math + english as sum
from exam;
~~~
* * *
### 有where条件
\==语法格式==
~~~
select xxx
from 表名
where 条件
~~~
* 查询英语成绩大于90分的同学
~~~
select *
from exam
where english > 90;
~~~
* 查询总分大于200分的所有同学
~~~
#错误写法:因为关键字执行顺序:from->where->select->order by
#where语句优先于select,所以where中无法用select中的别名
select name,chinese+math+english as sum
from exam
where sum>200;
#正确写法:
select name,chinese+math+english as sum
from exam
where chinese+math+english>200;
~~~
* * *
### 有运算符
\==where子句中常用的运算符==
**比较运算符**
| 运算符 | 解释 |
| --- | --- |
| , =, =, <> | 小于,大于,小于(大于)等于,不等于 |
**逻辑运算符**
| 运算符 | 解释 |
| --- | --- |
| between...and... | 显示在某一区间的值 |
| `in(set)` | 显示在in列表中的值。例:`in(100,200)` |
| `like '张%'` | 模糊查询: `%`代表0-多个任意字符; `_`表示一个字符 |
| `is null` | 判断是否为空: `select * from user where id is null;` |
| `ifnull(原值,替代值)` | 如果原值为null,则使用代替值 `select ifnull(score,0) from exam;` |
| and | 多个条件同时成立 |
| or | 多个条件任意一个成立即可 |
| not | 不成立。例:`where not(salary>100);` |
* 查询英语分数在80-100之间的同学
> `between...and...`所表示的区间为`[n,m]`
~~~
select *
from exam
where english between 70 and 95;
~~~
* 查询数学分数为75,86,87的同学
~~~
select *
from exam
where math in(75,86,87);
~~~
* 查询所有姓张的同学的成绩
~~~
select *
from exam
where name like '张%';
~~~
* 查询数学分数>70,语文分数>80的同学
~~~
select *
from exam
where math>70 and chinese>80;
~~~
* 查询数学分>70,或者语文分>80的同学
~~~
select *
from exam
where math>70 or chinese>80;
~~~
* 查询数学不及格(60分)的同学
~~~
select *
from exam
where math not(math>=60);
#写法二:
select *
from exam
where math<60;
~~~
* 查询未参加数学考试(null)的同学
~~~
select name,ifnull(math,0)
from exam
where math is null;
~~~
### 有order by
> `order by` 特点:
>
> * 永远写在整个sql语句的最后
>
> * 是所有关键字中最后一个执行的关键字
>
>
> 扩展:
>
> * `order by`会严重影响查询效率,使查询速度变得很慢
>
\==语法格式==
> `asc`:升序(默认)
>
> `desc`:降序
>
> `order by` 指定排序的列,可以是表中的列名,也可以是select语句后指定的列名
~~~
select 字段名1,字段名2,...
from 表名
order by 字段名 asc|desc
~~~
* 对语文成绩排序后输出
~~~
#不写参数,默认升序
select *
from exam
order by chinese;
#参数升序
select *
from exam
order by chinese asc;
#参数降序
select *
from exam
order by chinese desc;
~~~
* 对总分按照降序输出
~~~
select name,chinese+ifnull(math,0)+english as sum
from exam
order by sum desc;
~~~
* 对姓关的学生的成绩排序输出
~~~
select *
from exam
where name like '关%'
order by chinese;
~~~
### 分组操作
> 分组子句和聚集函数经常在一起使用。表示在分组后,在进行每组的聚集函数执行操作
\==语法格式==
~~~
select 列名,...
from 表名
group by 字段名
~~~
**图解**:
![](https://gitee.com/sxhDrk/images/raw/master/imgs/%E5%A4%96%E9%94%AE.jpg)
* 对订单中商品归类后,显示每一类商品的总价
~~~
select product sum(price)
from orders
group by product;
~~~
#### having子句
> 对分组结果进行过滤
>
> \==having和where的区别:==
>
> * where在分组前进行条件过滤
>
> * having在分组后进行条件过滤
>
> * 使用where的地方都可以用having替换。但是having可以使用分组函数,而where后不可以使用
>
* 查询购买了几类商品,并且每类总价大于100的商品
~~~
select product
from oreders
group by product
having sum(price)>100;
~~~
## 聚集函数
### count
> 求表中一共有多少行
\==语法格式==
> `count(*)`
>
> `count(1)`:参数可以是任意值,可查询出行数
~~~
select count(*)|count(列名)
from 表名
[where 判断语句];
~~~
* 统计一个班有多少个学生
~~~
#通过count(*)统计
select count(*)
from exam;
#通过count(1)统计
select count(1)
from exam;
#通过count(id)统计
select count(id)
from exam;
~~~
* 统计数学成绩大于90的学生有多少个
~~~
select count(*)
from exam
where math>90;
~~~
* 统计总分大于250的人数
~~~
select count(1)
from exam
where chinese+ifnull(math,0)+english>250;
~~~
### sum
> 求某一列的和
\==语法格式==
~~~
select sum(列名) {,sum(列名),...}
from 表名
[where 条件]
~~~
> 注意:
>
> * sum仅对数值起作用,否则会报错
>
> * 对多列求和,`,`号不能少
>
* 统计一个班级数学总成绩
~~~
select sum(math) as mathSum
from exam;
~~~
* 统计一个班语文、英语、数学各科的总成绩
~~~
select sum(chinese) cSum,
sum(english) eSum,
sum(ifnull(math,0)) mSum
from exam;
~~~
* 统计一个班级语文、英语、数学的成绩总和
~~~
select sum(chinese+english+ifnull(math,0))
from exam;
#写法二
select sum(chinese)+
sum(ifnull(math,0))+
sum(english)
from exam;
~~~
* 统计一个班级语文成绩的平均分
~~~
select sum(chinese)/count(chinese) chAvg
from exam;
~~~
### avg
> 求平均值
\==语法格式==
~~~
select avg(列名) {,avg(列名),...}
from 表名
~~~
* 求一个班级数学的平均分
~~~
select avg(ifnull(math,0))
from exam;
~~~
* 求一个班级总分的平均分
~~~
select avg(chinese+ifnull(math,0)+english) avg
from exam;
~~~
### max/min
> 求最大值/最小值
\==语法格式==
~~~
select max(列名)/min(列名)
from 表名
[where 条件]
~~~
* 求班级英语最高分和最低分
~~~
select max(english) max,
min(english) min
from exam;
~~~
* 求班级最高语文成绩的学生姓名和成绩值
~~~
select *
from exam;
where chinese =
(
select max(chinese)
from exam;
)
~~~
* * *
# 库的导出&导入
## 导出
> 可视化工具导出
* IDEA中,右键要导出的database,选择:dump with mysqldump
* 窗口中选择mysqldump.exe
* 下方out path选择要导出的路径,最后点Run
> cmd窗口导出(不常用)
* mysqldump -u 用户名 -p 数据库名 > 文件名.sql
* mysqldump -u root -p
* db\_name > d:/1.sql
## 导入
> 可视化工具IDEA
* 选择目标数据库,右键——>Run Sql Script
* 选择导出的.spl文件即可
> cmd窗口导入(不常用)
* mysql –u 用户名 -p 数据库名 < 文件名.sql
* mysql -u root -p db\_name < d:/1.sql
* mysql -u root -p mydb3 < d:/1.sql
* * *
# 外键
> 只是描述一种两表之间的关系
>
> 不建议使用
>
> * 大数据量大吞吐量的表,有外键的话,影响执行效率
>
> * 小数据量的表,也可以不适用
>
* 图示:
![](https://gitee.com/sxhDrk/images/raw/master/imgs/group-by.png)
* 插入数据时:先向主键中插入信息,再向声明外键的表中插入信息
* 删除数据时:先把声明外键的表中数据删除,再把主键中的数据删除
* * *
# 多表设计
> 表于表之间的一种关系描述
## 1对1
> 案例:user基本表,userInfo详细表
* user基本表
~~~
create table user
(
id int primary key auto_increment,
name varchar(20)
);
insert into user values (default, '张三');
insert into user values (default, '李四');
insert into user values (default, '王五');
insert into user values (default, '王六');
insert into user values (default, '王器');
insert into user values (default, '王巴');
~~~
* userInfo详细表
~~~
create table userInfo
(
user_id int primary key,
email varchar(20),
phone varchar(15),
address varchar(100)
);
insert into userInfo values (1, '110@qq.com', '110', '家');
insert into userInfo values (2, '120@qq.com', '110', '家');
insert into userInfo values (3, '130@qq.com', '110', '家');
insert into userInfo values (4, '140@qq.com', '110', '家');
insert into userInfo values (8, '140@qq.com', '180', '家');
insert into userInfo values (9, '140@qq.com', '190', '家');
~~~
### 查询
* 写法一:
~~~
select *
from user,userInfo
where userInfo.user_id = user.id;
~~~
![](https://gitee.com/sxhDrk/images/raw/master/imgs/1%E5%AF%B9%E5%A4%9A.png)
* 写法二:
> `join`:内连接
>
> * join左边的表 与 join右边的表 通过on的条件去查询,只有当左边的表有记录且 右边的表也有记录,才能查询出来
>
> * ![](https://gitee.com/sxhDrk/images/raw/master/imgs/%E5%B7%A6%E8%BF%9E%E6%8E%A5.jpg)
>
~~~
select *
from user
join userinfo
on user.id=userInfo.user_id;
~~~
![](https://gitee.com/sxhDrk/images/raw/master/imgs/1%E5%AF%B9%E5%A4%9A.png)
* 写法三:
> `left join` :左连接。
>
> * 左表作为主表,去关联右表。
>
> * 无论左表中的数据 是否 能够匹配右表,左表的数据都全部显示
>
> * ![](https://gitee.com/sxhDrk/images/raw/master/imgs/%E5%B7%A6%E8%BF%9E%E6%8E%A5%E7%A4%BA%E6%84%8F%E5%9B%BE.jpg)
>
~~~
select *
from user
left join userinfo
on user.id=userInfo.user_id;
~~~
![](https://gitee.com/sxhDrk/images/raw/master/imgs/%E5%86%85%E8%BF%9E%E6%8E%A5.jpg)
* 写法四:
> `right join`:右连接
>
> * 右表作为主表,关联左表
>
> ![](https://gitee.com/sxhDrk/images/raw/master/imgs/%E5%8F%B3%E8%BF%9E%E6%8E%A5.jpg)
>
~~~
select *
from user
right join userinfo
on user.id=userInfo.user_id;
~~~
![](https://gitee.com/sxhDrk/images/raw/master/imgs/%E5%8F%B3%E8%BF%9E%E6%8E%A5%E7%A4%BA%E6%84%8F%E5%9B%BE.jpg)
* 写法五:笛卡儿积查询(==执行结果没有意义==)
> * 没有on查询条件
>
> * 表1有m条数据,表2有n条数据,匹配结果是:m\*n条数据
>
>
> 缺点:
>
> * 全匹配的效果,执行效率很慢,执行结果没有意义
>
> * 以后在使用多表查询时,一定要要加上关联条件(on ....)
>
~~~
select * from user,userinfo;
~~~
## 1对多
> 案例:emp员工表,dept部门表
>
> 一个部门对应着多名员工
* emp员工表
~~~
create table emp(
id int primary key auto_increment,
dept_id int,/*对应部门表的id主键*/
name varchar(20)
);
insert into emp values (default,100,'张三');
insert into emp values (default,100,'李四');
insert into emp values (default,100,'王五');
insert into emp values (default,100,'王六');
~~~
* dept部门表
~~~
create table dept(
dept_id int primary key auto_increment,
dept_name varchar(20)
);
insert into dept values (100,'大数据开发部');
insert into dept values (200,'大数据运维部');
~~~
### 查询
* 查询每一名员工所在的部门信息
~~~
select *
from emp
left join dept
on emp.dept_id=dept.dept_id;
~~~
![](https://gitee.com/sxhDrk/images/raw/master/imgs/1%E5%AF%B9%E5%A4%9A%E5%B7%A6%E8%BF%9E%E6%8E%A5.jpg)
* 查询一个部门下所有的员工
~~~
select *
from emp
right join dept
on emp.dept_id=dept.dept_id;
~~~
![](https://gitee.com/sxhDrk/images/raw/master/imgs/1%E5%AF%B9%E5%A4%9A%E5%8F%B3%E8%BF%9E%E6%8E%A5.jpg)
## 多对多
> 案例:teacher表,student表
>
> 多对多关系下,必须要有一个关系表,来维护两表之间的联系
>
> 一个老师对应多个学生,一个学生对应多个老师
* teacher表
~~~
create table teacher(
t_id int primary key auto_increment,
t_name varchar(20),
t_age int
);
insert into teacher values (default,'曹洋',38);
insert into teacher values (default,'许宁',38);
insert into teacher values (default,'朴乾',38);
~~~
* student表
~~~
create table student(
s_id int primary key auto_increment,
s_name varchar(20),
s_age int
);
insert into student values (default,'梁山伯',20);
insert into student values (default,'祝英台',18);
insert into student values (default,'西门庆',19);
~~~
* t\_s关系表
> 多对多的关系下:必须要维护一个关系表
~~~
create table t_s(
t_id int,/*与老师表的id对应*/
s_id int/*与学生表的id对应*/
);
#一个老师有多个学生,一个学生对应多个老师
insert into t_s values (1,1);
insert into t_s values (1,2);
insert into t_s values (1,3);
#第二个老师的学生
insert into t_s values (2,1);
insert into t_s values (2,2);
insert into t_s values (2,3);
#第三个老师
insert into t_s values (3,1);
insert into t_s values (3,2);
~~~
### 查询
* 查询每一个老师下面对应的学生的信息,要求:显示老师信息同时显示学生信息
![](https://gitee.com/sxhDrk/images/raw/master/imgs/%E5%A4%9A%E5%AF%B9%E5%A4%9A%E6%9F%A5%E8%AF%A2.jpg)
~~~
select tt.*,s.s_name,s.s_age
from(select t.*,ts.s_id
from teacher t
join t_s ts
on t.t_id=ts.t_id
) tt join student s on tt.s_id=s.s_id;
~~~
![](https://gitee.com/sxhDrk/images/raw/master/imgs/%E5%A4%9A%E5%AF%B9%E5%A4%9A.jpg)
* * *
# 面试题
## delete与truncate的区别
* delete:
* delete from删除表中的数据
* 逐条删除,效率较低,但不会摧毁表,能维护表结构和表关系。适用于单表或多表的删除
* truncate:
* 删除整张表然后再重建
* 删除效率较高,但是可能会摧毁表于表之间的关系。适用于单表的删除
## select语句的\*和单独写索引效率问题
一个sql的查询效率和索引有很大关系。
* 如果一个表中有索引,将会大大提升查询效率
* 使用`*`号和书写全部字段都会使用id这个索引,只要使用索引,他们的查询效率都会很高
* 如一定要去分两者效率,则书写全部字段比书写\*号要快一些
* 原因:
* `*`号需要判断当前表中使用了哪些字段
* 直接书写字段名称:数据库只需要根据指定的字段名称查询即可,无需判断使用了哪些字段
## count(\*)和count(1)谁的效率更高
`count(*)`和`count(1)`两者的执行效率相似。
* 如果表中的字段数量较少,则两者的查询效率几乎一致
* 如果字段中字段数量较多,
* `count(1)`查询效率稍快
* `count(*)`在计数之前需要统计有多少个字段,这个统计时间十分短暂,可以忽略不计。
* 所以在字段数量较少的时候,两者的查询效率是一致的
数据库中存在范式这个概念。范式是用来规定当前数据库建表时的规范。这个规范规定了如何创建一个表。例如:字段中的数据含义必须独立。字段之间关联性降至最低等
按照这些规范来创建的表,字段数量一定不会很多,所以字段数量较多这种情况,一般不会存在。所以就不会考虑`count(*)`统计多个字段的时间。
最终可以认为`count(*)`和`count(1)`两者的执行效率是一致的。
- 导读
- Mysql
- Mysql基础
- Msql事务
- Mysql书写技巧
- Mysql索引
- 集合操作
- SQL复习
- Linux
- shell基础
- shell基础命令
- shell基本命令
- shell判断语句
- 运算符
- 循环语句
- 函数
- 练习
- 案例
- Java启动脚本
- CentOS7 FTP安装与配置
- 安装Mysql
- 安装Redis
- 防火墙
- 安装JDK
- MongoDB
- MongoDB安装
- MongoDB账号管理
- MongoDB增删改查
- MongoDB索引
- 数据备份与恢复
- MongoDB其它
- MongoDB分组聚合复杂查询
- Nginx
- Nginx安装配置
- Nginx使用
- Kafka
- Kafka介绍
- Kafka概念
- Linux安装Kafka
- windows环境安装kafka
- SpringBoot整合Kafka
- Docker
- 入门
- Docker常用命令
- Docker镜像
- Docker容器数据卷
- Dockerfile解析
- Docker常用安装
- Docker本地镜像发布阿里云
- SpringBoot
- Maven项目管理
- SpringBoot入门
- SpringBoot配置文件
- 整合持久层框架
- SpringBoot案例
- SpringBoot解决跨域
- 参数校验
- SpringBoot单元测试