mysql學習總結

1.1 mysql的簡介介紹
1、什麼是mysql?
mysql是一個開源的關係型數據庫管理系統,現在是oracle公司旗下的一款產品,由C和C++語言編寫,可移植性高。支持在多種操作系統上安裝,最常見有AIX,linux,window。mysql因爲開源免費,所以受到了目前互聯網行業的歡迎。

以mysql作爲數據庫,linux系統作爲操作系統,apache或者nginx作爲web服務器,perl/php/python作爲服務端的腳本解釋器,就可以搭建起一個免費的網站。被業界稱爲LNMP或者LAMP

2.1 mysql各個版本的重要性介紹

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

2.2 mysql的服務管理

  • 查看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
    

2.3 mysql的可視化圖形界面與命令行操作

  • 命令行模式:
    
    	登錄命令:mysql -u用戶 -p密碼
    
     	退出命令:exit;	quit;
    
  • 圖形化模式:
     	ip地址或者主機名:120.76.62.13
    

2.4 mysql的庫表深入解析

  • 什麼是庫?
    顧名思義就是數據倉庫的意思,存儲着一定數據結構的數據,一個數據庫中可能包含着若干個表,我們可以
    通過數據庫提供的多種方法來管理數據庫裏邊的數據。本質上mysql數據庫是一個關係型數據服務管理系統
  • 什麼是表?
    我們所說的表就是數據表,每一張表是由行和列組成,每記錄一條數據,數據表就增加一行。列是由字段名
    與字段數據屬性組成,我們稱之列爲字段,每一個字段有着多個屬性。例如是否允許爲空、長度、類型等等
    數據庫:database
    數據表:table
    字段(列):column
    行:row

2.5 mysql的操作語句

  • 操作語句分爲四類:
  1. DDL 數據定義語言 (Data Definition Language) 例如:建庫,建表
  2. DML 數據操縱語言(Data Manipulation Language) 例如:對錶中的數據進行增刪改操作
  3. DQL 數據查詢語言(Data Query Language)例如:對數據進行查詢
  4. DCL 數據控制語言(Data Control Language)例如:對用戶的權限進行設置

3.1 如何創建、查看以及使用/切換mysql數據庫

  • 直接創建數據庫 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%’;

3.2 mysql中常用數據類型

  • 數據類型是什麼?
    數據類型是指列、存儲過程參數、表達式和局部變量的數據特徵,它決定了數據的存儲格式,代表了不同的信息類型。有一些數據是要存儲爲數字的,數字當中有些是要存儲爲整數、小數、日期型等…

  • mysql常見數據類型
    <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 字節 () (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代表小數位個數
     
     <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     存儲日期+時間,可作時間戳
    

eg:

  • 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());
    

3.3 如何創建表及其約束條件

  • 語法:
    CREATE TABLE 表名 (
    字段名1 字段類型1 約束條件1 說明1,
    字段名2 字段類型2 約束條件2 說明2,
    字段名3 字段類型3 約束條件3 說明3
    );
    create table 新表名 as select * from 舊錶名 where 1=2;(注意:建議這種創建表的方式用於日常測試,因 爲可能索引什麼的會複製不過來)
    create table 新表名 like 舊錶名;

  • 約束條件:

    comment ----說明解釋
    not null ----不爲空
    default ----默認值
    unsigned ----無符號(即正數)
    auto_increment ----自增
    zerofill ----自動填充
    unique key ----唯一值

eg:

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

3.4 mysq數據常用屬性的查看

  • 查看數據庫中的所有表:show tables;
  • 查看錶結構:desc 表名;
  • 查看創建表的sql語句:show create table 表名;

3.5 mysql表結構維護與刪除

  • 修改表名

    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 表名 modify 列名 新類型;
    alter table user modify servnumber varchar(20);

  • 修改列名

    alter table 表名 change 舊列名 新列名 類型;
    alter table user change servnumber telephone varchar(20);

  • 刪除列

    alter table 表名 drop 列名;
    alter table user drop famliy;

  • 修改字符集

    alter table 表名 character set 字符集;
    alter table user character set GBK;

  • mysql表的刪除

    drop table 表名;
    drop table user;

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

