1. 程式人生 > >MySQL 事務、檢視、索引

MySQL 事務、檢視、索引

一、檢視

1.1 為什麼使用檢視?

   安全——不希望使用者看到整個資料庫的結構,所以對不同許可權的使用者使用不同的檢視隱藏必要資料;

 方便——讓使用者更容易獲得、理解資料;

1.2 什麼是檢視?

 檢視是一種檢視資料庫中一個或多個表中資料的方法,是儲存在資料庫中的select查詢。

 檢視是一種虛擬表,它的行和列來自查詢中引用的表,在執行時,它直接顯示來自表中的資料。

1.3 檢視常用來進行下面三種操作

  • 篩選表中的行;
  • 防止未經許可的使用者訪問敏感資料;
  • 將多個物理資料表,抽象為一個邏輯資料表。

1.4 建立、檢視檢視

    1)建立檢視格式:
         create view view_Name as <select子句>;

    2)刪除檢視   (如果資料庫中已經存在同名檢視,先刪除)
         drop view if exists view_student;
    3)檢視檢視 
         select * from view_student;

   4)舉例:

--建立檢視
create view v_goods as select g.*,c.name as cates_name,b.name as brand_name from goods as g left join goods_cates as c on g.cates_id = c.id left join goods_brand as b on g.brand_id = b.id;

--檢視檢視
 select * from v_goods;

-- 刪除檢視
drop view v_goods;

1.5 使用檢視的注意事項

  • 每個檢視中可以使用多個表
  • 與查詢相似,一個檢視可以巢狀另一個檢視,但最好不要超過三層;
  • 對檢視資料進行新增、更新和刪除操作直接影響表中的資料;
  • 當資料來自多個表時,不允許新增和刪除資料。

1.6、檢視的作用

    1)提高了重用性,就像一個函式

    2)對資料庫重構,卻不影響資料庫的執行

    3)提高了安全效能,可以對不同的使用者

    4)讓資料更加清晰

 

二、事務(Transaction)

2.1 什麼是事務?

SQL中,事務是指將一系列資料操作捆綁成為一個整體進行統一管理。

如果一個事務執行成功,該事務中進行的所有資料均會提交,稱為資料庫中的永久組成部分;

如果事務執行時遇到錯誤切必須取消or回滾,則資料將全部恢復到操作前的狀態,所有更改會被清除。

在資料庫系統上執行併發操作時,事務是作為最小的控制單元來使用的,特別適用於多使用者同時操作的資料庫系統。

2.2 事務的ACID屬性

原子性(Atomicity):一個事物必須被視為一個不可分割的最小單位,這個事物中的所有操作要麼全部提交成功,要麼全部回滾失敗,對於一個事物來說,不可能只執行其中的一部分操作,這就是事物的原子性。

事務中的所有元素必須作為一個整體提交或回滾。

一致性(Consistency):資料庫總是從一個一致性的狀態轉換到另一個一致性的狀態。(在前面的例子中)

一致性確保了,及時在執行第三四語句之間系統崩潰,支票賬戶中也不會損失200元,因為事物最終沒有提交,所以事物中所做的修改也不會被儲存到資料庫中。

事務完成時,資料必須處於一致狀態。在事務進行中,可能會不一致。如轉賬操作中的金額總量。

隔離性(isolation):通常來說,一個事物所做的修改在最終提交以前,對其他事物是不可見得(在前面的例子中,當執行完第三條語句,最後一條語句還沒有執行完成,此時另外一個賬戶彙總程式開始執行,則其賬戶的餘額並沒有被剪掉200塊)

對資料進行修改的所有併發事務是彼此隔離的,即事務是獨立的。

永續性(durability):一旦事物提交,則其所做的修改會永久儲存到資料庫中。(此時,及時系統崩潰,修改的資料也不會丟失)

指不管系統是否發生了故障,事務處理的結果都是永久的。就是說一旦事務被提交,事務的效果會被永久地保留在資料庫中。

2.3 如何執行事務

MySQL的預設儲存引擎InnoDB支援事務,InnoDB主要通過UNDO和REDO日誌實現

UNDO日誌:複製事務執行前的資料,用於在事務發生異常時回滾資料;

REDO日誌:記錄在事務執行中,每條對資料進行更新的操作,當事務提交時,內容會一起被重新整理到磁碟。

2.4  事務的執行過程

