1. 程式人生 > 實用技巧 >MySQL一篇從入門到精通

MySQL一篇從入門到精通

1、Mysql資料庫面試必備

1.1、MySQL各個版本介紹

簡介:各個版本的區別 官網:https://dev.mysql.com/downloads/mysql/

  • MySQL Community Server 社群版本,開源免費,但不提供官方技術支援。
  • MySQL Enterprise Edition 企業版本,需付費,購買了之後可以電話支援
  • MySQL Cluster 叢集版,開源免費。可將幾個MySQL Server封裝成一個Server。

1.2、MySQL安裝—win版

Mysql5.7-64位下載地址:https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-winx64.zip

1、下載後得到zip壓縮包.

2、解壓到自己想要安裝到的目錄,本人解壓到的是D:\Environment\mysql-5.7.19

3、新增環境變數:我的電腦->屬性->高階->環境變數->選擇PATH,在其後面新增:mysql 安裝檔案下的bin資料夾

4、新建編輯 my.ini 檔案 ,注意替換路徑位置

[mysqld]
basedir=D:\Program Files\mysql-5.7\
datadir=D:\Program Files\mysql-5.7\data\
port=3306
skip-grant-tables

5、啟動管理員模式下的CMD,並切換至mysql下的bin目錄,將mysql 註冊成服務

# mysqld --install 服務名稱
mysqld --install mysql5.7.19

6、初始化資料檔案輸入(使用其中一個即可):

# 方式一:初始化使用者密碼為空,同時生成Data資料夾
mysqld --initialize-insecure --user=mysql
# 方式二:會列印root使用者的初始預設密碼,同時並生成Data資料夾
mysqld --initialize --console

7、然後再次啟動mysql 然後用命令 mysql –u root –p 進入mysql管理介面(密碼可為空)

8、進入介面後更改root密碼,然後重新整理許可權

-- 修改密碼
update mysql.user set authentication_string=password('password') where user='root' and Host='localhost';

-- 重新整理許可權
flush privileges;

10、修改 my.ini檔案刪除最後一句skip-grant-tables

11、重啟mysql即可正常使用

net stop mysql
net start mysql

12、刪除服務命令

# mysqld --remove 服務名稱
mysqld --remove mysql

1.3、MySQL安裝—Linux版

1、安裝開發工具包和依賴包

# 安裝開發工具包
$ yum groups mark install 'Development Tools'
$ yum -y install wget bzip2 bzip2-devel gcc gcc-c++

# 安裝依賴包
$ yum -y install ncurses-devel openssl-devel openssl cmake mariadb-devel

2、為mysql建立使用者和組

# 建立使用者和組
$ groupadd -r -g 306 mysql
$ useradd -r -M -s /sbin/nologin -g mysql mysql

3、下載二進位制格式的mysql軟體包

# 下載二進位制格式的mysql軟體包
$ cd /usr/src/
$ wget https://downloads.mysql.com/archives/get/file/mysql-5.7.23-linux-glibc2.12-x86_64.tar.gz

4、解壓軟體至/usr/local/

# 解壓軟體至/usr/local/
$ tar xf mysql-5.7.23-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
$ cd /usr/local/

$ ln -s mysql-5.7.23-linux-glibc2.12-x86_64/ mysql
注:
1.ln軟連線,-s是代號(symbolic)的意思;
2.使用方法:ln -s 原始檔 目標檔案;
3.我們需要在不同的目錄,用到相同的檔案時,我們只要在其它目錄下用ln命令連結(link)它就可以,不必重複的佔用磁碟空間。

5、修改目錄/usr/local/mysql的屬主屬組,新增環境變數

# 修改目錄/usr/local/mysql的屬主屬組,新增環境變數
# 注:-R處理指定目錄以及其子目錄下的所有檔案
$ chown -R mysql.mysql /usr/local/mysql
$ echo 'export PATH=/usr/local/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
$ ./etc/profile.d/mysql.sh 

6、建立資料存放目錄

$ mkdir /opt/data
$ chown -R mysql.mysql /opt/data/

7、初始化資料庫

$ /usr/local/mysql/bin/mysqld --initialize --user=mysql --datadir=/opt/data/

8、配置mysql

$ ln -sv /usr/local/mysql/include/ /usr/local/include/mysql
‘/usr/local/include/mysql’ -> ‘/usr/local/mysql/include/’

$ echo '/usr/local/mysql/lib' > /etc/ld.so.conf.d/mysql.conf
$ ldconfig -v

9、生成配置檔案

[root@zzg local]# cat > /etc/my.cnf <<EOF
> [mysqld]
> basedir = /usr/local/mysql
> datadir = /opt/data
> socket = /tmp/mysql.sock
> port = 3306
> pid-file = /opt/data/mysql.pid
> user = mysql
> skip-name-resolve
> EOF

10、配置服務啟動指令碼

$ cp -a /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
$ sed -ri 's#^(basedir=).*#\1/usr/local/mysql#g' /etc/init.d/mysqld
$ sed -ri 's#^(datadir=).*#\1/opt/data#g' /etc/init.d/mysqld

11、啟動

$ service mysqld start

12、修改密碼