4.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 表名 (字段名) values (對應值1),(對應值2),(對應值3);

  • 創建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 ‘部門編號’
    );

4.2 表數據的修改以及刪除

  • 修改(更新):
    update 表名 set 字段名1=值1 where 字段名=值;

    update 表名 set 字段名1=值1,字段名2=值2 where 字段名=值;
    
  • 刪除:
    delete from 表名 where 字段名=值;

     truncate table 表名;
     delete from 表名;
     drop table 表名;
    
  • 注意事項:
    面試時:面試官問在刪改數據之前,你會怎麼做?
    答案:會對數據進行備份操作,以防萬一,可以進行數據回退

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

4.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字符集文件的保存路徑

  • 臨時:set names 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;

5.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);

5.1 查詢子句之一 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;
    

5.2 查詢子句之二group by分組查詢(分組)

簡介:詳解group by的用法以及應用場景
  • 作用:把行 按 字段 分組

  • 語法:group by 列1,列2…列N

  • 適用場合:常用於統計場合,一般和聚合函數連用

    eg:
    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;

5.3 查詢子句之三having條件查詢(篩選)

簡介:詳解having的用法以及應用場景
  • 作用:對查詢的結果進行篩選操作
    
  • 語法:having 條件 或者 having 聚合函數 條件
    
  • 適用場合:一般跟在group by之後
    

    eg:
    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;

5.4 查詢子句之四order by排序查詢(排序)

簡介:詳解order by的用法以及應用場景
  • 作用:對查詢的結果進行排序操作

  • 語法:order by 字段1,字段2 …

  • 適用場合:一般用在查詢結果的排序

    eg:
    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 
    

5.5 查詢子句之五limit限制查詢(限制)

簡介:詳解limit的用法以及應用場景
  • 作用:對查詢結果起到限制條數的作用

  • 語法:limit n,m n:代表起始條數值,不寫默認爲0;m代表:取出的條數

  • 適用場合:數據量過多時,可以起到限制作用

    eg:
    select * from XD.employee limit 4,5;

5.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 條件);

    eg:查詢出公司有員工的部門的詳細信息
    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);

5.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。

    eg:列出部門名稱和這些部門的員工信息,同時列出那些沒有的員工的部門
    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;

5.8 mysql查詢之內連接查詢與聯合查詢

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

  • 內連接:獲取兩個表中字段匹配關係的記錄

  • 主要語法:INNER JOIN 表名 ON 條件;

    eg:想查出員工張飛的所在部門的地址
    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(加上最大條數就行),需要對子句用括號括起來
    
    eg:對銷售員的工資從低到高排序,而文員的工資從高到低排序
        (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);
    

5.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;
    

5.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
      語句:elect 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;
    

6.DCL數據控制語言(對用戶權限的設置)

  • 什麼是DCL數據控制語言?
    數據控制語言(DCL:Data Control Language)是用來設置或者更改數據庫用戶或角色權限的語句,這些語句包括GRANT、DENY、REVOKE等語句

6.1 限制root用戶指定ip登錄

  • 查看root用戶可以在哪臺機器登錄

    select user,host from mysql.user where user=‘root’;

  • 修改mysql庫裏邊的user表

    update mysql.user set host=‘localhost’ where user=‘root’;

  • 刷新權限

    flush privileges;