MySQL的預設設定下,每句SQL語句就是一個事務,即執行SQL語句後自動提交。

(1)開始時,開啟事務 or 關閉預設的自動提交:

  begin; 
  /*或者*/
  start transaction;

這兩個語句顯示地標記一個事務的起始點.

(2)提交事務

  commit;

這個語句標誌一個事務會成功提交,資料儲存到資料庫的資料檔案中,並釋放連線時佔用的資源。

(3)回滾事務

    rollback;

取消自事務起始點到該語句的所有資料更新操作,將資料狀態回滾到事務開始前,並釋放事務控制的資源。

/*銀行轉賬例項*/
use mybank;
set names gbk;
begin;
update bank set currentMoney=currentMoney-500 where customerName='張三';
/*如果在這裡發現張三的賬戶中餘額不足500,就需要rollback*/
update bank set currentMoney=currentMoney+500 where customerName='李四';
commit;

2.5 MySQL中事務的隔離級別

MySQL中事務的預設隔離級別是repeatable-read(可重讀)級別,意味著會話B中如果未關閉自動提交,在會話A中執行事務未結束時(沒有commit或者rollback),會話B只能讀取到未提交的資料。

2.6 通過關閉自動提交執行事務

/*關閉自動提交*/
use mybank;
set names gbk;
set autocommit=0;
/*一個事務開始,假設操作沒有問題*/
update bank set currentMoney=currentMoney-500
     where customerName='張三';
update bank set currentMoney=currentMoney+500
     where customerName='李四';
commit;
/*一個事務已經結束,這是下一個事務的起點*/

/*假設新的事務中,出現了問題,張三餘額不足啦!*/
update bank set currentMoney=currentMoney-500
     where customerName='張三';
rollback;

set autocommit=1;

 

2.7 編寫事務的原則

  • 事務儘可能簡短,較大的事務佔用的資源很多;
  • 事務中訪問的資料量儘量少,這樣事務之間對資源的爭奪就少;
  • 查詢資料不要使用事務;
  • 事務處理的過程中儘量不要出現等待使用者輸入的操作。

三、索引——大大提高資料庫的檢索速度

3.1 什麼是索引

 索引提供指標以指向儲存在表中指定列的資料值,再根據指定的排序次序排列這些指標。

 資料庫使用指標的方式與使用書的目錄很相似,通過搜尋索引找到特定的值,再跟隨指標到達包含該值的行。

 索引是建立在資料庫表物件上的,由表中的一個欄位 or 多個欄位生成的鍵組成。

   這些鍵儲存在資料結構(B-樹或雜湊表)中,因此根據索引的儲存型別,B樹索引和雜湊索引。

 InnoDB和MyISAM儲存引擎支援B-樹索引。

3.2 索引分類

(1)普通索引

  允許在定義索引的列中插入重複值和空值,唯一任務是加快對資料的訪問速度。

  因此,應該只為那些最常出現在查詢條件或排序條件中的資料列建立索引。

(2)唯一索引

  唯一索引不允許兩行具有相同的索引值。

  若資料中存在重複的鍵值,一般情況下,所屬資料庫是不允許建立唯一索引;

  若已經建立了唯一索引,當新資料使得表中的鍵值重複時,資料庫也拒絕接受此資料。

  建立了唯一索引的列允許有空值。

(3)主鍵索引

  在資料庫關係圖中為表定義一個主鍵將自動建立主鍵索引,主鍵索引是唯一索引的特殊型別。

  主鍵索引要求主鍵中的每個值是非空、唯一的,當在查詢中使用主鍵索引時,它還允許快速訪問資料。

(4)複合索引

  建立索引時,可以將多個列組合作為索引。

  需要注意的是,只有在查詢中使用了組合索引最左邊的欄位時,索引才會被使用。

(5)全文索引

 全文索引的作用是在定義索引的列上支援值的全文查詢,允許在這些索引列中插入重複值和空值。

 全文索引可以在char、varchar或text型別的列上建立,主要用於在大量文字文字中搜索字串,此時使用全文索引的效率將大大高於使用SQL的like關鍵字的效率。

(6)空間索引

  對空間資料型別的列建立的索引,如geometry、point等。

  建立空間索引的列,必須為not null,且只能在儲存引擎為MyISAM的表中建立。

3.3 建立、刪除索引

  在已存在的表上新增索引的基本語法:

/*建立索引*/
/*length為索引長度,只有字串型別才能指定索引長度*/
create [unique|fulltext|spatial|] index index_name
    on tableName(colum_Name[length]...);

/*刪除索引*/
drop index tableName.index_name;

  刪除表,該表的所有索引將同時被刪除;

  刪除表中的列,如果要刪除的列為索引的組成部分,則該列也會從索引中刪除;

  如果組成索引的列都被刪除,則整個索引都將被刪除。

 

  3.4  選擇建立索引的列

  • 頻繁搜尋的列;
  • 經常用作查詢的列;
  • 經常排序、分組的列;
  • 經常用作連線的列(主鍵/外來鍵)

  不要使用下面的列建立索引:

  • 僅包含幾個不同值的列;
  • 表中僅包含幾行,因為為小型表建立索引並不實用;

 

 3.5 一點經驗

  查詢時減少使用*返回全部列,不要返回不需要的列;

  索引應該儘量小,在位元組數小的列上建立索引;

  where子句中有多個條件表示式時,包含索引的表示式應置於其他表示式之前;

  避免在order by子句中使用表示式;

  根據業務資料發生頻率,定期重新生成或重新組織索引,進行碎片整理。

 

  3.6 檢視索引

/*檢視已建立的索引*/
show index from tableName;

/*檢視學生表中的索引*/
show index from `student`\G;

  在查詢語句後面加“\G”,表示結果將按列排列。當表中列較多,需要看錶中各列中的值時非常有用。

  在儲存型別為InnoDB的表中,經常使用唯一索引、普通索引、組合索引來提高查詢效率。

練習:

  #開始執行時間監測
    set profiling =1
    #查詢一萬條資料ha-99999
    select * from test_index where ttle="ha-99999"
    #檢視執行時間
    show profiles;
    # 為title_indexd的title列建立索引
    create index title_index on test_index(title(10))
    #執行查詢語句
     select * from test_index where ttle="ha-99999"
     #檢視執行時間
    show profiles;

3.7注意:

要注意:建立太多的索引將會影響更新和插入的速度,因為它需要同樣更新每個索引檔案,對於一個經常要更新和插入的表格,就沒有必要為一個很少使用where字句單獨建立索引,對於比較小的表,排序的開銷不會很大,也沒有必要建立另外的索引。

建立索引會佔用磁碟空間。

四、備份與恢復資料

4.1備份資料:

  #備份資料 mysqldump -uroot -p123456 資料庫名 > jd.sql 

  mysqldump -uroot -p123456 jing_dong > jd.sql 

4.2恢復資料

  1)連線mysql,建立新的資料庫

   2)退出資料庫,執行如下命令:

  #恢復資料 mysql  -uroot -p123456 新資料庫名 < jd.sql 

  mysql -uroot -p123456 jing_dong2 < jd.sql 

五、MYSQL主從

1 主從同步的定義

主從同步使得資料可以從一個數據庫伺服器複製到其他伺服器上,在複製資料時,一個伺服器充當主伺服器(master),其餘的伺服器充當從伺服器(slave)。因為複製是非同步進行的,所以從伺服器不需要一直連線著主伺服器,從伺服器甚至可以通過撥號斷斷續續地連線主伺服器。通過配置檔案,可以指定複製所有的資料庫,某個資料庫,甚至是某個資料庫上的某個表。

使用主從同步的好處:

1.通過增加從伺服器來提高資料庫的效能,在主伺服器上執行寫入和更新,在從伺服器上向外提供讀功能,可以動態地調整從伺服器的數量,從而調整整個資料庫的效能。

2.提高資料安全,因為資料已複製到從伺服器,從伺服器可以終止複製程序,所以,可以在從伺服器上備份而不破壞主伺服器相應資料。

3.在主伺服器上生成實時資料,而在從伺服器上分析這些資料,從而提高主伺服器的效能。

2 主從同步的機制

 Mysql伺服器之間的主從同步是基於二進位制日誌機制,主伺服器使用二進位制日誌來記錄資料庫的變動情況,從伺服器通過讀取和執行該日誌檔案來保持和主伺服器的資料一致。在使用二進位制日誌時,主伺服器的所有操作都會被記錄下來,然後從伺服器會接收到該日誌的一個副本。從伺服器可以指定執行該日誌中的哪一類事件(譬如只插入資料或者只更新資料),預設會執行日誌中的所有語句。每一個從伺服器會記錄關於二進位制日誌的資訊:檔名和已經處理過的語句,這樣意味著不同的從伺服器可以分別執行同一個二進位制日誌的不同部分,並且從伺服器可以隨時連線或者中斷和伺服器的連線。主伺服器和每一個從伺服器都必須配置一個唯一的ID號(在my.cnf檔案的[mysqld]模組下有一個server-id配置項),另外,每一個從伺服器還需要通過CHANGEMASTERTO語句來配置它要連線的主伺服器的ip地址,日誌檔名稱和該日誌裡面的位置(這些資訊儲存在主伺服器的資料庫裡)