mysql> set password = password(123456');

mysql的核心知識之服務管理

簡介:mysql的service服務管理與登入管理

檢視mysql服務程序:ps -ef | grep mysql service
服務管理:cp -a mysql.server /etc/rc.d/init.d/mysql
啟動命令:service mysql start
關閉命令:service mysql stop
重新啟動命令:service mysql restart
檢視狀態命令:service mysql status
登入管理:ln -s /usr/local/mysql/bin/*  /bin 
登入命令:mysql -uroot -p
預設埠號:3306 
配置檔案:/etc/my.cnf

1.4、MySQL各類語句精講

簡介:MySQL的操作語句分類

名稱 解釋 命令
DDL 資料定義語言 (Data Definition Language) 建庫、建表 CREATE、DROP、ALTER
DML 資料操縱語言(Data Manipulation Language) 表中資料的增刪改操作 INSERT、UPDATE、DELETE
DQL 資料查詢語言(Data Query Language) 對資料進行查詢 SELECT
DCL 資料控制語言(Data Control Language) 對使用者的許可權進行設定 GRANT、commit、 rollback

2、DDL資料定義語言

2.1、資料庫建立/檢視/使用/切換

簡介:細講資料庫的建立使用

--直接建立資料庫 db1
create database db1;

--檢視當前在哪個庫裡邊
select database();

--進入庫的操作
use 庫名;

--判斷是否存在,如果不存在則建立資料庫 db2
create database if not exists db2;

--建立資料庫並指定字符集為 gbk
create database db3 default character set gbk;

--檢視某個庫是什麼字符集;
show create database XD; 

--檢視當前mysql使用的字符集
show variables like 'character%';

2.2、建表之常用資料型別

<1>整數型
     型別      大小      範圍(有符號)               範圍(無符號unsigned)    用途
     TINYINT   1 位元組    (-128,127)                (0,255)                 小整數值
     SMALLINT  2 位元組    (-32768,32767)            (0,65535)               大整數值
     MEDIUMINT 3 位元組    (-8388608,8388607)        (0,16777215)            大整數值
     INT       4 位元組    (-2147483648,2147483647)  (0,4294967295)          大整數值
     BIGINT    8 位元組    (-2的63次方,-2的63次方減1)  (0,2的64次方減1)          極大整數值

<2>浮點型
 FLOAT(m,d)  4 位元組    單精度浮點型  備註:m代表總個數,d代表小數位個數
 DOUBLE(m,d) 8 位元組    雙精度浮點型  備註:m代表總個數,d代表小數位個數
 
 <3>定點型
 DECIMAL(m,d)    依賴於M和D的值,如果M>D,為M+2否則為D+2位元組   備註:m代表總個數,d代表小數位個數
 
 <4>字串型別 
 型別          大小              用途
 CHAR          0-255位元組         定長字串
 VARCHAR       0-65535位元組       變長字串
 TINYTEXT      0-255位元組         短文字字串
 TEXT          0-65535位元組       長文字資料
 MEDIUMTEXT    0-16777215位元組    中等長度文字資料
 LONGTEXT      0-4294967295位元組  極大文字資料
 
 char的優缺點:存取速度比varchar更快,但是比varchar更佔用空間
 varchar的優缺點:比char省空間。但是存取速度沒有char快
 
 <5>時間型
 資料型別    位元組數          格式                    備註
 date        3             yyyy-MM-dd             儲存日期值
 time        3             HH:mm:ss               儲存時分秒
 year        1             yyyy                   儲存年
 datetime    8             yyyy-MM-dd HH:mm:ss    儲存日期+時間
 timestamp   4             yyyy-MM-dd HH:mm:ss    儲存日期+時間,可作時間戳(根據時區來顯示)
  • 時間型別:
create table test_time (
    date_value date,
    time_value time,
    year_value year,
    datetime_value datetime,
    timestamp_value timestamp
) engine=innodb charset=utf8;
-- 插入時間資料
insert into test_time values(now(), now(), now(), now(), now());

mysql> select * from test_time;
+------------+------------+------------+---------------------+---------------------+
| date_value | time_value | year_value | datetime_value      | timestamp_value     |
+------------+------------+------------+---------------------+---------------------+
| 2020-07-26 | 14:19:44   |       2020 | 2020-07-26 14:19:44 | 2020-07-26 14:19:44 |
+------------+------------+------------+---------------------+---------------------+
  • Decima(定點型)和 Float/Double(浮點型)區別:

其區別在於:float,double等非標準型別,在DB中儲存的是近似值,而Decimal則以字串的形式儲存數值。

float有個壞處,當你給定的資料是整數的時候,那麼它就以整數給你處理。這樣我們在存取貨幣值的時候自然遇到問題,我的default值為:0.00而實際儲存是0,同樣我存取貨幣為12.00,實際儲存是12。

幸好mysql提供了兩個資料型別:decimal,這種資料型別可以輕鬆解決上面的問題:decimal型別被 MySQL 以同樣的型別實現,這在 SQL92 標準中是允許的。他們用於儲存對準確精度有重要要求的值,例如與金錢有關的資料。

create table t1(
    field_float float(10,2) default null, 
    field_decimal decimal(10,2) default null
);
insert into t1 values
(1234567.21, 1234567.21),
(9876543.21, 9876543.12),
(98765430.21, 98765430.12);

mysql> select * from t1;
+-------------+---------------+
| field_float | field_decimal |
+-------------+---------------+
|  1234567.25 | 1234567.21    |
|  9876543.00 | 9876543.12    |
| 98765432.00 | 98765430.12   |
+-------------+---------------+
浮點型float:
1234567.21 出現偏差:1234567.25
9876543.21 出現偏差:9876543.00
98765430.21出現偏差:98765432.00


create table t2(
    field_float float(5,2) default null,
    field_double double(5,2) default null,
    field_decimal decimal(5,2) default null
);
insert into t2 values (1.2345,1.2345,1.2345);
insert into t2 values (12.345,12.345,12.345);
insert into t2 values (123.45,123.45,123.45);
insert into t2 values (1234.5,1234.5,1234.5);
insert into t2 values (123.4,123.4,123.4);

mysql> select * from t2;
+-------------+--------------+---------------+
| field_float | field_double | field_decimal |
+-------------+--------------+---------------+
|        1.23 |         1.23 | 1.23          |
|       12.35 |        12.35 | 12.35         |
|      123.45 |       123.45 | 123.45        |
|      999.99 |       999.99 | 999.99        |
|      123.40 |       123.40 | 123.40        |
+-------------+--------------+---------------+

1.2345 --- 小數點後最多2位,所以儲存可以,自動四捨五入資料截斷,輸出: 1.23
12.345 --- OK,小數位超1為,由於超出位為5,自動四捨五入,最後得出為 12.35
123.45 --- 正好符合3個整數位和2個小數位
1234.5 --- 因為小數位未滿2位,要補0.所以應該為1234.50,但是整個位數超出了5,儲存報錯,輸出999.99
123.4 ---  小數未滿部分補0。按照123.40儲存

預設狀態比較:

浮點數如果不寫經度和標度,會按照實際精度值儲存,如果有精度和標度,則會自動將四捨五入後的結果插入,系統不會報錯;定點數如果不寫精度和標度,則按照預設值decimal(10,0) 來操作,如果資料超過了精度和標度值,系統會報錯。

2.3、建立資料表

簡介:講解表是怎麼來建立的,以及常見約束條件舉例說明

  • 建表
CREATE TABLE 表名 (
    欄位名1 欄位型別1 約束條件1 說明1,
    欄位名2 欄位型別2 約束條件2 說明2,
    欄位名3 欄位型別3 約束條件3 說明3
);
  • 複製表
-- 1.1.只複製表結構到新表,注意:這種方式用於日常測試,因為可能索引等會複製不過來
create table 新表名 as select * from 舊錶名 where 1=2;

-- 1.2.複製表結構及資料到新表
create table 新表名 as select * from 舊錶名

-- 2.複製表結構及資料到新表
create table 新表名 like 舊錶名;
  • 約束條件
comment         ----說明解釋
not null        ----不為空
default         ----預設值
unsigned        ----無符號(即正數)
auto_increment  ----自增
zerofill        ----自動填充,不足位數的用0來填充,如 int(3),5則為005
unique key      ----唯一值
  • 測試
CREATE TABLE student (
    id tinyint(5) zerofill auto_increment  not null comment '學生學號',
    name varchar(20) default null comment '學生姓名',
    age  tinyint  default null comment '學生年齡',
    class varchar(20) default null comment '學生班級',
    sex char(5) not null comment '學生性別',
    unique key (id)
)engine=innodb charset=utf8;

CREATE TABLE student (
    id tinyint(5)  auto_increment  default null comment '學生學號',
    name varchar(20) default null comment '學生姓名',
    age  tinyint  default null comment '學生年齡',
    class varchar(20) default null comment '學生班級',
    sex char(5) not null comment '學生性別',
    unique key (id)
)engine=innodb charset=utf8;

2.4、資料表檢視

簡介:如何查看錶的基本結構資訊

  • 檢視資料庫中的所有表:show tables;
  • 檢視建立表的sql語句:show create table 表名;
  • 查看錶結構:desc 表名;
  • \G :有結束sql語句的作用,還有把顯示的資料縱向旋轉90度,替換“ ; ”
  • \g :有結束sql語句的作用,等同 “ ; ”
  • 查看錶資訊:show table status\G
--語法:
 --[FROM db_name]可選,表示查詢哪個資料庫下面的表資訊。
--[LIKE 'pattern'] 可選,表示查詢哪些具體的表名
show table status [FROM db_name] [LIKE 'pattern']

-- 檢視當前庫所有表的資訊:
show table status\G
-- 查詢db_name 資料庫裡所有表的資訊
show table status from db_name\G
-- 查詢db_name 裡 table_name 表的資訊
show table status from db_name like 'table_name '\G
-- 查詢db_name 資料庫裡表名以tb開頭的表的資訊
show table status from db_name LIKE 'tb%'\G
  • 輸出欄位解釋:
mysql> show table status like 'tableName' \G

Name:表名稱
Engine:表的儲存引擎
Version:版本
Row_format:行格式。對於MyISAM引擎,這可能是Dynamic,Fixed或Compressed。動態行的行長度可變,例如Varchar或Blob型別欄位。固定行是指行長度不變,例如Char和Integer型別欄位
Rows:表中的行數。對於MyISAM和其他儲存引擎,這個值是精確的,對於innoDB儲存引擎,這個值通常是估算的
Avg_row_length:平均每行包括的位元組數 
Data_length:整個表的資料量(以位元組為單位)
Max_data_length:表可以容納的最大資料量,該值和儲存引擎相關
Index_length:索引佔用磁碟的空間大小(以位元組為單位)
Data_free:對於MyISAM引擎,表示已經分配,但目前沒有使用的空間。這部分空間包含之前被刪除的行,以及後續可以被insert利用到的空間
Auto_increment:下一個Auto_increment的值
Create_time:表的建立時間
Update_time:表的最近更新時間
Check_time:使用 check table 或myisamchk工具最後一次檢查表的時間
Collation:表的預設字符集和字元排序規則
Checksum:如果啟用,儲存的是整個表的實時校驗和
Create_options:建立表時指定的其他選項
Comment:包含了其他額外資訊,對於MyISAM引擎,儲存的是表在建立時帶的註釋。如果表使用的是innodb引擎 ,儲存的是InnoDB表空間的剩餘空間。如果是一個檢視,註釋裡面包含了VIEW字樣。
  • 其他示例:
-- 檢視資料庫中的所有表:
mysql> show tables;
+---------------------+
| Tables_in_jdbcstudy |
+---------------------+
| t1                  |
| t2                  |
| test_time           |
| student             |
+---------------------+
4 rows in set (0.04 sec)


-- 檢視建立表的sql語句:
-- show create table 表名;
mysql> show create table test_time;
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                                                                                                                                 |
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_time | CREATE TABLE `test_time` (
  `date_value` date DEFAULT NULL,
  `time_value` time DEFAULT NULL,
  `year_value` year(4) DEFAULT NULL,
  `datetime_value` datetime DEFAULT NULL,
  `timestamp_value` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.05 sec)


-- 查看錶結構:
-- desc 表名;
mysql> desc test_time;
+-----------------+-----------+------+-----+---------+-------+
| Field           | Type      | Null | Key | Default | Extra |
+-----------------+-----------+------+-----+---------+-------+
| date_value      | date      | YES  |     | NULL    |       |
| time_value      | time      | YES  |     | NULL    |       |
| year_value      | year(4)   | YES  |     | NULL    |       |
| datetime_value  | datetime  | YES  |     | NULL    |       |
| timestamp_value | timestamp | YES  |     | NULL    |       |
+-----------------+-----------+------+-----+---------+-------+
5 rows in set (0.00 sec)


-- \G:有結束sql語句的作用,把顯示的資料縱向旋轉90度,替換;
mysql> show create table test_time\G
*************************** 1. row ***************************
       Table: test_time
Create Table: CREATE TABLE `test_time` (
  `date_value` date DEFAULT NULL,
  `time_value` time DEFAULT NULL,
  `year_value` year(4) DEFAULT NULL,
  `datetime_value` datetime DEFAULT NULL,
  `timestamp_value` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


-- \g :有結束sql語句的作用,等同 ;
desc test_time\g
-- 等同於
desc test_time;

2.5、資料表結構維護與刪除

簡介:細講核心知識表結構的修改

  • 修改表名
rename table 舊錶名 to 新表名;
rename table student to user;
  • 新增列
-- 給表新增一列:
alter table 表名 add 列名 型別;
alter table user add addr varchar(50);

alter table 表名 add 列名 型別 comment '說明';
alter table user add famliy varchar(50) comment '學生父母';

-- 給表最前面新增一列:
alter table 表名 add 列名 型別 first;
alter table user add job varchar(10) first;

-- 給表某個欄位後新增一列:
alter table 表名 add 列名 型別 after 欄位名;
alter table user add servnumber int(11)  after id;

-- 注意:沒有給表某個欄位前新增一列的說法。
  • 刪除列
alter table 表名 drop 列名;
alter table user drop famliy;
  • 修改列型別
alter table 表名 modify 列名 新型別;
alter table user modify servnumber varchar(20);
  • 修改列名
alter table 表名 change 舊列名 新列名 型別;
alter table user change servnumber telephone varchar(20);
  • 修改字符集
alter table 表名 character set 字符集;
alter table user character  set GBK;
  • 資料表的刪除
-- 如刪除不存在的資料表會丟擲錯誤
drop table 表名;
drop table user;

-- 看錶是否存在,若存在則刪除表:
drop table if exists 表名;
drop table if exists teacher;

3、DML資料操縱語言

3.1、資料新增

簡介:講解表資料新增的多種例子

  • 普通的插入表資料
insert into 表名(欄位名) values(欄位對應值);

-- 選擇欄位插入資料
insert into employee (empno,ename,job,mgr,hiredate,sal,deptnu) 
values ('1000','小明','經理','10001','2019-03-03','12345.23','10');

-- 所有欄位都插入時可以省略欄位名
insert into 表名 values(所有欄位對應值);
insert into employee  values ('1001','小明','經理','10001','2019-03-03','12345.23','10');   
  • 蠕蟲複製(將一張表的資料複製到另一張表中)
insert into 表名1 select * from 表名2;​
insert into 表名1(欄位名1,欄位名2) select 欄位名1,欄位名2 from 表名2;

insert into emp (empno,ename) select empno,ename from employee;
  • 建表複製
create table 表名1 as select 欄位名1,欄位名2 from 表名2;

create table emp as select empno ,ename from employee;
  • 一次性插入多個數據
insert into 表名 (欄位名1,欄位名2) values (值1,值2),(值3.值4),(值5,值6);
  • 建立SQL:
--某個公司的員工表
CREATE TABLE employee(
    empno       INT PRIMARY KEY comment '僱員編號',
    ename       VARCHAR(20) comment '僱員姓名',
    job         VARCHAR(20) comment '僱員職位',
    mgr         INT comment '僱員上級編號',
    hiredate    DATE comment '僱傭日期',
    sal         DECIMAL(7,2) comment '薪資',
    deptnu      INT comment '部門編號'
);

3.2、表資料的修改及刪除

簡介:講解如何對錶資料進行修改刪除以及注意事項

  • 修改(更新):
update 表名 set 欄位名1=值1 where 欄位名=值;
update 表名 set 欄位名1=值1,欄位名2=值2 where 欄位名=值;
  • 刪除:
delete from 表名 where 欄位名=值;

--刪除表的三種方式
truncate table 表名;
delete from 表名;
drop table 表名;
  • 刪除速度:
drop > truncate > delete
  • 注意事項:
面試時:面試官問在刪改資料之前,你會怎麼做?
答案:會對資料進行備份操作,以防萬一,可以進行資料回退

面試時:delete與truncate與drop 這三種刪除資料的共同點都是刪除資料,他們的不同點是什麼?
    1.delele 會把刪除的操作記錄給記錄起來,以便資料回退,不會釋放空間,而且不會刪除定義。
    2.truncate不會記錄刪除操作,會把表佔用的空間恢復到最初,不會刪除定義
    3.drop會刪除整張表,釋放表佔用的空間。

3.3、中文亂碼問題

簡介:詳細講解漢字顯示亂碼問題

  • 檢視當前mysql使用的字符集:show variables like 'character%';
mysql> show variables like 'character%';
+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | utf8                             |
| character_set_connection | utf8                             |
| character_set_database   | utf8                             |
| character_set_filesystem | binary                           |
| character_set_results    | utf8                             |
| character_set_server     | utf8                             |
| character_set_system     | utf8                             |
| character_sets_dir       | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+

- character_set_client:客戶端請求資料的字符集
- character_set_connection:客戶端與伺服器連線的字符集
- character_set_database:資料庫伺服器中某個庫使用的字符集設定,如果建庫時沒有指明,將預設使用配置上的字符集
- character_set_results:返回給客戶端的字符集(從資料庫讀取到的資料是什麼編碼的)
- character_set_server:為伺服器安裝時指定的預設字符集設定。
- character_set_system:系統字符集(修改不了的,就是utf8)
- character_sets_dir:mysql字符集檔案的儲存路徑
  • 臨時修改:
mysql> set character_set_xxx gbk;
  • 永久修改:修改配置檔案my.cnf裡邊的
[client]
default-character-set=gbk
#作用於外部的顯示

[mysqld]
character_set_server=gbk
#作用於內部,會作用於建立庫表時預設字符集
  • 修改庫的字符集編碼
alter database xiaoxiao default character set gbk;
  • 修改表的字符集編碼
alter table employee default character set utf8;

4、DQL資料查詢語言

簡介:細講對資料表中的資料進行各種查詢,以及專案實戰查詢

/*建立部門表*/
CREATE TABLE dept(
    deptnu      INT  PRIMARY KEY comment '部門編號',
    dname       VARCHAR(50) comment '部門名稱',
    addr        VARCHAR(50) comment '部門地址'
);

某個公司的員工表
CREATE TABLE employee(
    empno       INT  PRIMARY KEY comment '僱員編號',
    ename       VARCHAR(50) comment '僱員姓名',
    job         VARCHAR(50) comment '僱員職位',
    mgr         INT comment '僱員上級編號',
    hiredate    DATE comment '僱傭日期',
    sal         DECIMAL(7,2) comment '薪資',
    deptnu      INT comment '部門編號'
)ENGINE=MyISAM DEFAULT CHARSET=utf8;

/*建立工資等級表*/
CREATE TABLE salgrade(
    grade       INT  PRIMARY KEY comment '等級',
    lowsal      INT comment '最低薪資',
    higsal      INT comment '最高薪資'
);

/*插入dept表資料*/
INSERT INTO dept VALUES (10, '研發部', '北京');
INSERT INTO dept VALUES (20, '工程部', '上海');
INSERT INTO dept VALUES (30, '銷售部', '廣州');
INSERT INTO dept VALUES (40, '財務部', '深圳');

/*插入emp表資料*/
INSERT INTO employee VALUES (1009, '唐僧', '董事長', NULL, '2010-11-17', 50000,  10);
INSERT INTO employee VALUES (1004, '豬八戒', '經理', 1009, '2001-04-02', 29750, 20);
INSERT INTO employee VALUES (1006, '猴子', '經理', 1009, '2011-05-01', 28500, 30);
INSERT INTO employee VALUES (1007, '張飛', '經理', 1009, '2011-09-01', 24500,10);
INSERT INTO employee VALUES (1008, '諸葛亮', '分析師', 1004, '2017-04-19', 30000, 20);
INSERT INTO employee VALUES (1013, '林俊杰', '分析師', 1004, '2011-12-03', 30000, 20);
INSERT INTO employee VALUES (1002, '牛魔王', '銷售員', 1006, '2018-02-20', 16000, 30);
INSERT INTO employee VALUES (1003, '程咬金', '銷售員', 1006, '2017-02-22', 12500, 30);
INSERT INTO employee VALUES (1005, '後裔', '銷售員', 1006, '2011-09-28', 12500, 30);
INSERT INTO employee VALUES (1010, '韓信', '銷售員', 1006, '2018-09-08', 15000,30);
INSERT INTO employee VALUES (1012, '安琪拉', '文員', 1006, '2011-12-03', 9500,  30);
INSERT INTO employee VALUES (1014, '甄姬', '文員', 1007, '2019-01-23', 7500, 10);
INSERT INTO employee VALUES (1011, '妲己', '文員', 1008, '2018-05-23', 11000, 20);
INSERT INTO employee VALUES (1001, '小喬', '文員', 1013, '2018-12-17', 8000, 20);

/*插入salgrade表資料*/
INSERT INTO salgrade VALUES (1, 7000, 12000);
INSERT INTO salgrade VALUES (2, 12010, 14000);
INSERT INTO salgrade VALUES (3, 14010, 20000);
INSERT INTO salgrade VALUES (4, 20010, 30000);
INSERT INTO salgrade VALUES (5, 30010, 99990);

4.1、where條件查詢

簡介:詳解where條件下的各種查詢

  • 簡單查詢
select * from employee;
select empno,ename,job as ename_job from employee;
  • 精確條件查詢
select * from employee where ename='後裔';
select * from employee where sal != 50000;
select * from employee where sal <> 50000;
select * from employee where sal > 10000;
  • 模糊條件查詢
show variables like '%aracter%'; 
select * from employee  where ename like '林%';
  • 範圍查詢
select * from employee where sal between 10000 and 30000;
select * from employee where hiredate between '2011-01-01' and '2017-12-1';
  • 離散查詢
select * from employee where ename in ('猴子','林俊杰','小紅','小胡');  
  • 清除重複值
select distinct(job) from employee;
統計查詢(聚合函式):
  • 統計查詢(聚合函式):
--count(code)或者count(*)
select count(*) from employee;
select count(ename) from employee;
        
--sum()  計算總和 
select sum(sal) from employee;
        
--max()    計算最大值
select * from employee where sal= (select  max(sal) from employee);
        
--avg()   計算平均值
select avg(sal) from employee;
        
--min()   計算最低值
select * from employee where sal= (select  min(sal) from employee);
        
--concat函式: 起到連線作用
select concat(ename,' 是 ',job) as aaaa from employee;

4.2、group by分組查詢(分組)

簡介:詳解group by的用法以及應用場景

  • 作用:把行 按 欄位 分組
  • 語法:group by 列1,列2....列N
  • 適用場合:常用於統計場合,一般和聚合函式連用
select deptnu,count(*) from employee group by deptnu;
select deptnu,job,count(*) from employee group by deptnu,job;
select job,count(*) from employee group by job;

4.3、having條件查詢(篩選)

簡介:詳解having的用法以及應用場景

  • 作用:對查詢的結果進行篩選操作
  • 語法:having 條件 或者 having 聚合函式 條件
  • 適用場合:一般跟在group by之後
select job,count(*) from employee group by job having job ='文員';
select  deptnu,job,count(*) from employee group by deptnu,job having count(*)>=2;
select  deptnu,job,count(*) as 總數 from employee group by deptnu,job having 總數>=2;

4.4、order by排序查詢(排序)

簡介:詳解order by的用法以及應用場景

  • 作用:對查詢的結果進行排序操作
  • 語法:order by 欄位1,欄位2 .....
  • 適用場合:一般用在查詢結果的排序
select * from employee order by sal;
select * from employee order by hiredate;
select  deptnu,job,count(*) as 總數 from employee group by deptnu,job having 總數>=2 order by deptnu desc;
select  deptnu,job,count(*) as 總數 from employee group by deptnu,job having 總數>=2 order by deptnu asc;
select  deptnu,job,count(*) as 總數 from employee group by deptnu,job having 總數>=2 order by deptnu;

-- 順序:where ---- group by ----- having ------ order by 

4.5、limit限制查詢(限制)

簡介:詳解limit的用法以及應用場景

  • 作用:對查詢結果起到限制條數的作用
  • 語法:limit n,m n:代表起始條數值,不寫預設為0;m代表:取出的條數
  • 適用場合:資料量過多時,可以起到限制作用
select * from XD.employee limit 4,5;

4.6、exists 型子查詢

簡介:詳解exists的用法

  • exists型子查詢後面是一個受限的select查詢語句
  • exists子查詢,如果exists後的內層查詢能查出資料,則返回 TRUE 表示存在;為空則返回 FLASE則不存在。
  • 分為倆種:exists 跟 not exists​
select 1 from employee where 1=1;
select * from 表名 a where exists (select 1 from 表名2 where 條件);

-- 查詢出公司有員工的部門的詳細資訊
select * from dept a where exists (select 1 from employee b where a.deptnu=b.deptnu);
select * from dept a where not exists (select 1 from employee b where a.deptnu=b.deptnu);

4.7、左連線與右連線查詢

簡介:詳解左右連線的用法以及應用場景

  • 左連線稱之為左外連線 右連線稱之為右外連線 這倆個連線都是屬於外連線
  • 左連線關鍵字:left join 表名 on 條件 / left outer 表名 join on 條件
  • 右連線關鍵字:right join 表名 on 條件/ right outer 表名 join on 條件
  • 左連線說明: left join 是left outer join的簡寫,左(外)連線,左表(a_table)的記錄將會全部表示出來, 而右表(b_table)只會顯示符合搜尋條件的記錄。右表記錄不足的地方均為NULL。
  • 右連線說明:right join是right outer join的簡寫,與左(外)連線相反,右(外)連線,左表(a_table)只會顯示符合搜尋條件的記錄,而右表(b_table)的記錄將會全部表示出來。左表記錄不足的地方均為NULL。
-- 列出部門名稱和這些部門的員工資訊,同時列出那些沒有的員工的部門
-- dept,employee
select a.dname,b.* from dept a  left join employee b on a.deptnu=b.deptnu;
select b.dname,a.* from employee a  right join  dept b on b.deptnu=a.deptnu;

4.8、內連線查詢與聯合查詢

簡介:詳解內連線與聯合查詢的用法以及應用場景

  • 內連線:獲取兩個表中欄位匹配關係的記錄
  • 主要語法:INNER JOIN 表名 ON 條件;
-- 想查出員工張飛的所在部門的地址
select a.addr  from dept a inner join employee b on a.deptnu=b.deptnu and b.ename='張飛';
select a.addr from dept a,employee b where a.deptnu=b.deptnu and b.ename='張飛';
  • 聯合查詢:就是把多個查詢語句的查詢結果結合在一起
    • 主要語法1:... UNION ... (去除重複)
    • 主要語法2:... UNION ALL ...(不去重複)
  • UNION查詢的注意事項:
    • 1.兩個select語句的查詢結果的“欄位數”必須一致;​
    • 2.通常,也應該讓兩個查詢語句的欄位型別具有一致性;​
    • 3.也可以聯合更多的查詢結果;​
    • 4.用到order by排序時,需要加上limit(加上最大條數就行),需要對子句用括號括起來
-- 對銷售員的工資從低到高排序,而文員的工資從高到低排序
(select * from employee a where a.job = '銷售員'  order by a.sal limit 999999) 
    union  
(select * from employee b where b.job = '文員' order by b.sal desc limit 999999);

4.9、專案高階查詢實戰(一)

簡介:高階查詢實戰

  • 查出至少有一個員工的部門。顯示部門編號、部門名稱、部門位置、部門人數。
-- 涉及表: employee dept
-- 語句:
select deptnu,count(*) from employee group by deptnu
-- 語句:
select a.deptnu,a.dname,a.addr, b.zongshu from dept a,
	(select deptnu,count(*) as zongshu from employee group by deptnu) b 
	where a.deptnu=b.deptnu;
  • 列出薪金比安琪拉高的所有員工
--涉及表:employee
--語句:
select * from  employee where sal > (select sal from employee where ename='安琪拉');
  • 列出所有員工的姓名及其直接上級的姓名
-- 涉及表:employee
-- 語句:
select a.ename,ifnull(b.ename,'BOSS') as leader from employee a left join employee b on a.mgr=b.empno;
  • 列出受僱日期早於直接上級的所有員工的編號、姓名、部門名稱
-- 涉及表:employee dept
-- 條件:a.hiredate < b.hiredate
-- 語句:
select a.empno,a.ename,c.dname from employee a 
    left join employee b on a.mgr=b.empno 
    left join dept c on a.deptnu=c.deptnu 
    where a.hiredate < b.hiredate;
  • 列出部門名稱和這些部門的員工資訊,同時列出那些沒有員工的部門
-- 涉及表:dept employee
-- 語句:
select a.dname,b.* from dept a left join employee b on a.deptnu=b.deptnu;
  • 列出所有文員的姓名及其部門名稱,所在部門的總人數
-- 涉及表:employee dept
-- 條件:job='文員'
-- 語句:
select deptnu,count(*) as zongshu from employee group by deptnu;
--語句:
select b.ename,a.dname,b.job,c.zongshu from dept a ,employee b ,
	(select deptnu,count(*) as zongshu from employee group by deptnu) c 
	where a.deptnu=b.deptnu and b.job='文員' and b.deptnu=c.deptnu;

4.10、專案高階查詢實戰(二)

簡介:高階查詢實戰續

  • 列出最低薪金大於15000的各種工作及從事此工作的員工人數
-- 涉及表:employee
-- 條件:min(sal) > 15000 
-- 語句:
select job,count(*) from employee group by job having   min(sal) > 15000;
  • 列出在銷售部工作的員工的姓名,假定不知道銷售部的部門編號
-- 涉及表:employee dept
select  ename  from employee where deptnu=(select deptnu from dept where dname='銷售部');
  • 列出與諸葛亮從事相同工作的所有員工及部門名稱
-- 涉及表:employee dept
-- 語句:
select a.ename,b.dname from employee a,dept b 
	where a.deptnu = b.deptnu 
	and a.job = (select job from employee where ename='諸葛亮');
--語句:
select a.ename,b.dname from employee a 
	left join dept b on a.deptnu = b.deptnu 
	where a.job = (select job from employee where ename='諸葛亮');
  • 列出薪金比 在部門30工作的員工的薪金 還高的員工姓名和薪金、部門名稱
-- 涉及表:employee dept
-- 語句:
select a.ename,a.sal,b.dname from employee a ,dept b 
	where a.deptnu=b.deptnu 
	and sal > (select max(sal) from employee where deptnu=30);
  • 列出每個部門的員工數量、平均工資
-- 涉及表:employee
-- 語句:
select deptnu , count(*) ,avg (sal) from employee  group by deptnu;
  • 列出薪金高於公司平均薪金的所有員工資訊,所在部門名稱,上級領導,工資等級
-- 涉及表:employee dept salgrade
-- 條件:select avg(sal) from employee
-- 語句:
select a.*,c.dname,b.ename,d.grade from employee a,employee b,dept c ,salgrade d 
    where a.mgr=b.empno and a.deptnu =c.deptnu 
    and a.sal > (select avg(sal) from employee) 
    and a.sal between d.lowsal and d.higsal;

5、DCL資料控制語言(使用者許可權)

簡介:精講資料控制語言如何限制使用者的各種許可權

資料控制語言(DCL:Data Control Language)是用來設定或者更改資料庫使用者或角色許可權的語句,
這些語句包括GRANT、DENY、REVOKE等語句。

5.1、限制使用者指定ip登入

簡介:詳解如何從安全形度出發限制root使用者指定ip登入

-- 檢視root使用者可以在哪臺機器登入
select user,host from mysql.user where user='root';

-- 修改mysql庫裡邊的user表
update mysql.user set host='localhost' where user='root';
update mysql.user set host='%' where user='root';

-- 重新整理許可權
flush privileges;

5.2、使用者密碼

簡介:詳解忘記密碼以及如何修改使用者密碼

  • 修改使用者密碼分三種方法:
-- 1.第一種(mysql客戶端介面內)
-- 語法:set password for 使用者@ip = password('密碼');
-- 為當前使用者設定密碼
set password = password('密碼')
-- 為指定使用者設定密碼
set password for root@'%' = password('root');
set password for root@localhost = password('root');
-- 重新整理許可權
flush privileges;


-- 2.第二種(mysql客戶端介面內)
-- 語法:
-- update mysql.user set authentication_string=password('密碼') where user='使用者' and host='ip';
-- 該使用者可以從任意遠端主機登陸
update mysql.user set authentication_string=password('root') where user='root' and host='%';
-- 只有本地使用者可以登入
update mysql.user set authentication_string=password('root') where user='root' and host='localhost';
-- 重新整理許可權
flush privileges;


-- 3.第三種(在Linux介面中):
-- 語法:
-- mysqladmin -u使用者 -p舊密碼 password 新密碼;
mysqladmin -uroot -p password 123456;
mysqladmin -uroot -proot password 123456;
  • 忘記密碼:
  1. 第一步:修改配置檔案my.cnf (預設在/etc/my.cnf),在[mysqld]下面加上 skip-grant-tables (跳過許可權的意思)
  2. 第二步:重啟mysql服務
  3. 第三步:mysql -uroot -p 無需密碼登入進入
  4. 第四步:修改密碼

5.3、建立新使用者並限制ip網段登入

簡介:講解如何建立新使用者與刪除使用者並限制ip登入

  • 建立使用者的語法:
--username:你將建立的使用者名稱 

--host:指定該使用者在哪個主機上可以登陸,如果是本地使用者可用localhost,如果想讓該使用者可以從任意遠端主機登陸,可以使用萬用字元% 

--password:該使用者的登陸密碼,密碼可以為空,如果為空則該使用者可以不需要密碼登陸伺服器

create user 'username'@'host' identified by 'password';
  • 建立使用者
--1.建立一個pig使用者,並指定登入密碼:123456,可以在任何一臺遠端主機都可以登入
create user 'pig'@'%' identified by '123456';
-- 重新整理許可權
flush privileges;

--2.建立一個pig使用者,並指定登入密碼:為空,指定在120網段的機器登入
create user 'pig'@'120.%.%.%' identified by '';
-- 重新整理許可權
flush privileges;
  • 檢視許可權:
-- 查詢
select * from mysql.user where user='pig'\G

mysql> show grants for 'pig'@'%';
+---------------------------------+
| Grants for pig@%                |
+---------------------------------+
| GRANT USAGE ON *.* TO 'pig'@'%' |
+---------------------------------+
1 row in set (0.00 sec)
USAGE:無許可權的意思 


mysql> show grants for 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION        |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)
WITH GRANT OPTION:表示這個使用者擁有grant許可權,即可以對其他使用者授權
  • 刪除使用者