6.2 忘記密碼以及如何修改用戶密碼

  • 修改用戶密碼分三種方法:
  1. 第一種:set password for 用戶@ip = password('密碼');
      set password for root@localhost = password('root');
    
  2. 第二種:mysqladmin -u用戶 -p舊密碼 password 新密碼;
    mysqladmin -urootmysqladmin -uroot -proot password;
    
  3. 第三種: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='localhost';
    
  • 忘記密碼:
  1. 第一步:修改配置文件my.cnf (默認在/etc/my.cnf),在[mysqld]下面加上 skip-grant-tables (跳過權限的意思)
    
  2. 第二步:重啓mysql服務
    
  3. 第三步:mysql -uroot -p 無需密碼登錄進入
    
  4. 第四步:修改密碼
    

6.3 如何創建新用戶並限制ip網段登錄

  • 創建用戶的語法:create user ‘username’@‘host’ identified by ‘password’;

    username:你將創建的用戶名

    host:指定該用戶在哪個主機上可以登陸,如果是本地用戶可用localhost,如果想讓該用戶可以從任意遠程主機 登陸,可以使用通配符%

    password:該用戶的登陸密碼,密碼可以爲空,如果爲空則該用戶可以不需要密碼登陸服務器

  • 創建用戶語法:

    創建一個pig用戶,並指定登錄密碼:123456,可以在任何一臺遠程主機都可以登錄

    create user ‘pig’@’%’ identified by ‘123456’;

    創建一個pig用戶,並指定登錄密碼:爲空,指定在120網段的機器登錄

    create user ‘pig’@‘120.%.%.%’ identified by ‘’;

  • 查看權限:

     select * from mysql.user where user='pig'\G
      mysql> show grants for 'pig'@'%';
      +---------------------------------+
      | Grants for pig@%                |
      +---------------------------------+
      | GRANT USAGE ON *.* TO 'pig'@'%' |
      +---------------------------------+
      USAGE:無權限的意思
      mysql> show grants for 'root'@'localhost';
      +---------------------------------------------------------------------+
      | Grants for root@localhost                                           |
      +---------------------------------------------------------------------+
      | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
      +---------------------------------------------------------------------+
      WITH GRANT OPTION:表示這個用戶擁有grant權限,即可以對其他用戶授權
    
  • 刪除用戶語法:drop user ‘username’@‘host’;

     drop user 'pig'@'%';
     delete from mysql.user where user='pig';
    

6.4 如何實現庫表權限授權與回收

  • 授權語法:grant 權限1,權限2… on 數據庫對象 to ‘用戶’

    grant 權限1,權限2… on 數據庫對象 to ‘用戶’@‘host’ identified by ‘password’;

  • all privileges:代表所有權限

  • . :代表所有庫所有表

    對現有用戶進行授權:對現有用戶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’;

  • 回收語法: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;

7.事務實戰,視圖,觸發器,以及存儲過程

7.1事務的詳細解析

  • 什麼是事務?

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

  • 事務的特性(ACID):

  • 原子性(Atomicity):事務必須是原子工作單元,一個事務中的所有語句,應該做到:要麼全做,要麼一個都不做;

  • 一致性(Consistency):讓數據保持邏輯上的“合理性”,比如:小明給小紅打10000塊錢,既要讓小明的賬戶減少10000,又要讓小紅的賬戶上增加10000塊錢;

  • 隔離性(Isolation):如果多個事務同時併發執行,但每個事務就像各自獨立執行一樣。

  • 持久性(Durability):一個事務執行成功,則對數據來說應該是一個明確的硬盤數據更改(而不僅僅是內存中的變化)。

  • 你要使用事務的話,表的引擎要爲innodb引擎

7.2 事務操作實例

  • 事務的開啓與提交:

  • 事務的開啓:begin; start transaction;

  • 事務的提交: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):表示關閉
    ON (1):表示開啓
    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
    記得重啓服務纔會生效