3 配置主從同步的基本步驟

有很多種配置主從同步的方法,可以總結為如下的步驟:

(1)在主伺服器上,必須開啟二進位制日誌機制和配置一個獨立的ID

(2)在每一個從伺服器上,配置一個唯一的ID,建立一個用來專門複製主伺服器資料的賬號

(3)在開始複製程序前,在主伺服器上記錄二進位制檔案的位置資訊

(4)如果在開始複製之前,資料庫中已經有資料,就必須先建立一個數據快照(可以使用mysqldump匯出資料庫,或者直接複製資料檔案)

(5)配置從伺服器要連線的主伺服器的IP地址和登陸授權,二進位制日誌檔名和位置

4 詳細配置主從同步的方法

4.1資料備份

如果在設定主從同步前,主伺服器上已有大量資料,可以使用 mysqldump 進行資料備份並還原到從伺服器以實現資料的複製。執行命令:

$ mysqldump -uroot -pmysql --all-databases --lock-all-tables > ~/master_db.sql

 --all-databases :匯出所有資料庫

 --lock-all-tables :執行操作時鎖住所有表,防止操作時有資料修改

 ~/master_db.sql :匯出的備份資料(sql 檔案)位置,可自己指定

資料還原命令:

$ mysql –uroot –pmysql < master_db.sql

4.2配置主伺服器master(從伺服器也要設定,但是注意server-id不能相同,主伺服器配置為1,從伺服器配置其他數值

編輯設定mysqld的配置檔案,設定log_bin和server-id

server-id不能相同,主伺服器配置為1,從伺服器配置其他數值

$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

# 啟用log_bin和server-id兩項配置

這裡寫圖片描述

重啟服務:

$ sudo service mysql restart

登入主伺服器Ubuntu中的mysql,建立用於從伺服器同步資料使用的帳號

$ mysql –uroot –pmysql

mysql> grant replication slave on *.* to 'slave'@'%' identified by 'slave';

mysql> show master status;

mysql> flush privileges;

mysql> show master status;


+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000001 |      107 |              |                  |

+------------------+----------+--------------+------------------+

1 row in set (0.00 sec)

File為使用的日誌檔名字,Position為使用的檔案位置,這兩個引數必須記下,配置從伺服器時會用到。

4.3配置從伺服器器slave

編輯設定mysqld的配置檔案,server-id

$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

# 修改server-id不能與mysql主服務相同,2開始的數值



$ mysql –uroot –pmysql

mysql> change master to master_host='104.199.171.116',master_user='slave',master_password='slave',master_log_file='mysql-bin.000001',master_log_pos=107;
注:master_host:主伺服器 Ubuntu 的 ip 地址

master_log_file: 前面查詢到的主伺服器日誌檔名

master_log_pos: 前面查詢到的主伺服器日誌檔案位置

開啟同步,檢視同步狀態

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

mysql> start slave;

mysql> show slave status \G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 104.199.171.116

                  Master_User: slave

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000001

          Read_Master_Log_Pos: 107

               Relay_Log_File: yangwanyan-relay-bin.000002

                Relay_Log_Pos: 253

        Relay_Master_Log_File: mysql-bin.000001

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

              Replicate_Do_DB:

          Replicate_Ignore_DB:

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                   Last_Errno: 0

                   Last_Error:

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 107

              Relay_Log_Space: 414

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File:

           Master_SSL_CA_Path:

              Master_SSL_Cert:

            Master_SSL_Cipher:

               Master_SSL_Key:

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

               Last_SQL_Errno: 0

               Last_SQL_Error:

  Replicate_Ignore_Server_Ids:

             Master_Server_Id: 1

1 row in set (0.00 sec)

新建資料庫表和使用者

1

2

mysql>  create database ttsx charset='utf8';

mysql> grant all on ttsx.* to 'ttsx'@'%' identified by '123456';