-- 刪除使用者語法:
drop user 'username'@'host';

-- 刪除pig使用者的兩種方式
drop user 'pig'@'%'; 
delete from mysql.user where user='pig';
-- 重新整理許可權
flush privileges;

5.4、庫表許可權授權與回收

簡介:講解如何限制使用者對庫表的增刪改查許可權

  • 授權語法:
grant 許可權1,許可權2..... on 資料庫物件 to '使用者'  [with grant option]

grant 許可權1,許可權2..... on 資料庫物件 to '使用者'@'host' identified by 'password' [with grant option];
  • all privileges:代表所有許可權

  • *.*:代表所有庫所有表

  • with grant option:這個選項表示該使用者可以將自己擁有的許可權授權給別人。

    • 注意:經常有人在建立操作使用者的時候不指定WITH GRANT OPTION選項導致後來該使用者不能使用GRANT命令建立使用者或者給其它使用者授權。
  • 許可權授權

--對現有使用者進行授權:對現有使用者pig授予所有庫所有表所有許可權。 
grant all privileges on *.* to 'pig';

--對沒有的使用者進行授權:建立一個新使用者dog授予XD庫的所有許可權,登入密碼123456,任何一臺主機登入 
grant all privileges on XD.* to 'dog'@'%' identified by '123456';