7.3 視圖的應用

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

    視圖(view)是一種虛擬存在的表,是一個邏輯表,它本身是不包含數據的。作爲一個select語句保存在數據字典中的。
    通過視圖,可以展現基表(用來創建視圖的表叫做基表base table)的部分數據,說白了視圖的數據就是來自於基表

  • 視圖的優點是:

    1)簡單:使用視圖的用戶完全不需要關心後面對應的表的結構、關聯條件和篩選條件,對用戶來說已經是過濾好的複合條件的結果集。

    2)安全:使用視圖的用戶只能訪問他們被允許查詢的結果集,對錶的權限管理並不能限制到某個行某個列,但是通過視圖就可以簡單的實現。

    3)數據獨立:一旦視圖的結構確定了,可以屏蔽表結構變化對用戶的影響,源表增加列對視圖沒有影響;源表修改列名,則可以通過修改視圖來解決,不會造成對訪問者的影響。
      
    4)不佔用空間:視圖是邏輯上的表,不佔用內存空間

    總而言之,使用視圖的大部分情況是爲了保障數據安全性,提高查詢效率。

  • 視圖的創建以及修改

    創建的基本語法是:
    create view <視圖名稱> as select 語句;
    create view <視圖名稱> (字段) as select 語句;
    create or replace view <視圖名稱>;

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

    視圖刪除語法:
    drop view <視圖名稱> ;

  • 視圖的缺點

    1)性能差:sql server必須把視圖查詢轉化成對基本表的查詢,如果這個視圖是由一個複雜的多表查詢所定義,那麼,即使是視圖的一個簡單查詢,sql server也要把它變成一個複雜的結合體,需要花費一定的時間。

    2)修改限制:當用戶試圖修改試圖的某些信息時,數據庫必須把它轉化爲對基本表的某些信息的修改,對於簡單的試圖來說,這是很方便的,但是,對於比較複雜的試圖,可能是不可修改的。

7.4 觸發器介紹

  • 什麼是觸發器?

    觸發器就是監視某種情況,並觸發某種操作

  • 創建觸發器的語法:

    create trigger 觸發器名稱 after/before insert/update/delete on 表名
    for each row
    begin
    sql語句;
    end

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

  • 刪除觸發器的語法:
    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保存的新數據

7.5 mysql的存儲過程介紹

  • 什麼是存儲過程?

    存儲過程就是把複雜的一系列操作,封裝成一個過程。類似於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();
    

8.索引與存儲引擎的介紹
8.1 存儲引擎介紹
(1)什麼是數據庫存儲引擎?

數據庫引擎是數據庫底層軟件組件,不同的存儲引擎提供不同的存儲機制,索引技巧,鎖定水平等功能,使用不同的數據庫引擎,可以獲得特定的功能

(2)如何查看引擎?

如何查看數據庫支持的引擎
show engines;

查看當前數據的引擎:
show create table 表名\G

查看當前庫所有表的引擎:
show table status\G

(3)建表時指定引擎

create table yingqin (id int,name varchar(20)) engine='InnoDB';

(4)修改表的引擎

alter table 表名 engine='MyiSAm';

修改默認引擎
    vi /etc/my.cnf
    [mysqld]下面
    default-storage-engine=MyIsAM
    記得保存後重啓服務

(5)MyISAM與InnoDB的區別

MyISAM:支持全文索引(full text);不支持事務;表級鎖;保存表的具體行數;奔潰恢復不好

Innodb:支持事務;以前的版本是不支持全文索引,但在5.6之後的版本就開始支持這個功能了;行級鎖(並非絕對,當執行sql語句時不能確定範圍時,也會進行鎖全表例如: update table set id=3 where name like 'a%';);不保存表的具體行數;奔潰恢復好

(6)總結:什麼時候選擇什麼引擎比較好

MyISAM:
    一般來說MyISAM不需要用到事務的時候
    做很多count計算

InnoDB:
    可靠性要求高的,或者要求支持事務
 	 想要用到外鍵約束的時候(講外鍵的時候會講)

推薦:
    推薦用InnoDB

