MySQL數據庫進階

1、視圖(不重要)

視圖是一個虛擬表(非真實存在),其本質是【根據SQL語句獲取動態的數據集,併爲其命名】,用戶使用時只需使用【名稱】便可獲取結果集,並能夠將其看成表來使用html

1.1 爲何須要視圖

  • 簡化查詢
  • 能夠進行權限控制,咱們能夠把表的權限進行封閉,可是開放相應的視圖權限,視圖裏只開放部分數據

1.2 建立視圖

--格式:CREATE VIEW 視圖名稱 AS  SQL語句
CREATE VIEW v1 AS 
SELET nid, name from A where nid > 4

1.3 使用視圖

使用視圖時,將其看成表進行操做便可,視圖和真實的表都會相互影響mysql

select * from v1

1.4 刪除視圖

--格式:DROP VIEW 視圖名稱
DROP VIEW v1

1.5 修改視圖

-- 格式:ALTER VIEW 視圖名稱 AS SQL語句
ALTER VIEW v1 AS
SELET A.nid, B. NAME FROM A
LEFT JOIN B ON A.id = B.nid
LEFT JOIN C ON A.id = C.nid
WHERE
    A.id > 2
AND C.nid < 5

2、函數(不重要)

2.1 常見內置函數

CHAR_LENGTH(str)
        返回值爲字符串str 的長度,長度的單位爲字符。一個多字節字符算做一個單字符。
        對於一個包含五個二字節字符集, LENGTH()返回值爲 10, 而CHAR_LENGTH()的返回值爲5。
    CONCAT(str1,str2,...)
        字符串拼接
        若有任何一個參數爲NULL ,則返回值爲 NULL。
    FORMAT(X,D)
        將數字X 的格式寫爲'#,###,###.##',以四捨五入的方式保留小數點後 D 位, 並將結果以字符串的形式返回。若  D 爲 0, 則返回結果不帶有小數點,或不含小數部分。
        例如:
            SELECT FORMAT(12332.1,4); 結果爲: '12,332.1000'
    INSTR(str,substr)
        返回字符串 str 中子字符串的第一個出現位置。
    LEFT(str,len)
        返回字符串str 從開始的len位置的子序列字符。
    LOWER(str)
        變小寫
    UPPER(str)
        變大寫
    LTRIM(str)
        返回字符串 str ,其引導空格字符被刪除。
    RTRIM(str)
        返回字符串 str ,結尾空格字符被刪去。
    SUBSTRING(str,pos,len)
        獲取字符串子序列
    LOCATE(substr,str,pos)
        獲取子序列索引位置
    REPEAT(str,count)
        返回一個由重複的字符串str 組成的字符串,字符串str的數目等於count 。
        若 count <= 0,則返回一個空字符串。
        若str 或 count 爲 NULL,則返回 NULL 。
    REPLACE(str,from_str,to_str)
        返回字符串str 以及全部被字符串to_str替代的字符串from_str 。
    REVERSE(str)
        返回字符串 str ,順序和字符順序相反。
    RIGHT(str,len)
        從字符串str 開始,返回從後邊開始len個字符組成的子序列

2.2 自定義函數

delimiter \\
create function f1(
    i1 int,
    i2 int)
returns int
BEGIN
    declare num int;
    set num = i1 + i2;
    return(num);
END \\
delimiter ;

2.3 刪除函數

drop function func_name;

2.4 執行函數

# 獲取返回值
declare @i VARCHAR(32);
select UPPER('alex') into @i;
SELECT @i;
# 在查詢中使用
select f1(11,nid) ,name from tb2;

3、觸發器(不重要)

3.1 觸發器的定義

進行數據庫應用軟件的開發時,咱們有時會碰到表中的某些數據改變,但願同時引發其餘相關數據改變的需求
利用觸發器就能知足這樣的需求,它能在表中的某些特定數據變化時自動完成相關的操做算法