--對沒有的使用者進行授權:建立一個新使用者cat授予XD庫的employee表 查與修改許可權,登入密碼123456,任何一臺主機登入
grant select,update on XD.employee to 'cat'@'%' identified by '123456';

--對沒有的使用者進行授權:對使用者cat授予XD庫的employee表insert 許可權,登入密碼123456,任何一臺主機登入 
grant insert on XD.employee to 'cat'@'%' identified by '123456';

-- 重新整理許可權
flush privileges;
  • 許可權回收
-- 語法:
revoke 許可權1,許可權2..... on 資料庫物件 from '使用者'@'host';

--回收pig使用者的所有許可權(注意:並沒有回收它的登入許可權) 
revoke all privileges on *.* from 'pig' @ '%'; 
flush privileges;

--回收pig使用者的所有許可權(並回收它的登入許可權) 
delete from mysql.user where user='pig'; 
flush privileges;

--回收cat使用者對XD庫的employee的查與修改許可權 
revoke select,update on XD.employee from 'cat'@'%'; 

-- 重新整理許可權
flush privileges;
  • 許可權解釋
-- 許可權列表
ALL [PRIVILEGES]    -- 設定除GRANT OPTION之外的所有簡單許可權
ALTER    -- 允許使用ALTER TABLE
ALTER ROUTINE    -- 更改或取消已儲存的子程式
CREATE    -- 允許使用CREATE TABLE
CREATE ROUTINE    -- 建立已儲存的子程式
CREATE TEMPORARY TABLES        -- 允許使用CREATE TEMPORARY TABLE
CREATE USER        -- 允許使用CREATE USER, DROP USER, RENAME USER和REVOKE ALL PRIVILEGES。
CREATE VIEW        -- 允許使用CREATE VIEW
DELETE    -- 允許使用DELETE
DROP    -- 允許使用DROP TABLE
EXECUTE        -- 允許使用者執行已儲存的子程式
FILE    -- 允許使用SELECT...INTO OUTFILE和LOAD DATA INFILE
INDEX     -- 允許使用CREATE INDEX和DROP INDEX
INSERT    -- 允許使用INSERT
LOCK TABLES        -- 允許對您擁有SELECT許可權的表使用LOCK TABLES
PROCESS     -- 允許使用SHOW FULL PROCESSLIST
REFERENCES    -- 未被實施
RELOAD    -- 允許使用FLUSH
REPLICATION CLIENT    -- 允許使用者詢問從屬伺服器或主伺服器的地址
REPLICATION SLAVE    -- 用於複製型從屬伺服器(從主伺服器中讀取二進位制日誌事件)
SELECT    -- 允許使用SELECT
SHOW DATABASES    -- 顯示所有資料庫
SHOW VIEW    -- 允許使用SHOW CREATE VIEW
SHUTDOWN    -- 允許使用mysqladmin shutdown
SUPER    -- 允許使用CHANGE MASTER, KILL, PURGE MASTER LOGS和SET GLOBAL語句,mysqladmin debug命令;允許您連線(一次),即使已達到max_connections。
UPDATE    -- 允許使用UPDATE
USAGE    -- “無許可權”的同義詞
GRANT OPTION    -- 允許授予許可權