8.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++))dopass=head/dev/urandomtrdcazheadc8letserber=serber+1echo&quot;insertintotest(id,username,servnumber,password,createtime)values(number;i++ )) do pass=`head /dev/urandom | tr -dc a-z | head -c 8` let serber=serber+1 echo &quot;insert into test(id,username,servnumber,password,createtime) values(&#x27;i’,‘useri,{i}&#x27;,&#x27;{serber}’,’$pass’,now());" >>sql.txt

      done
    

vi test.sh

執行shell腳本:sh test.sh

進行插數操作:source /home/dazhu/sql.txt

8.3 普通索引與唯一索引

  • 什麼是普通索引?

    普通索引(index)顧名思義就是各類索引中最爲普通的索引,主要任務就是提高查詢速度。其特點是允許出現相同的索引內容,允許空(null)值

  • 什麼是唯一索引?

    唯一索引:(unique)顧名思義就是不可以出現相同的索引內容,但是可以爲空(null)值

  • 如何創建普通索引或者唯一索引?

    • 創建表的時候創建
      create table test (
      id int(7) zerofill auto_increment not null,
      username varchar(20),
      servnumber varchar(30),
      password varchar(20),
      createtime datetime,
      unique (id)
      )DEFAULT CHARSET=utf8;

    • 直接爲表添加索引
      語法:
      alter table 表名 add index 索引名稱 (字段名稱);
      eg:
      alter table test add unique unique_username (username);

      注意:假如沒有指定索引名稱時,會以默認的字段名爲索引名稱
      
    • 直接創建索引
      語法:create index 索引 on 表名 (字段名);
      eg:create index index_createtime on test (createtime);

  • 查看索引
    語法:show index from 表名\G
    eg: show index from test\G

  • 如何刪除索引

    語法:drop index 索引名稱 on 表名;
    eg:drop index unique_username on test;

    語法:alter table 表名 drop index 索引名;
    eg:alter table test drop index createtime;

8.4 主鍵索引

  • 什麼是主鍵索引?

    把主鍵添加索引就是主鍵索引,它是一種特殊的唯一索引,不允許有空值,而唯一索引(unique是允許爲空值的)。指定爲“PRIMARY KEY”

    主鍵:主鍵是表的某一列,這一列的值是用來標誌表中的每一行數據的。
    注意:每一張表只能擁有一個主鍵

  • 創建主鍵:
    1)創建表的時候創建

    2)直接爲表添加主鍵索引
       語法:alter table 表名 add primary key (字段名);
       eg:alter table test add primary key (id);
    
  • 刪除主鍵:

    語法:
    alter table 表名 drop primary key;
    eg:
    alter table test drop primary key;

    注意:在有自增的情況下,必須先刪除自增,纔可以刪除主鍵

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

8.5全文索引的使用

  • 什麼是全文索引?
    全文索引是將存儲在數據庫中的文章或者句子等任意內容信息查找出來的索引,單位是詞。全文索引也是目前搜索引擎使用的一種關鍵技術。指定爲 fulltex

  • 創建練習表的sql:
    create table command (
    id int(5) unsigned primary key auto_increment,
    name varchar(10),
    instruction varchar(60)
    )engine=MyISAM;

  • 插入數據sql:
    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 …’);

  • 添加全文索引:

    • 創建表的時候創建全文索引
    • 通過alter添加
      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、對英文檢索時忽略大小寫
    

8.6 外鍵約束剖析

  • 什麼是外鍵?

    外鍵就是作用於兩個表數據之間的鏈接的一列或多列,用來保證表與表之間的數據的完整性和準確性。

  • 添加外鍵約束:

    語法:foreign key (字段名) references 關聯的表名(關聯表的字段名)

    注意:主鍵跟外鍵的字段類型一定要相

    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;

    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

  • 注意點總結:

    (1)倆個表,主鍵跟外鍵的字段類型一定要相同

    (2)要使用外鍵約束表的引擎一定得是InnoDB引擎,MyISAM是不起作用的

    (3)在幹掉外鍵索引之前必須先把外鍵約束刪除,才能刪除索引