3.2 觸發器的應用場合

  • 當向一張表中添加或刪除記錄時,須要在相關表中進行同步操做

    好比,當一個訂單產生時,訂單所購的商品的庫存量相應減小sql

  • 當表上某列數據的值與其餘表中的數據有聯繫時

    好比,當某客戶進行欠款消費,能夠在生成訂單時經過設計觸發器判斷該         客戶的累計欠款是否超出了最大限度數據庫

  • 當須要對某張表進行跟蹤時

     好比,當有新訂單產生時,須要及時通知相關人員進行處理,此時能夠在         訂單表上設計添加觸發器加以實現服務器

3.3. 觸發器的建立語法

# 插入前
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
    ...
END
# 插入後
CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
BEGIN
    ...
END
# 刪除前
CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
BEGIN
    ...
END
# 刪除後
CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
BEGIN
    ...
END
# 更新前
CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
BEGIN
    ...
END
# 更新後
CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
BEGIN
    ...
END

3.4 觸發器案例

delimiter //
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
    INSERT INTO tb2 (NAME)
VALUES
    ('aa')
END//
delimiter ;

注意:NEW表示即將插入的數據行,OLD表示即將刪除的數據行

 3.5 刪除觸發器

DROP TRIGGER tri_after_insert_tb1;

3.6 使用觸發器

觸發器沒法由用戶直接調用,而知因爲對錶的【增/刪/改】操做被動引起的數據結構

insert into tb1(num) values(666)

4、事務

通俗的說,事務指一組操做,要麼都執行成功,要麼都執行失敗

4.1 事務的ACID特性

  • 原子性(Atomicity),原子意爲最小的粒子,即不能再分的事務,要麼所有執行,要麼所有取消(就像上面的銀行例子)
  • 一致性(Consistency):指事務發生前和發生後,數據的總額依然匹配
  • 隔離性(Isolation):簡單點說,某個事務的操做對其餘事務不可見的
  • 持久性(Durability):當事務完成後,其影響應該保留下來,不能撤消,只能經過「補償性事務」來抵消以前的錯誤

4.2 事務的用法

開啓事務(start transaction)
執行sql操做(普通sql操做)
提交/回滾(commit/rollback)
create table user(
id int auto_increment primary key,
name varchar(32) not null default '',
money int not null default 1000
)engine=innodb charset=utf8;

 insert into user (name,money) values ('wangyong',1000),('liguo',1000);

# 正常操做
 start transaction;
update user set money=1100 where name='wangyong';
updata user set money=900 where name='liguo';
# 出現異常
 rollback;

# 最終結果, 數據未發生變化
mysql> select * from user;
+----+----------+-------+
| id | name     | money |
+----+----------+-------+
|  1 | wangyong |  1000 |
|  2 | liguo    |  1000 |
+----+----------+-------+

 

注意:建表的時候, 選擇 innodb 引擎

4.3 事務常見的執行流程

購物流程中的訂單付款操做含有如下3步子操做:函數

  • 從用戶的餘額中扣除訂單價格
  • 在用戶的帳戶變更記錄裏記下流水
  • 修改訂單狀態爲已付款

這三步需保證原子性,請用事務來控制此過程性能

 5、索引

索引是表的目錄,在查找內容以前能夠先在目錄中查找索引位置,以此快速定位查詢數據。對於索引,會保存在額外的文件中。大數據

5.1 索引的時間複雜度

設有N條記錄,若是不用索引,那平均查找N/2次,可是用了索引以後呢?

通常狀況下,是以2爲底,N的對數

這塊就涉及到二叉樹的查找了

5.2 索引的好處與壞處

  • 好處:加快了查詢的速度
  • 壞處:下降了增刪改的速度,增大了表的文件大小(索引文件甚至比數據文件都還要大)

問題:大數據量進行導入別的數據表的時候,怎麼辦??

5.3 索引的概念

相似於字典中的目錄,如何快速找到某個字?

能夠給字典加目錄

對數據庫來講,索引的做用便是給 「數據」 加目錄

因此所謂的索引,是數據庫中專門用於幫助用戶快速查詢數據的一種數據結構