/* 表維護 */

-- 分析和儲存表的關鍵字分佈
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE 表名 ...
-- 檢查一個或多個表是否有錯誤
CHECK TABLE tbl_name [, tbl_name] ... [option] ...
option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
-- 整理資料檔案的碎片
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

6、事物|檢視|觸發器|儲存過程

6.1、事務的詳細解析

簡介:深入詳解事務

什麼是事務?

	資料庫事務通常指對資料庫進行讀或寫的一個操作過程。有兩個目的,第一個是為資料庫操作提供了一個從失敗中恢復到正常狀態的方法,同時提供了資料庫即使在異常狀態下仍能保持一致性的方法;第二個是當多個應用程式在併發訪問資料庫時,可以在這些應用程式之間提供一個隔離方法,以防止彼此的操作互相干擾。
  • 事務的特性(ACID):

    • 原子性(Atomicity):事務必須是原子工作單元,一個事務中的所有語句,應該做到:要麼全做,要麼一個都不做;
    • 一致性(Consistency):讓資料保持邏輯上的“合理性”,比如:小明給小紅打10000塊錢,既要讓小明的賬戶減少10000,又要讓小紅的賬戶上增加10000塊錢;
    • 隔離性(Isolation):如果多個事務同時併發執行,但每個事務就像各自獨立執行一樣。
    • 永續性(Durability):一個事務執行成功,則對資料來說應該是一個明確的硬碟資料更改(而不僅僅是記憶體中的變化)。
  • 你要使用事務的話,表的引擎要為innodb引擎

6.2、事務實戰

簡介:主要講解事務的開啟以及事務實戰,深入瞭解什麼是事務

事務的開啟與提交:

  • 事務的開啟:
    • begin;(5.7之後)
    • start transaction;(5.7之前)
  • 事務的提交:commit;
  • 事務的回滾:rollback;
create table account (
    id tinyint(5) zerofill auto_increment  not null comment 'id編號',
    name varchar(20) default null comment '客戶姓名',
    money decimal(10,2) not null comment '賬戶金額',
    primary key (id)
)engine=innodb charset=utf8;
  • 開啟autocommit(臨時生效):
    • OFF(0):表示關閉:set autocommit=0;
    • ON (1):表示開啟:set autocommit=1;
    • 查詢autocommit是否開啟:show variables like 'autocommit';
 # 關閉事務自動提交
 mysql> set autocommit=0;
  Query OK, 0 rows affected (0.00 sec)
  
  mysql> show variables like 'autocommit';
  +---------------+-------+
  | Variable_name | Value |
  +---------------+-------+
  | autocommit    | OFF   |
  +---------------+-------+
  
  # 開啟事務自動提交
  mysql> set autocommit=1;
  Query OK, 0 rows affected (0.00 sec)
  mysql> 
  mysql> show variables like 'autocommit';
  +---------------+-------+
  | Variable_name | Value |
  +---------------+-------+
  | autocommit    | ON    |
  +---------------+-------+
  • 開啟autocommit(永久生效):
    • 修改配置檔案:vi /etc/my.cnf
    • 在[mysqld]下面加上:autocommit=1
    • 記得重啟服務才會生效

6.3、檢視的應用

簡介:詳細講解檢視的優缺點以及應用

  • 什麼是檢視?檢視的作用是什麼?

    • 檢視(view)是一種虛擬存在的表,是一個邏輯表,它本身是不包含資料的。作為一個select語句儲存在資料字典中的。
    • 通過檢視,可以展現基表(用來建立檢視的表叫做基表base table)的部分資料,說白了檢視的資料就是來自於基表
  • 檢視的優點是:

1)簡單:使用檢視的使用者完全不需要關心後面對應的表的結構、關聯條件和篩選條件,對使用者來說已經是過濾好的複合條件的結果集。
2)安全:使用檢視的使用者只能訪問他們被允許查詢的結果集,對錶的許可權管理並不能限制到某個行某個列,但是通過檢視就可以簡單的實現。
3)資料獨立:一旦檢視的結構確定了,可以遮蔽表結構變化對使用者的影響,源表增加列對檢視沒有影響;源表修改列名,則可以通過修改檢視來解決,不會造成對訪問者的影響。
4)不佔用空間:檢視是邏輯上的表,不佔用記憶體空間

總而言之,使用檢視的大部分情況是為了保障資料安全性,提高查詢效率。
  • 檢視的缺點
 1)效能差:sql server必須把檢視查詢轉化成對基本表的查詢,如果這個檢視是由一個複雜的多表查詢所定義,
   那麼,即使是檢視的一個簡單查詢,sql server也要把它變成一個複雜的結合體,需要花費一定的時間。
 
 2)修改限制:當用戶試圖修改試圖的某些資訊時,資料庫必須把它轉化為對基本表的某些資訊的修改,
   對於簡單的試圖來說,這是很方便的,但是,對於比較複雜的試圖,可能是不可修改的。
  • 檢視的建立以及修改
--建立的基本語法是:
create view <檢視名稱> as select 語句;
create view <檢視名稱> (欄位) as select 語句;
--檢視存在時,可以對檢視進行修改;檢視不存在時,可以建立檢視
create or replace view <檢視名稱>;

--修改的語法是:
alter view <檢視名稱> as select 語句;

--檢視檢視的欄位資訊
desc 檢視名;
describe 檢視名;

--檢視檢視的詳細資訊(定義語句)
show create view 檢視名;
--檢視刪除語法:
drop view <檢視名稱> ;

6.4、觸發器介紹

簡介:介紹什麼是觸發器以及如何來建立

  • 什麼是觸發器:觸發器就是監視某種情況,並觸發某種操作