8.7 聯合索引

  • 什麼是聯合索引?

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

  • 怎麼來創建聯合索引?

    alter table 表名 add index(字段1,字段2,字段3);

    alter table test add index(username,servnumber,password);

  • 怎麼刪除聯合索引?

    alter table test drop index username;

  • 爲什麼要使用聯合索引,而不使用多個單列索引?

    聯合索引的效率遠遠高於單列索引

  • 聯合索引的最左原則

  • 注意點總結:

    索引並非越多越好,過多的索引會增加數據的維護速度還有磁盤空間的浪費。

    當表的數據量很大的時候,可以考慮建立索引。

    表中經常查數據的字段,可以考慮建立索引。

    想要保證表中數據的唯一性,可以考慮建立唯一索引。

    想要保證倆張表中的數據的完整性跟準確性,可以考慮建立外鍵約束。

    經常對多列數據進行查詢時,可以考慮建立聯合索引。

9.sql語句優化思路

9.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 = ‘路徑’;

  • 第三步:查看慢查詢的時間臨界值

    show variables like ‘%long%’;

  • 第四步:設置慢查詢的時間標準

    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

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

9.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

9.3 mysql語句優化的幾個小建議

  • 第一個注意點:

    儘量避免使用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

  • 第五個注意點:

    要小心條件字段類型的轉換

10.備份技能

10.1 爲什麼要進行數據備份

  • 數據備份的意義:
    (1)保護數據的安全;

    (2)在出現意外的時候(硬盤的損壞,斷電,黑客的攻擊),以便數據的恢復;
    
    (3)導出生產的數據以便研發人員或者測試人員測試學習;
    
    (4)高權限的人員操作失誤導致數據丟失,以便恢復;
    

10.2 備份的介紹

  • 數據庫的備份類型:
    (1)完全備份:對整個數據庫的數據進行備份

    (2)部分備份:對部分數據進行備份(可以是一張表也可以是多張表)
    
    	  增量備份:是以上一次備份爲基礎來備份變更數據的,節約空間
    
    	  差異備份:是以第一次完全備份的基礎來備份變更備份的,浪費空間
    
  • 數據庫備份的方式:
    (1)邏輯備份:直接生成sql語句保存起來,在恢復數據的時候執行備份的sql語句來實現數據的恢復

    (2)物理備份:直接拷貝相關的物理數據
    
    區別:邏輯備份效率低,恢復數據效率低,但是邏輯備份節約空間;物理備份浪費空間,但是相對邏輯備份而言效率比較高
    
  • 數據庫備份的場景:
    (1)熱備份:備份時,數據庫的讀寫操作不會受到影響

    (2)溫備份:備份時,數據庫的讀操作可以進行,但是寫操作不能執行
    
    (3)冷備份:備份時,不能進行任何操作
    

10.3 mysqldump備份實例(跨機器)
簡介:如何利用mysql自帶命令mysqldump來備份單庫或者多庫

  • mysqldump使用語法:
    mysqldump -u 用戶 -h host -p 密碼 dbname table > 路徑

  • 遠程備份單庫例子:
    mysqldump -uroot -pabc123456 -h120.25.93.69 zabbix | gzip > /mysql_data_back/zabbix_users.sql.gz

  • 遠程備份單庫例子並保留創建庫語句:
    mysqldump -uroot -pabc123456 -h120.25.93.69 --databases zabbix | gzip > /mysql_data_back/zabbix_bak.sql.gz

  • 遠程備份單庫單表的例子:
    mysqldump -uroot -pabc123456 -h120.25.93.69 zabbix users | gzip > /mysql_data_back/zabbix_users.sql.gz

  • 遠程備份多庫的例子:
    mysqldump -uroot -pabc123456 -h120.25.93.69 --databases zabbix XD | gzip > /mysql_data_back/zabbix_XD.sql.gz

  • 遠程備份全庫的例子:
    mysqldump -uroot -pabc123456 -h120.25.93.69 --all-databases | gzip > /mysql_data_back/all.sql.gz