5.4 常見的索引類型

  • 主鍵索引:加速查詢 + 列值惟一 + 表中只有一個(不能夠有null)
  • 普通索引:僅加速查詢
  • 惟一索引:加速查詢 + 列值惟一(能夠有null)
  • 組合索引:多列值組成一個索引,

5.4.1 主鍵索引(primary key)

1. 建立表 + 索引

# 第一種:
    create table test(
        id int auto_increment primary key,
        name varchar(32) not null default ''
    )engine=innodb charset=utf8;

# 第二種:
    create table test(
        id int not null default 0,
        name varchar(32) not null default ''
    )engine=innodb charset=utf8;
    
    alter table test change id id int auto_increment primary key

5.4.2 普通索引(index)

普通索引僅有一個功能:加速查詢

1. 建立表 + 索引

# 第一種
    create table test(
        id int auto_increment primary key,
        name varchar(32) not null default '',
        index ix_name (name)
    )engine=innodb charset=utf8;

# 第二種
     create table test(
        id int auto_increment primary key,
        name varchar(32) not null default ''
    )engine=innodb charset=utf8;
    
    create index ix_name on test (name);

2. 建立索引

create index index_name on table_name(column_name)

3. 刪除索引

drop index_name on table_name;

4. 查看索引

show index from table_name; 

 5.4.3 惟一索引(unique)

惟一索引有兩個功能:加速查詢 和 惟一約束(可含null)

1. 建立表 + 索引

# 第一種
    create table test(
        id int auto_increment primary key,
        name varchar(32) not null default '',
        unique ix_name (name)
    )engine=innodb charset=utf8;

# 第二種  create unique index 索引名稱 on 表名(name);
    create table test(
        id int auto_increment primary key,
        name varchar(32) not null default ''
    )engine=innodb charset=utf8;
    
    create unique index ix_name on test (name);

2. 建立索引

create unique index 索引名 on 表名(列名)

3. 刪除索引

drop unique index 索引名 on 表名

5.4.4 聯合索引 (unique index)

組合索引是將n個列組合成一個索引

其應用場景爲:頻繁的同時使用n列來進行查詢,如:where n1 = ‘alex’ and n2 = 666

1. 建立表 + 索引

# 建立聯合惟一索引  create unique index 索引名稱 on 表名 (name,age);
    create table test(
        id int auto_increment primary key,
        age int not null default 0, 
        name varchar(32) not null default ''
    )engine=innodb charset=utf8;
    
    create unique index ix_name_age on test (age, name);

create table in3(
    nid int not null auto_increment primary key,
    name varchar(32) not null,
    email varchar(64) not null,
    extra text
)

2. 建立索引

create index ix_name_email on in3(name,email);

如上建立組合索引以後,查詢:

  • name and email – 使用索引
  • name – 使用索引
  • email – 不使用索引

注意:對於同時搜索n個條件時,組合索引的性能好於多個單一索引合併

5.5 使用規則

數據庫表中添加索引後確實會讓查詢速度起飛,但前提必須是正確的使用索引來查詢,若是以錯誤的方式使用,則即便創建索引也會不奏效。
即便創建索引,索引也不會生效:

- like '%xx'
    select * from tb1 where name like '%cn';
- 使用函數
    select * from tb1 where reverse(name) = 'xxx';
- 類型不一致
    若是列是字符串類型,傳入條件是必須用引號引發來,否則...
    select * from tb1 where name = 999;
- order by
    select email from tb1 order by name desc;
    當根據索引排序時候,選擇的映射若是不是索引,則不走索引
    特別的:若是對主鍵排序,則仍是走索引:
        select * from tb1 order by nid desc;
 
- 組合索引最左前綴
    若是組合索引爲:(name,email)
    name and email       -- 使用索引
    name                 -- 使用索引
    email                -- 不使用索引

其餘注意事項

- 避免使用select *
- count(1)或count(列) 代替 count(*)
- 建立表時儘可能時 char 代替 varchar
- 表的字段順序固定長度的字段優先
- 組合索引代替多個單列索引(常用多個條件查詢時)
- 使用鏈接(JOIN)來代替子查詢(Sub-Queries)
- 索引散列值(重複少)不適合建索引,例:性別不適合