-- 建立單個執行語句的觸發器
create trigger 觸發器名稱 before|after insert|update|delete
on 表名 for each row sql語句;

-- 建立有多個執行語句的觸發器,不同語句用分號隔開  
create trigger 觸發器名稱 before|after insert|update|delete
on 表名 for each row
begin
    執行語句列表
end

--before/after:可以設定為事件發生前或後
--insert/update/delete:它們可以在執行insert、update或delete的過程中觸發
--for each row:每隔一行執行一次動作


--檢視觸發器資訊
--1.檢視所有觸發器
SHOW TRIGGERS;
--檢視某個觸發器,所有觸發器的資訊都存在 information_schema 資料庫的 triggers 表中
SELECT * FROM information_schema.triggers WHERE trigger_name= '觸發器名';

--刪除觸發器
drop trigger 觸發器名稱;
  • 演示:
--建立一個員工遲到表:
 create table work_time_delay(
    empno int not null comment '僱員編號',
    ename varchar(50) comment '僱員姓名',
    status int comment '狀態'
);
-- 自定義語句的結束符號
delimiter //

mysql> delimiter //
mysql> 
mysql> create trigger trig_work after insert on work_time_delay
    -> for each row
    -> begin
    ->     update employee set sal=sal-100 where empno=new.empno;
    -> end
    -> //
Query OK, 0 rows affected (0.01 sec)

new:指的是事件發生before或者after儲存的新資料

6.5、儲存過程介紹

簡介:介紹什麼是儲存過程

  • 什麼是儲存過程:儲存過程就是把複雜的一系列操作,封裝成一個過程。類似於shell,python指令碼等。
  • 儲存過程的優缺點
優點是:
    1)複雜操作,呼叫簡單
    2)速度快
        
缺點是:
    1)封裝複雜
    2) 沒有靈活性
  • 建立儲存過程語法:
create procedure 名稱 (引數....)
    begin
        過程體;
        過程體;
    end
  • 引數:in|out|inout 引數名稱 型別(長度)

    • in:表示呼叫者向過程傳入值(傳入值可以是字面量或變數)
    • out:表示過程向呼叫者傳出值(可以返回多個值)(傳出值只能是變數)
    • inout:既表示呼叫者向過程傳入值,又表示過程向呼叫者傳出值(值只能是變數)
  • 宣告變數:declare 變數名 型別(長度) default 預設值;

  • 給變數賦值:set @變數名=值;

  • 呼叫儲存命令:call 名稱(@變數名);

  • 刪除儲存過程命令:drop procedure 名稱;

  • 檢視建立的儲存過程命令:show create procedure 名稱\G

  • 示例:

# 建立一個簡單的儲存過程:
# 自定義語句的結束符號
mysql> delimiter //
mysql> create procedure  name(in n int)
    -> begin
    -> select * from employee limit n;
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> set @n=5;
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> 
mysql> call name(@n);
mysql> create procedure  name()
    -> begin
    -> declare  n int default 6;
    -> select * from employee limit n;
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> call name();

7、儲存引擎與索引

7.1、儲存引擎介紹

簡介:主要來詳細介紹MyISAM與InnoDB引擎

  • 什麼是資料庫儲存引擎?

    • 資料庫引擎是資料庫底層軟體元件,不同的儲存引擎提供不同的儲存機制,索引技巧,鎖定水平等功能,使用不同的資料庫引擎,可以獲得特定的功能
  • 如何檢視引擎

--如何檢視資料庫支援的引擎
show engines;

--檢視當前資料的引擎:
show create table 表名\G

--檢視當前庫所有表的引擎:
show table status\G
  • 建表時指定引擎
create table yingqin (
    id int,
    name varchar(20)
) engine='InnoDB';--(or MyISAM)
  • 修改表的引擎
alter table 表名 engine='MyiSAm';
  • 修改預設引擎
# 修改預設引擎,記得儲存後重啟服務
vi /etc/my.cnf
[mysqld] #增加下面配置
default-storage-engine=MyIsAM

7.2、常用索引介紹

簡介:講解什麼是索引,索引的優缺點,以及常見索引有哪些

  • 什麼是索引?

索引是一個單獨的,儲存在磁碟中上的資料庫結構,它們包含著對資料表裡的所有記錄的引用指標。使用索引可以快速的找出在某列或多列中有特定值的行。

  • 索引的優點:
通過建立唯一索引,來保證資料庫表中的每一行資料的唯一性。
可以加快資料的檢索速度。
可以保證表資料的完整性與準確性
  • 索引的缺點:
索引需要佔用物理空間。
對錶中的資料進行改動時,索引也需要跟著動態維護,降低了資料的維護速度。
  • 索引的常見型別:
index:		--普通索引
unique:		--唯一索引
primary key:--主鍵索引
foreign key:--外來鍵索引
fulltext:	 --全文索引
			 --組合索引
  • 建立表的sql語句:
create table test (
    id int(7) zerofill auto_increment not null,
    username varchar(20),
    servnumber varchar(30),
    password varchar(20),
    createtime datetime,
    primary key (id)
)DEFAULT CHARSET=utf8;
  • 生成百萬甚至千萬級別表的sql 語句 shell指令碼:
#!/bin/bash

echo "請輸入欄位servnumber的值:"
read serber
echo "請輸入建立sql語句的數量:"
read number

# char=`head /dev/urandom | tr -dc 0-9 | head -c 11`

for (( i=0;i<$number;i++ ))
        do
        pass=`head /dev/urandom | tr -dc a-z | head -c 8`
        let serber=serber+1
        echo "insert into test(id,username,servnumber,password,createtime) values('$i','user${i}','${serber}','$pass',now());" >>sql.txt

done
  • vi test.sh
  • 執行shell指令碼:sh test.sh
  • 進行插數操作:source /home/dazhu/sql.txt

7.3、普通索引與唯一索引

資料:https://blog.csdn.net/qq_41573234/article/details/80250279

簡介:介紹普通索引(index)與唯一索引(unique

普通索引(index):顧名思義就是各類索引中最為普通的索引,主要任務就是提高查詢速度。
                其特點是允許出現相同的索引內容,允許空(null)值
唯一索引:(unique)顧名思義就是不可以出現相同的索引內容,但是可以為空(null)值
  • 如何建立普通索引或者唯一索引?
    • 建立表的時候建立
-- 普通索引index
create table test (
    id int(7) zerofill auto_increment not null,
    username varchar(20),
    servnumber varchar(30),
    password varchar(20),
    createtime datetime,
    index (id)
)DEFAULT CHARSET=utf8;

-- 唯一索引unique
create table test (
    id int(7) zerofill auto_increment not null,
    username varchar(20),
    servnumber varchar(30),
    password varchar(20),
    createtime datetime,
    unique index (id)
    -- unique index unique_id(id)  //unique_id為索引名稱
)DEFAULT CHARSET=utf8;
  • 直接為表新增索引
--注意:假如沒有指定索引名稱時,會以預設的欄位名為索引名稱
alter table 表名 add index 索引名稱 (欄位名稱);
alter table test add unique unique_username (username);
  • 直接建立索引
create index 索引 on 表名 (欄位名);
create index index_createtime on test (createtime);

-- CREATE <索引名> ON <表名> (<列名> [<長度>] [ ASC | DESC])
-- 索引名:指定索引名。一個表可以建立多個索引,但每個索引在該表中的名稱是唯一的。
-- 表名:指定要建立索引的表名。
-- 列名:指定要建立索引的列名。通常可以考慮將查詢語句中在 JOIN 子句和 WHERE 子句裡經常出現的列作為索引列。
-- 長度:可選引數,其指索引的長度,必須是字串型別才可以使用。
-- ASC|DESC:可選項。ASC指定索引按照升序來排列,DESC指定索引按照降序來排列,預設為ASC
  • 檢視索引
show index from 表名\G
show index from test\G
  • 如何刪除索引
drop index 索引名稱 on 表名;
drop index unique_username on test;

alter table 表名 drop index 索引名;
alter table test drop index createtime;

7.4、主鍵索引

簡介:詳細講解主鍵索引

  • 什麼是主鍵索引?(PRIMARY KEY
把主鍵新增索引就是主鍵索引,它是一種特殊的唯一索引,不允許有空值,而唯一索引(unique是允許為空值的)。
指定為“PRIMARY KEY”

主鍵:主鍵是表的某一列,這一列的值是用來標誌表中的每一行資料的。
注意:每一張表只能擁有一個主鍵
  • 建立主鍵:
1)建立表的時候建立
create table test (
    id int(7) primary key auto_increment,-- 建立索引方式一
    username varchar(20),
    password varchar(20)
    -- PRIMARY KEY (`rcd_id`) 建立索引方式二
)DEFAULT CHARSET=utf8;

2)直接為表新增主鍵索引
alter table 表名 add primary key (欄位名);
alter table test add primary key (id);
  • 刪除主鍵:
alter table 表名 drop primary key; 
alter table test drop primary key;
--注意:在有自增的情況下,必須先刪除自增,才可以刪除主鍵

--刪除自增:
alter table test change id id int(7) unsigned zerofill not null;

7.5、全文索引