10.4 mysql數據的恢復

  • 遠程恢復數據(備份的數據文件裏有創建庫的語句):
    mysql -uroot -pabc123456 -h120.25.93.69 < zabbix_bak.sql

  • 遠程恢復數據(備份的數據文件裏沒有創建庫的語句):
    mysql -uroot -pabc123456 -h120.25.93.69 zabbix < zabbix_bak.sql

10.5 物理備份

  • 看找數據庫源文件路徑(一):
    mysql> show variables like ‘datadir%’;
    ±--------------±--------------+
    | Variable_name | Value |
    ±--------------±--------------+
    | datadir | /data/mydata/ |
    ±--------------±--------------+

  • 看找數據庫源文件路徑(二):
    cat /etc/my.cnf

  • MyISAM表源文件:
    db.opt:創建庫的時候生成,主要存儲着當前庫的默認字符集和字符校驗規則

    .frm :記錄着表結構信息的文件
    
    .MYI:記錄着索引的文件
    
    .MYD :記錄着表的數據
    
  • InnoDB表源文件:InnoDB有着共享表空間跟獨立表空間的概念。
    db.opt:創建庫的時候生成,主要存儲着當前庫的默認字符集和字符校驗規則

    .frm :記錄着表結構信息的文件
    
    .ibd :獨立表空間,裏邊記錄這個表的數據和索引
    
    ibdata1:共享表空間,裏邊記錄表的數據和索引
    
  • 請求全局讀鎖:
    flush tables with read lock;

  • 解鎖:
    unlock tables;

10.6 利用二進制日誌mysqlbinlog備份數據

  • 什麼是二進制日誌:
    二進制日誌就是記錄着mysql數據庫中的一些寫入性操作,比如一些增刪改,但是,不包括查詢!

  • 二進制日誌有哪些功能:
    一般情況下,二進制日誌有着數據複製和數據恢復的功能

  • 注意:
    開啓二進制日誌會有1%的性能消耗!

  • 查看二進制日誌是否開啓:
    mysql> show variables like ‘log_bin%’;
    ±--------------------------------±------+
    | Variable_name | Value |
    ±--------------------------------±------+
    | log_bin | OFF |

  • 開啓二進制日誌 : vi /etc/my.cnf
    [mysqld]
    log-bin=/data/mydata/log_bin/mysql-bin
    server-id=1

  • 查看所有的binlog日誌列表:
    mysql> show master logs;
    ±-----------------±----------+
    | Log_name | File_size |
    ±-----------------±----------+
    | mysql-bin.000001 | 23638 |
    ±-----------------±----------+

  • 刷新二進制日誌:
    flush logs;

  • 重置(清空)二進制日誌文件:
    mysql> show master logs;
    ±-----------------±----------+
    | Log_name | File_size |
    ±-----------------±----------+
    | mysql-bin.000001 | 1091 |
    ±-----------------±----------+

  • 使用mysqldump備份數據時,加上-F選項可以重新生成一個新的二進制日誌文件
    mysqldump -uroot -p XD user -F > user_bak.sql

10.7 利用二進制日誌mysqlbinlog恢復數據

  • 查看二進制日誌文件的內容報錯:
    [root@xdclass-public log_bin]# mysqlbinlog mysql-bin.000002
    mysqlbinlog: [ERROR] unknown variable ‘default-character-set=utf8’

    • 解決:
      第一種:在mysqlbinlog 後邊加上 --no-defaults

      第二種:註釋掉配置文件裏邊的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’

    [root@xdclass-public log_bin]# 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'
    
    [root@xdclass-public log_bin]# 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 */
    [root@xdclass-public log_bin]# 
    
  • 恢復數據:

    • 第一步:把備份的數據表user恢復到數據庫中:mysql -uroot -p XD < /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
  • 登錄數據庫查看數據是否恢復回來

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章