# 介紹
## 數據庫的概念
* 數據庫:存儲數據的倉庫
* 數據庫類型:【層次式數據庫,網絡式數據庫】,關系型數據庫
## 關系型數據庫
* 常用的關模型來存儲的數據的數據庫叫做關系型數據庫
* 常見數據庫
* 商業數據庫
* 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 字段名
~~~
**圖解**:

* 對訂單中商品歸類后,顯示每一類商品的總價
~~~
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
* * *
# 外鍵
> 只是描述一種兩表之間的關系
>
> 不建議使用
>
> * 大數據量大吞吐量的表,有外鍵的話,影響執行效率
>
> * 小數據量的表,也可以不適用
>
* 圖示:

* 插入數據時:先向主鍵中插入信息,再向聲明外鍵的表中插入信息
* 刪除數據時:先把聲明外鍵的表中數據刪除,再把主鍵中的數據刪除
* * *
# 多表設計
> 表于表之間的一種關系描述
## 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;
~~~

* 寫法二:
> `join`:內連接
>
> * join左邊的表 與 join右邊的表 通過on的條件去查詢,只有當左邊的表有記錄且 右邊的表也有記錄,才能查詢出來
>
> * 
>
~~~
select *
from user
join userinfo
on user.id=userInfo.user_id;
~~~

* 寫法三:
> `left join` :左連接。
>
> * 左表作為主表,去關聯右表。
>
> * 無論左表中的數據 是否 能夠匹配右表,左表的數據都全部顯示
>
> * 
>
~~~
select *
from user
left join userinfo
on user.id=userInfo.user_id;
~~~

* 寫法四:
> `right join`:右連接
>
> * 右表作為主表,關聯左表
>
> 
>
~~~
select *
from user
right join userinfo
on user.id=userInfo.user_id;
~~~

* 寫法五:笛卡兒積查詢(==執行結果沒有意義==)
> * 沒有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;
~~~

* 查詢一個部門下所有的員工
~~~
select *
from emp
right join dept
on emp.dept_id=dept.dept_id;
~~~

## 多對多
> 案例: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);
~~~
### 查詢
* 查詢每一個老師下面對應的學生的信息,要求:顯示老師信息同時顯示學生信息

~~~
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;
~~~

* * *
# 面試題
## 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單元測試