5.6 查看是否使用索引:explain

使用方式:explain selext * from test;

explain selext * from test;

+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------
|  1 | SIMPLE      | test  | index | NULL          | ix_name | 98      | NULL |    1 | Using index 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------

參數分析:

id
        查詢順序標識
    select_type
        查詢類型
            SIMPLE          簡單查詢
            PRIMARY         最外層查詢
            SUBQUERY        映射爲子查詢
            DERIVED         子查詢
            UNION           聯合
            UNION RESULT    使用聯合的結果
            ...
    table
        正在訪問的表名
    type
        查詢時的訪問方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
            ALL             全表掃描,對於數據表從頭至尾找一遍
                            select * from tb1;
                            特別的:若是有limit限制,則找到以後就不在繼續向下掃描
                                   select * from tb1 where email = 'xxxx@live.com'
                                   select * from tb1 where email = 'xxxx@live.com' limit 1;
                                   雖然上述兩個語句都會進行全表掃描,第二句使用了limit,則找到一個後就再也不繼續掃描。
            INDEX           全索引掃描,對索引從頭至尾找一遍
                            select nid from tb1;
            RANGE          對索引列進行範圍查找
                            select *  from tb1 where name < 'xxx';
                            PS:
                                between and
                                in
                                >   >=  <   <=  操做
                                注意:!= 和 > 符號
            REF             根據索引查找一個或多個值
                            select *  from tb1 where name = 'xxx';
            CONST           常量
                            表最多有一個匹配行,由於僅有一行,在這行的列值可被優化器剩餘部分認爲是常數,const表很快,由於它們只讀取一次。
                            select nid from tb1 where nid = 2 ;
            SYSTEM          系統
                            表僅有一行(=系統表)。這是const聯接類型的一個特例。
    possible_keys
        可能使用的索引
    key
        真實使用的
    key_len
        MySQL中使用索引字節長度
    rows
        mysql估計爲了找到所需的行而要讀取的行數 ------ 只是預估值
    extra
        該列包含MySQL解決查詢的詳細信息
        「Using index」
            此值表示mysql將使用索引覆蓋,以免訪問表。不要把覆蓋索引和index訪問類型弄混了。
        「Using where」
            這意味着mysql服務器將在存儲引擎檢索行後再進行過濾,許多where條件裏涉及索引中的列,當(而且若是)它讀取索引時,就能被存儲引擎檢驗,所以不是全部帶where子句的查詢都會顯示「Using where」。有時「Using where」的出現就是一個暗示:查詢可受益於不一樣的索引。
        「Using temporary」
            這意味着mysql在對查詢結果排序時會使用一個臨時表。
        「Using filesort」
            這意味着mysql會對結果使用一個外部索引排序,而不是按索引次序從表裏讀取行。mysql有兩種文件排序算法,這兩種排序方式均可以在內存或者磁盤上完成,explain不會告訴你mysql將使用哪種文件排序,也不會告訴你排序會在內存裏仍是磁盤上完成。

刪除索引後效果

# drop 索引名稱 on 表名
drop index ix_name_age on test;

mysql> explain select * from test;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | test  | ALL  | NULL          | NULL | NULL    | NULL |    1 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+

5.7 慢日誌

日誌文件: 記錄了執行速度特別慢的SQL語句

配置MySQL自動記錄慢日誌

slow_query_log = OFF                            是否開啓慢日誌記錄
long_query_time = 2                              時間限制,超過此時間,則記錄
slow_query_log_file = /usr/slow.log        日誌文件

5.7.1 開啓方式

1. show variables like '%query%';
2. set global long_query_time = 1; 設置慢查詢的時間
3. set global  slow_query_log = ON
4. set global slow_query_log_file = E:\program\mysql-5.6.44-winx64\data\oldboy-slow.log

5.7.2 普通日誌記錄(general log)

SQL審計 (記錄sql的操做語句)
show variables like '%general%';

5.8 索引原理

https://www.cnblogs.com/wangyong123/articles/11621128.html

相關文章
相關標籤/搜索