簡介:介紹什麼是全文索引以及使用

  • 什麼是全文索引?(fulltex
全文索引是將儲存在資料庫中的文章或者句子等任意內容資訊查找出來的索引,單位是詞。
全文索引也是目前搜尋引擎使用的一種關鍵技術。指定為 fulltex
  • 建立練習表的sql,並插入資料:
-- 建表
create table command (
    id int(5) unsigned primary key auto_increment,
    name varchar(10),
    instruction varchar(60)
)engine=MyISAM;

-- 資料插入
insert into command values('1','ls','list directory contents');
insert into command values('2','wc','print newline, word, and byte counts for each file');
insert into command values('3','cut','remove sections from each line of files');
insert into command values('4','sort','sort lines of text files');
insert into command values('5','find','search for files in a directory hierarchy');
insert into command values('6','cp','複製檔案或者資料夾');
insert into command values('7','top','display Linux processes');
insert into command values('8','mv','修改檔名,移動');
insert into command values('9','停止詞','is,not,me,yes,no ...');
  • 新增全文索引:
-- 建立表的時候建立全文索引,索引名稱為command_instruction
create table command (
    id int(5) unsigned primary key auto_increment,
    name varchar(10),
    instruction varchar(60),
    fulltext key command_instruction(instruction)
)engine=MyISAM;

-- 直接為表新增全文索引
alter table command add fulltext(instruction);
  • 使用全文索引:
select * from 表名 where match  (欄位名) against ('檢索內容');
select * from command where match(instruction) against ('sections');
  • 檢視匹配度:
select * from command where match(instruction) against ('directory');
  • 停止詞:出現頻率很高的詞,將會使全文索引失效
  • in boolean mode 模式:
in boolean mode:意思是指定全文檢索模式為布林全文檢索(簡單可以理解為是檢索方式)
select * from 表名 where match (欄位名) against ('檢索內容' in boolean mode);
  • 注意點:使用萬用字元*時,只能放在詞的後邊,不能放前邊。
  • 刪除全文索引:
alter table command drop index instruction;
  • 注意點總結:
    • 1、一般情況下建立全文索引的欄位資料型別為 char、varchar、text 。其它欄位型別不可以​
    • 2、全文索引不針對非常頻繁的詞做索引。比如is,no,not,you,me,yes這些,我們稱之為停止詞​
    • 3、對英文檢索時忽略大小寫

7.6、外來鍵約束剖析

簡介:解析什麼是外來鍵約束,以及有什麼作用

  • 什麼是外來鍵?(foreign key
外來鍵就是作用於兩個表資料之間的連結的一列或多列,用來保證表與表之間的資料的完整性和準確性。
  • 新增外來鍵約束:
語法:foreign key (欄位名) references 關聯的表名(關聯表的欄位名)
注意:主鍵跟外來鍵的欄位型別一定要相同

-- 1、create table的方法:
CREATE TABLE `employee` (
    `empno` int(11) NOT NULL COMMENT '僱員編號',
    `ename` varchar(50) DEFAULT NULL COMMENT '僱員姓名',
    `job` varchar(30) DEFAULT NULL,
    `mgr` int(11) DEFAULT NULL COMMENT '僱員上級編號',
    `hiredate` date DEFAULT NULL COMMENT '僱傭日期',
    `sal` decimal(7,2) DEFAULT NULL COMMENT '薪資',
    `deptnu` int(11) DEFAULT NULL COMMENT '部門編號',
    PRIMARY KEY (`empno`),
    foreign key (`deptnu`) references dept(deptnu)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 -- 2、alter table的方法:
 alter table employee add foreign key (deptnu) references dept(deptnu);
  • 刪除外來鍵約束:(注意:在幹掉外來鍵索引之前必須先把外來鍵約束刪除,才能刪除索引)
mysql> alter table employee drop index deptnu;
ERROR 1553 (HY000): Cannot drop index 'deptnu': needed in a foreign key constraint
mysql> 
mysql> alter table employee drop foreign key employee_ibfk_1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> 
mysql> alter table employee drop index deptnu;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
  • 注意點總結:
    • 倆個表,主鍵跟外來鍵的欄位型別一定要相同​
    • 要使用外來鍵約束表的引擎一定得是InnoDB引擎,MyISAM是不起作用的​
    • 在幹掉外來鍵索引之前必須先把外來鍵約束刪除,才能刪除索引

7.7、聯合索引

簡介:詳細介紹聯合索引

  • 什麼是聯合索引:聯合索引又稱組合索引或者複合索引,是建立在倆列或者多列以上的索引。

  • 建立和刪除聯合索引

-- 建表時建立索引
create table test (
    id int(7) primary key auto_increment not null,
    username varchar(20),
    servnumber varchar(30),
    password varchar(20),
    createtime datetime,
    index (username,servnumber,password)
)DEFAULT CHARSET=utf8;

-- 增加表聯合索引
alter table 表名 add index(欄位1,欄位2,欄位3);
alter table test add index(username,servnumber,password);

-- 刪除聯合索引
alter table test drop index username;
  • 為什麼要使用聯合索引,而不使用多個單列索引?:聯合索引的效率遠遠高於單列索引

  • 聯合索引的最左原則:只有查詢條件中使用了這些欄位中第一個欄位(即username),索引才會被使用。

  • 注意點總結:

    • 索引並非越多越好,過多的索引會增加資料的維護速度還有磁碟空間的浪費。​
    • 當表的資料量很大的時候,可以考慮建立索引。​
    • 表中經常查資料的欄位,可以考慮建立索引。​
    • 想要保證表中資料的唯一性,可以考慮建立唯一索引。​
    • 想要保證倆張表中的資料的完整性跟準確性,可以考慮建立外來鍵約束。​
    • 經常對多列資料進行查詢時,可以考慮建立聯合索引。

8、SQL語句優化

8.1、慢查詢日誌開啟與問題定位

簡介:介紹如何開啟慢查詢日誌與問題定位

  • 第一步:檢視是否已經開啟了慢查詢日誌
mysql> show variables like 'slow%';
+---------------------+--------------------------------------+
| Variable_name       | Value                                |
+---------------------+--------------------------------------+
| slow_launch_time    | 2                                    |
| slow_query_log      | OFF                                  |
| slow_query_log_file | /data/mydata/xdclass-public-slow.log |
+---------------------+--------------------------------------+
  • 第二步:開啟慢查詢日誌
set global slow_query_log = on;

--日誌路徑也可以自定義:
set global slow_query_log_file = '路徑';
  • 第三步:檢視慢查詢的時間臨界值(查詢慢的日誌才會存入日誌)
mysql> show variables like '%long%';
mysql> 
+----------------------------------------------------------+-----------+
| Variable_name                                            | Value     |
+----------------------------------------------------------+-----------+
| long_query_time                                          | 10.000000 |
| performance_schema_events_stages_history_long_size       | 10000     |
| performance_schema_events_statements_history_long_size   | 10000     |
| performance_schema_events_transactions_history_long_size | 10000     |
| performance_schema_events_waits_history_long_size        | 10000     |
+----------------------------------------------------------+-----------+
  • 第四步:設定慢查詢的時間標準(臨界值)
set long_query_time=0.4;
  • 注意:重啟mysql服務會讓在互動介面設定的慢查詢恢復到預設
  • 永久生效的設定方法:
修改配置檔案 vi /etc/my.cnf
[mysqld]
slow_query_log = 1
long_query_time = 0.1
slow_query_log_file =/usr/local/mysql/mysql_slow.log

最後必須重啟服務才能生效!

8.2、SQL語句執行過程解析

簡介:介紹如何開啟效能詳情

  • 第一步:檢視效能詳情是否開啟
mysql> show variables like '%profiling%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| have_profiling         | YES   |
| profiling              | OFF   |
| profiling_history_size | 15    |
+------------------------+-------+
  • 第二步:開啟效能記錄功能
set profiling = on ;
  • 第三步:檢視效能的記錄
mysql> show profiles;
+----------+------------+---------------------------------------------------+
| Query_ID | Duration   | Query                                             |
+----------+------------+---------------------------------------------------+
|        1 | 0.00177775 | show variables like '%profiling%'                 |
|        2 | 0.00037900 | select * from test where id='087878'              |
|        3 | 0.34618025 | select * from test where servnumber='1367008787'  |
|        4 | 0.31986825 | select * from test where servnumber='13670087879' |
+----------+------------+---------------------------------------------------+
  • 第四步:檢視語句的執行效能詳情
mysql> show profile for query 4;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000100 |
| checking permissions | 0.000010 |
| Opening tables       | 0.000023 |
| init                 | 0.000045 |
| System lock          | 0.000015 |
| optimizing           | 0.000016 |
| statistics           | 0.000028 |
| preparing            | 0.000020 |
| executing            | 0.000006 |
| Sending data         | 0.319489 |
| end                  | 0.000037 |
| query end            | 0.000012 |
| closing tables       | 0.000012 |
| freeing items        | 0.000040 |
| cleaning up          | 0.000017 |
+----------------------+----------+

效能執行緒的詳細解釋官方文件連結:https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html

8.3、SQL語句優化建議(面試)

簡介:介紹日常工作應該儘量避免的sql語句

  • 第一個注意點:儘量避免使用select * from ,儘量精確到想要的結果欄位
  • 第二個注意點:儘量避免條件使用or
  • 第三個注意點:記得加上limit 限制行數,避免資料量過大消耗效能
  • 第四個注意點:使用模糊查詢時,%放在前面是會使索引失效
mysql> explain select * from test where servnumber like '%1367000%'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 996303
     filtered: 11.11
        Extra: Using where

9、資料安全與備份

9.1、備份的背景意義

簡介:資料庫備份的意義

  • 資料備份的意義

    • 保護資料的安全;
    • 在出現意外的時候(硬碟的損壞,斷電,黑客的攻擊),以便資料的恢復;
    • 匯出生產的資料以便研發人員或者測試人員測試學習;
    • 高許可權的人員操作失誤導致資料丟失,以便恢復;
  • 資料庫的備份型別:

    • 完全備份:對整個資料庫的資料進行備份
    • 部分備份:對部分資料進行備份(可以是一張表也可以是多張表)
    • 增量備份:是以上一次備份為基礎來備份變更資料的,節約空間
    • 差異備份:是以第一次完全備份的基礎來備份變更備份的,浪費空間
  • 資料庫備份的方式:

    • 邏輯備份:直接生成sql語句儲存起來,在恢復資料的時候執行備份的sql語句來實現資料的恢復
    • 物理備份:直接拷貝相關的物理資料
  • 區別:

    • 邏輯備份效率低,恢復資料效率低,但是邏輯備份節約空間;
    • 物理備份浪費空間,但是相對邏輯備份而言效率比較高
  • 資料庫備份的場景:

    • 熱備份:備份時,資料庫的讀寫操作不會受到影響
    • 溫備份:備份時,資料庫的讀操作可以進行,但是寫操作不能執行
    • 冷備份:備份時,不能進行任何操作

9.2、備份與恢復(mysqldump)

簡介:如何利用mysql自帶命令mysqldump來備份單庫或者多庫

  • mysqldump使用語法:
mysqldump -u使用者名稱 -p密碼 dbname table > 路徑/xxx.sql
mysqldump -u使用者名稱 -p密碼 --databases dbname1 dbname2 > xxx.sql

-- 常見選項:
-u: 使用者名稱
-p: 密碼
-P: 埠號,不寫預設3306
--host,-h:伺服器IP地址,不寫預設本地localhost
--all-databases, -A:備份所有資料庫
--databases, -B: 用於備份多個數據庫。如果沒有該選項,mysqldump把第一個名字引數作為資料庫名,後面的作為表名。使用該選項,mysqldum把每個名字都當作為資料庫名。
--no-data, -d:不匯出任何資料,只匯出資料庫表結構。
--no-create-info, -t:只匯出資料庫的資料,而不新增CREATE TABLE 語句
--no-create-db, -n:只匯出資料庫的資料,而不新增CREATE DATABASE 語句

--quick, -q:快速匯出
--xml, -X:匯出為xml檔案
  • 本地備份示例:
# 1. 備份全部資料庫的資料和結構(-A)
mysqldump -uroot -p123456 -A > 0101.sql

# 2. 備份全部資料庫的結構(-d)
mysqldump -uroot -p123456 -A -d > 0102.sql

# 3. 備份全部資料庫的資料(-t)(-n)
mysqldump -uroot -p123456 -A -t > 0103.sql
mysqldump -uroot -p123456 -A -n > 0113.sql

# 4. 備份單個數據庫的資料和結構(dnname 為資料庫名)
mysqldump -uroot -p123456 dnname > 0104.sql

# 5. 備份單個數據庫結構(dbname 為資料庫名,-d)
mysqldump -uroot -p123456 dbname -d > 0105.sql

# 6. 備份單個數據庫資料(sakila 為資料庫名,-t)
mysqldump -uroot -p123456 sakila -t > 0106.sql

# 7. 備份多個表的結構和資料 (table1,table2為表名)
mysqldump -uroot -p123456 dbname table1 table2 > 0107.sql

# 8. 一次備份多個數據庫
mysqldump -uroot -p123456 --databases db1 db2 > 0108.sql
  • 本機恢復資料:
# 資料恢復方式一:
# Linux系統命令列:1.先建庫  2.匯入資料
mysqladmin -uroot -p123456 create db_name 
mysql -uroot -p123456  db_name < d:\bak\0101.sql

注:在匯入備份資料庫前,db_name如果沒有,是需要建立的; 
    而且與backup20110527.sql中資料庫名是一樣的才可以匯入。

# 資料恢復方式二:將匯出的本地檔案匯入到指定資料庫
# 2. soure 方法: 
mysql > use db
mysql > source d:\bak\0101.sql
  • 遠端備份示例:
# 1.遠端備份單庫:
mysqldump -uroot -p123456 -h120.25.93.69 zabbix | gzip > /mysql_data_back/zabbix_users.sql.gz

# 2.遠端備份單庫並保留建立庫語句:
mysqldump -uroot -p123456 -h120.25.93.69 --databases zabbix | gzip > /mysql_data_back/zabbix_bak.sql.gz

# 3.遠端備份單庫單表:
mysqldump -uroot -p123456 -h120.25.93.69 zabbix users | gzip > /mysql_data_back/zabbix_users.sql.gz

# 4.遠端備份多庫:
mysqldump -uroot -p123456 -h120.25.93.69 --databases zabbix XD | gzip > /mysql_data_back/zabbix_XD.sql.gz

# 5.遠端備份整庫:
mysqldump -uroot -p123456 -h120.25.93.69 --all-databases | gzip > /mysql_data_back/all.sql.gz
  • 遠端恢復資料
# 遠端恢復資料(備份的資料檔案裡有建立庫的語句):
mysql -uroot -p123456 -h120.25.93.69 < zabbix_bak.sql

# 遠端恢復資料(備份的資料檔案裡沒有建立庫的語句):
mysql -uroot -p123456 -h120.25.93.69 zabbix < zabbix_bak.sql
  • 注意:
      1. 還原單個數據庫、單個數據庫多個表需要指定資料庫,而還原多個數據庫時不用指定資料庫。
      1. 區別:備份用的命令是mysqldump, 還原用的是mysql。

9.3、物理備份與恢復

簡介:詳解資料庫原始檔以及如何物理備份

  • 查詢資料庫原始檔路徑(2種方式):
# 方式一:mysql內查詢
mysql> show variables like 'datadir%';
+---------------+---------------+
| Variable_name | Value         |
+---------------+---------------+
| datadir       | /data/mydata/ |
+---------------+---------------+

# 方式二:配置檔案查詢
cat /etc/my.cnf
  • MyISAM表原始檔:
└── data
    └── dbname
        ├── db.opt     -- 建立庫的時候生成,主要儲存著當前庫的預設字符集和字元校驗規則
        └── table_name
            ├── .frm  --記錄著表結構資訊的檔案
            ├── .MYI  --記錄著索引的檔案
            └── .MYD  --記錄著表的資料
            
            
db.opt:建立庫的時候生成,主要儲存著當前庫的預設字符集和字元校驗規則
.frm :記錄著表結構資訊的檔案
.MYI:記錄著索引的檔案
.MYD:記錄著表的資料
  • InnoDB表原始檔:InnoDB有著共享表空間跟獨立表空間的概念。
└── data
    ├── ibdata1        -- 共享表空間,裡邊記錄表的資料和索引
    └── dbname
        ├── db.opt     -- 建立庫的時候生成,主要儲存著當前庫的預設字符集和字元校驗規則
        └── table_name
            ├── .frm  --記錄著表結構資訊的檔案
            └── .ibd  --獨立表空間,裡邊記錄這個表的資料和索引
 

db.opt:建立庫的時候生成,主要儲存著當前庫的預設字符集和字元校驗規則
.frm :記錄著表結構資訊的檔案
.ibd :獨立表空間,裡邊記錄這個表的資料和索引
ibdata1:共享表空間,裡邊記錄表的資料和索引
  • 備份單庫時分兩種情況:


1.包含InnoDB表的庫:
1.1.直接拷貝/data下的資料庫名目錄
2.2.拷貝/data 目錄下三個檔案
    -ib_logfile0:事務日誌
    -ib_logfile1:事務日誌
    -ibdata1   :共享表空間

2.包含MyISAM表的庫
2.1.直接拷貝/data下的資料庫目錄即可
  • 備份資料庫的時候遇到資料庫正在寫入資料報錯:
# 備份dbname資料庫時該資料庫正在寫入資料會顯示報錯
tar -czvf dbname.tar.gz dbname/
# 如果有資料寫入時會報錯,所以我們開源開啟讀鎖

# 請求全域性讀鎖
flush tables with read lock;
# 解鎖
unlock tables;

9.4、二進位制日誌備份(mysqlbinlog)

簡介:講解如何利用二進位制日誌來備份資料

  • 什麼是二進位制日誌:二進位制日誌就是記錄著mysql資料庫中的一些寫入性操作,比如一些增刪改,但是,不包括查詢!
  • 二進位制日誌有哪些功能:一般情況下,二進位制日誌有著資料複製和資料恢復的功能
  • 注意:開啟二進位制日誌會有1%的效能消耗!
  • 檢視二進位制日誌是否開啟:
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |
+---------------+-------+
  • 開啟二進位制日誌 :(記得重啟服務)
# 修改my.cnf配置檔案
vi /etc/my.cnf

# 加入log-bin配置
[mysqld]
# 開啟二進位制日誌log-bin
log-bin=/data/mydata/log_bin/mysql-bin
server-id=1
  • 檢視所有的binlog日誌列表:
mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |     23638 |
+------------------+-----------+
  • 重新整理二進位制日誌:
# 重置(清空)二進位制日誌檔案
mysql> flush logs;

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |     23638 |
| mysql-bin.000002 |      1091 |
+------------------+-----------+
  • 使用mysqldump備份資料時,加上-F選項可以重新生成一個新的二進位制日誌檔案
mysqldump -uroot -p test user -F  > test_bak.sql

9.5、二進位制日誌恢復(mysqlbinlog)

簡介:講解如何利用二進位制日誌來恢復資料

  • 檢視二進位制日誌檔案的內容報錯:
$ mysqlbinlog mysql-bin.000002
mysqlbinlog: [ERROR] unknown variable 'default-character-set=utf8'
  • 解決
# 第一種:在mysqlbinlog 後邊加上 --no-defaults 
$ mysqlbinlog --no-defaults ​ mysql-bin.000002
# 第二種:註釋掉配置檔案裡邊的:default-character-set=utf8
  • 把二進位制日誌檔案匯出成普通檔案:
# 第一種:在mysqlbinlog 後邊加上 --no-defaults 
$ mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -v mysql-bin.000002 > mysqlbin.sql

# 第二種:先註釋掉配置檔案裡邊的:default-character-set=utf8,在執行下命令
$ mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000002 > mysqlbin.sql
  • 找出要恢復的位置:
# 1.找出關鍵字的行數:
$ mysqlbinlog --no-defaults mysql-bin.000002 | cat -n  | grep -iw 'drop'
  4180  DROP TABLE `user` /* generated by server */

# 2.打印出相關內容:
$ mysqlbinlog --no-defaults mysql-bin.000002 | cat -n | sed -n '4170,4180p'​
  4170  # at 59578
  4171  #190419  0:41:48 server id 1  end_log_pos 59609 CRC32 0x36cda2b7        Xid = 6380
  4172  COMMIT/*!*/;
  4173  # at 59609
  4174  #190419  0:41:48 server id 1  end_log_pos 59674 CRC32 0x8de2f06a        Anonymous_GTID  last_committed=145      sequence_number=146
  4175  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
  4176  # at 59674
  4177  #190419  0:41:48 server id 1  end_log_pos 59787 CRC32 0x6b2edd2b        Query   thread_id=14    exec_time=0     error_code=0
  4178  use `XD`/*!*/;
  4179  SET TIMESTAMP=1555605708/*!*/;
  4180  DROP TABLE `user` /* generated by server */

恢復資料:

  • 第一步:把備份的資料表user恢復到資料庫中:mysql -uroot -p test < /mysql_data_back/user_bak.sql
  • 第二步:利用上面找到的刪除的位置進行恢復資料
$ mysqlbinlog --no-defaults --set-charset=utf8  --stop-position="59674" /data/mydata/log_bin/mysql-bin.000002 | mysql -uroot -p