1. 程式人生 > >數據庫的數據類型、索引、鎖、事務和視圖

數據庫的數據類型、索引、鎖、事務和視圖

ima -m log_file oat 寬度 默認值 col 說明 prim

數據庫的數據類型、索引、鎖、事務和視圖

數據的類型

1)數據類型:
    數據長什麽樣?
    數據需要多少空間來存放?
    系統內置數據類型和用戶定義數據類型
2)MySql 支持多種列類型:
    數值類型
    日期/時間類型
    字符串(字符) 類型
3)選擇正確的數據類型對於獲得高性能至關重要,三大原則:
    更小的通常更好,盡量使用可正確存儲數據的最小數據類型
    簡單就好,簡單數據類型的操作通常需要更少的CPU 周期
    盡量避免NULL,包含為NULL的列,對MySQL更難優化
4)整型
    tinyint(m)  1節個字節,範圍(-128~127)
    smallint(m)     2節個字節,範圍(-32768~32767)
    mediumint(m)    3節個字節,範圍(-8388608~8388607)
    int(m)  4節個字節,範圍(-2147483648~2147483647)
    bigint(m)   8節個字節,範圍(+-9.22*10 的18 次方)
    integer 
    decimal 
    註:
        1》取值範圍如果加了unsigned ,則最大值翻倍,如tinyint unsigned的取值範圍為(0~255)。
        2》int(m)裏的m是表示SELECT查詢結果集中的顯示寬度,並不影響實際的取值範圍。
        3》MySQL可以為整型類型指定寬度,例如Int(11) ,對絕大多數應用這是沒有意義的:它不會限制值的合法範圍,只是規定了MySQL的一些交互工具(例如MySQL 命令行客戶端)用來顯示字符的個數。對於存儲和計算來說,Int(1)和Int(20)是相同的。

5)浮點型,近似值
    float(m,d)  單精度浮點型8位精度(4字節)m總個數,d小數位
    double(m,d)     雙精度浮點型16位精度(8字節)m總個數,d小數位
    real    
    bit 
    示例
        設一個字段定義為float(6,3) ,如果插入一個數123.45678,實 實際數據庫裏存的是123.457 ,但總個數還以實際為準,即6位。
    
4)定點數
    1》在數據庫中存放的是精確值, 存為十進制。
    2》decimal(m,d)參數m<65是總個數,d<30且d<m 是小數位
    3》MySQL5.0 和更高版本將數字打包保存到一個二進制字符串中(每4個字節存9個數字)。例如,decimal(18,9) 小數點兩邊將各存儲9個數字,一共使用9個字節:小數點前的數字用4個字節,小數點後的數字用4個字節,小數點本身占1個字節
    4》浮點類型在存儲同樣範圍的值時,通常比decimal使用更少的空間。float使用4個字節存儲。double占用8個字節
    5》因為需要額外的空間和計算開銷,所以應該盡量只在對小數進行精確計算時才使用decimal。例如存儲財務數據。但在數據量比較大的時候,可以考慮使用bigint代替decimal。
    
5)字符型(char,varchar,_text)
    char(n)     固定長度,最多255個字符,不區分大小寫
    varchar(n)  可變長度,最多65535個字符
    tinytext    可變長度,最多255個字符
    text    tinytext,text,mediumtext,longtext。可變長度,最多65535個字符
    mediumtext      可變長度,最多2的24次方-1個字符
    longtext    可變長度,最多2的32次方-1個字符
    binary(M)   固定長度,可存二進制或字符,允許長度為0-M字節,區分大小寫
    varbinary(M)    可變長度,可存二進制或字符,允許長度為0-M字節
    blob    tinyblob,blob,mediumblob,longblob
    char和varchar: 
        1》char(n)若存入字符數小於n ,則以空格補於其後,查詢之時再將空格去掉。所以char 類型存儲的字符串末尾不能有空格,varchar不限於此。
        2》char(n)固定長度,char(4)不管是存入幾個字符,都將占用4個字節,varchar是存入的實際字符數+1個字節(n< n>255) ,所以varchar(4), 存入3 個字符將占用4 個字節。
        3》char類型的字符串檢索速度要比varchar 類型的快
    varchar和text: 
        1》varchar可指定n,text不能指定,內部存儲varchar是存入的實際字符數+1個字節(n< n>255) ,text是實際字符數+2個字節。
        2》text類型不能有默認值
        3》varchar可直接創建索引,text創建索引要指定前多少個字符,varchar查詢速度快於text。
6)二進制數據:blod
    BLOB和text存儲方式不同,TEXT以文本方式存儲,英文存儲區分大小寫,而Blob是以二進制方式存儲,不分大小寫。
    BLOB存儲的數據只能整體讀出
    TEXT可以指定字符集,BLOB不用指定字符集
    
7)日期時間類型
    date    日期 ‘2008-12-2‘
    time    時間 ‘12:25:36‘
    datetime    日期時間 ‘2008-12-2 22:06:44‘
    timestamp   自動存儲記錄修改時間
    year(2), year(4)    年份
    若定義一個字段為timestamp,這個字段裏的時間數據會隨其他字段修改的時候自動刷新,這個數據類型的字段可以存放這條記錄最後被修改的時間
8)修飾符
    NULL    數據列,可包含NULL值 
    NOT NULL    數據列,不允許包含NULL值
    DEFAULT     默認值
    PRIMARY KEY     主鍵
    UNIQUE KEY  唯一鍵
    CHARACTER SET name  指定一個字符集
    AUTO_INCREMENT  自動遞增,適用於整數類型
    UNSIGNED    無符號
    類型修飾符:
        字符型:not null,null,defalut ‘string’,characet set ‘charset’,collation ‘collocation‘
        整型:not null, null, defalut value, auto_increment, unsigned
        日期時間型:not null, null, default 
    
9)內建類型:
    enum枚舉,
        enum(‘sun‘,‘mon‘,‘tue‘,‘wed‘)
    set集合

數據庫的索引

1.數據庫索引
    1)數據庫索引
        1》數據庫的索引使數據庫程序無須對整個表進行掃描,就可以在其中找到所有數據。
        2》索引是某個表中一列或者若幹列值的集合,以及是物理標識這些值的數據頁的邏輯指針清單。
        3》提取表上字段中的數據來創建索引,構建出一個獨特的數據結構。也就是把表中某個或某些字段的數據提取出來另存為一個特定數據結構的數據,這些字段是在where字句中的用到的字段。
        
    2)索引的作用
        1》設置了合適的索引後,數據庫利用各種快速的定位技術,就能夠大大加快查詢速率,特別是表特別大的時候,或者是涉及多個表的時候。
        2》可以降低數據庫的I/O成本,並且索引還可以降低數據庫的排序成本。
        3》通過創建唯一性索引保證數據表數據的唯一性,可以加快表和表間的連接。
        4》在使用分組和排序時,可以大大減少分組和排序時間。
        5》加速查詢操作,副作用是降低寫操作性能。
        
    3)索引類型:b+ tree,hash
        b+ tree索引:
            順序存儲,每一個葉子結點到根結點的距離相同;
            左前綴索引,適合於範圍類型的數據查詢;
            
            適用於b+ tree索引的查詢類型:全鍵值、鍵值範圍、鍵前綴;
                全值匹配:精確匹配某個值;
                    where column = ‘value‘;
                匹配最左前綴:只精確匹配起頭的部分;
                    wehre column like ‘prefix%‘;                        
                匹配範圍值:
                    精確匹配某一列,範圍匹配另一列;
                    只用訪問索引的查詢:覆蓋索引;
                        index(name)
                        select name from students where name like ‘l%‘;
                                        
            不適用b+ tree索引:
                如果查詢條件不是從最左側列開始,索引無效;
                    index(age,fname), where fname=‘jerry‘;    , where age>30 and fname=‘smith‘;
                不能跳過索引中的某列;
                    index(name,age,gender)
                        where name=‘black‘ and age > 30;
                        where name=‘black‘ and gender=‘f‘;
                如果查詢中的某個列是為範圍查詢,那麽其右側的列都無法再使用索引優化查詢;
                    where age>30 and fname=‘smith‘;
            
        hash索引:
            基於哈希表實現,特別適用於值的精確匹配查詢;
            
            適用場景:
                只支持等值比較查詢,例如=, in(), <=>
                
            不用場景:
                所有非精確值查詢;mysql僅對memory存儲引擎支持顯式的hash索引;
    4)索引的細分
        1》普通索引
            這是最基本的索引類型,而且沒有唯一性之類的限制。
        2》唯一性索引
            索引的列的所有值都只能出現一次,即必須唯一,但可以為空NULL。
        3》主鍵索引、輔助索引
            主鍵索引是一種特殊的唯一索引,必須指定primary key,具有唯一性的同時不能為空null。
        4》全文索引
            mysql從3.23.23版開始支持全文索引和全文檢索。在mysql中,全文索引的類型為fulltext,全文索引可以在varchar或text類型的列上創建。
        5》單列索引與多列索引
            索引可以是單列上創建索引,也可以是在多列上創建索引。
        6》聚集索引、非聚集索引
            索引是否與數據存在一起;
        7》稠密索引、稀疏索引
            是否索引了每一個數據項;
    5)索引的優點
        降低需要掃描的數據量,減少io次數;
        可以幫助避免排序操作,避免使用臨時表; 
        幫助將隨機io轉為順序io;
        
2.創建索引的原則
    1)表的主鍵、外鍵必須有索引
    2)數據超過300行的表應該有索引
    3)經常與其他表進行連接的表,在連接字段上應該建立索引
    4)唯一性太差的字段不適合建立索引
    5)更新太頻繁的字段不適合建立索引
    6)經常出現在where字句中的字段,特別是大表的字段,應該建立索引
    7)索引應該建立在選擇性高的字段上
    8)索引應該建立在小字段上,對於大的文本字段甚至超長字段,不要建立索引
3.索引的管理
    1)創建索引
        help create index
            create [online|offline] [unique|fulltext|spatial] index index_name [index_type] on tbl_name (index_col_name,...) [index_option] ...
                index_col_name:字段
                    col_name [(length)] [asc | desc]
                index_type:
                    using {btree | hash}
                index_option:
                    key_block_size [=] value|index_type| with parser parser_name|comment ‘string‘
        1》創建普遍索引
            create index index_name on tbl_name(字段);
            alter table table_name add index index_name (column_list);
        2》創建唯一性索引
            create unique index index_name on tal_name(字段);
            alter table table_name add unique (字段);
        3》創建主鍵索引
            create table tbl_name([...],primary key(字段));##用於建表時創建主鍵
            alter table tal_name add primary key(字段);##建表時忘記創建主鍵可以進行修改
    2)查看索引
        show {index | indexes | keys} {from | in} tbl_name [{from | in} db_name] [where expr];
        show index from tbl_name;
        show keys from tbl_name;
        示例:
            show index from mytable from mydb;
            show index from mydb.mytable;
                Table:表的名稱。
                Non_unique:如果索引不能包括重復詞,則為0。如果可以,則為1。
                Key_name:索引的名稱。
                Seq_in_index:索引中的列序列號,從1開始。
                Column_name:列名稱。
                Collation:列以什麽方式存儲在索引中。在MySQL中,有值‘A’(升序)或NULL(無分類)。
                Cardinality:索引中唯一值的數目的估計值。通過運行ANALYZE TABLE或myisamchk -a可以更新。基數根據被存儲為整數的統計數據來計數,所以即使對於小型表,該值也沒有必要是精確的。基數越大,當進行聯合時,MySQL使用該索引的機會就越大。
                Sub_part:如果列只是被部分地編入索引,則為被編入索引的字符的數目。如果整列被編入索引,則為NULL。
                Packed:指示關鍵字如何被壓縮。如果沒有被壓縮,則為NULL。
                Null:如果列含有NULL,則含有YES。如果沒有,則該列含有NO。
                Index_type:用過的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
                Cmment:註釋,說明
                
    3)刪除索引
        drop [online|offline] index index_name on tbl_name;
        drop index index_name on tbl_name;
        alter table tbl_name drop index index_name;
        alter table tbl_name drop primary key;##每個表只允許有一個primary key,所以不用指明名稱。
        如果從表中刪除了某列,則索引會受到影響。對於多列組合的索引,如果刪除其中的某列,則該列也會從索引中刪除。如果刪除組成索引的所有列,則整個索引將被刪除。

4.對MySQL數據庫建立索引的事項及提高性能的手段
    1)註意事項:
        首先,應當考慮表空間和磁盤空間是否足夠。我們知道索引也是一種數據,在建立索引的時候勢必也會占用大量表空間。因此在對一大表建立索引的時候首先應當考慮的是空間容量問題。
        其次,在對建立索引的時候要對表進行加鎖,因此應當註意操作在業務空閑的時候進行。
    2)性能調整方面:
        首先,要考慮因素便是磁盤I/O。物理上,應當盡量把索引與數據分散到不同的磁盤上(不考慮陣列的情況)。邏輯上,數據表空間與索引表空間分開。這是在建索引時應當遵守的基本準則。
        其次,我們知道,在建立索引的時候要對表進行全表的掃描工作,因此,應當考慮調大初始化參數db_file_multiblock_read_count的值。一般設置為32或更大。
        再次,建立索引除了要進行全表掃描外同時還要對數據進行大量的排序操作,因此,應當調整排序區的大小。9i之前,可以在session級別上加大sort_area_size的大小,比如設置為100m或者更大。9i以後,如果初始化參數workarea_size_policy的值為TRUE,則排序區從pga_aggregate_target裏自動分配獲得。
        最後,建立索引的時候,可以加上nologging選項。以減少在建立索引過程中產生的大量redo,從而提高執行的速度。
    3)高性能索引策略:
        (1) 在where中獨立使用列,盡量避免其參與運算;
            where age+2 > 32 ; 
        (2) 左前綴索引:索引構建於字段的最左側的多少個字符,要通過索引選擇性來評估
            索引選擇性:不重復的索引值和數據表的記錄總數的比值;
        (3) 多列索引:
            and連接的多個查詢條件更適合使用多列索引,而非多個單鍵索引;
        (4) 選擇合適的索引列次序:選擇性最高的放左側;
5.設計MySql索引的時候有一下幾點註意:
    1,創建索引
        對於查詢占主要的應用來說,索引顯得尤為重要。很多時候性能問題很簡單的就是因為我們忘了添加索引而造成的,或者說沒有添加更為有效的索引導致。如果不加索引的話,那麽查找任何哪怕只是一條特定的數據都會進行一次全表掃描,如果一張表的數據量很大而符合條件的結果又很少,那麽不加索引會引起致命的性能下降。但是也不是什麽情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什麽優勢,還會影響到更新速度,這被稱為過度索引。
    2,復合索引
        比如有一條語句是這樣的:select * from users where area=’beijing’ and age=22;如果我們是在area和age上分別創建單個索引的話,由於mysql查詢每次只能使用一個索引,所以雖然這樣已經相對不做索引時全表掃描提高了很多效率,但是如果在area、age兩列上創建復合索引的話將帶來更高的效率。如果我們創建了(area, age,salary)的復合索引,那麽其實相當於創建了(area,age,salary)、(area,age)、(area)三個索引,這被稱為最佳左前綴特性。因此我們在創建復合索引時應該將最常用作限制條件的列放在最左邊,依次遞減。
    3,索引不會包含有NULL值的列
        只要列中包含有NULL值都將不會被包含在索引中,復合索引中只要有一列含有NULL值,那麽這一列對於此復合索引就是無效的。所以我們在數據庫設計時不要讓字段的默認值為NULL。
    4,使用短索引
        對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的 列,如果在前10 個或20 個字符內,多數值是惟一的,那麽就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁盤空間和I/O操作。
    5,排序的索引問題
        mysql查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那麽order by中的列是不會使用索引的。因此數據庫默認排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引。
    6,like語句操作
        一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like “%aaa%” 不會使用索引而like “aaa%”可以使用索引。
    7,不要在列上進行運算
    8,不使用NOT IN和操作
        NOT IN和大於等於操作都不會使用索引將進行全表掃描。NOT IN可以NOT EXISTS代替,id3則可使用id>3 or id
    
6.explain 來分析索引的有效性
    explain來分析索引有效性:
    help explain
        explain [explain_type] select select_options
            explain_type:
                extended  | partitions  
        explain tbl_name
            輸出結果:
                    id: 1
                select_type: simple
                    table: students
                    type: const
                possible_keys: primary
                    key: primary
                key_len: 4
                    ref: const
                    rows: 1
                    extra: 
        id:當前查詢語句中,第幾個select語句的編號;
            復雜的查詢的類型主要三種:
                簡單子查詢
                用於from中的子查詢
                聯合查詢
                註意:聯合查詢的分析結果會出現一個額外的匿名臨時表;
            
        select_type:查詢類型:
            簡單查詢:simple
            復雜查詢:
                簡單子查詢:subquery
                用於from中的子查詢:derived
                聯合查詢中的第一個查詢:primary
                聯合查詢中的第一個查詢之後的其它查詢:union
                聯合查詢生成的臨時表:union result
                
        table:查詢針對的表;
        
        type:關聯類型,或稱為訪問類型,即mysql如何去查詢表中的行
            all:全表掃描;
            index:根據索引的順序進行的全表掃描;但同時如果extra列出現了"using index”表示使用了覆蓋索引;
            range:有範圍限制地根據索引實現範圍掃描;掃描位置始於索引中的某一項,結束於另一項;
            ref:根據索引返回的表中匹配到某單個值的所有行(匹配給定值的行不止一個);
            eq_ref:根據索引返回的表中匹配到某單個值的單一行,僅返回一個行,但需要與某個額外的參考值比較,而不是常數;
            const,system:與某個常數比較,且只返回一行;
            
        possiable_keys:查詢中可能會用到的索引;
            
        key:查詢中使用的索引;
        
        key_len:查詢中用到的索引長度;
        
        ref:在利用key字段所顯示的索引完成查詢操作時所引用的列或常量值; 
        
        rows:mysql估計出的為找到所有的目標項而需要讀取的行數;
        
        extra:額外信息
            using index:使用了覆蓋索引進行的查詢;
            using where:拿到數據後還要再次進行過濾; 
            using temporary:使用了臨時表以完成查詢;
            using filesort:對結果使用了一個外部索引排序;
    
7.查詢緩存
    緩存:k/v 
        key:查詢語句的hash值
        value:查詢語句的執行結果
        
    如何判斷緩存是否命中:
        通過查詢語句的哈希值判斷:哈希值考慮的因素包括
            查詢本身、要查詢數據庫、客戶端使用的協議版本、...
                select name from students where stuid=3;
                select name from students where stuid=3;
            
    哪些查詢可能不會被緩存?
        查詢語句中包含udf
        存儲函數
        用戶自定義變量
        臨時表
        mysql系統表或者是包含列級別權限的查詢
        有著不確定結果值的函數(now());
        
    查詢緩存相關的服務器變量:
        query_cache_limit:能夠緩存的最大查詢結果;(單語句結果集大小上限)
            有著較大結果集的語句,顯式使用sql_no_cache,以避免先緩存再移出; 
        query_cache_min_res_unit:內存塊的最小分配單位;緩存過小的查詢結果集會浪費內存空間;
            較小的值會減少空間浪費,但會導致更頻繁地內存分配及回收操作; 
            較大值的會帶來空間浪費;
        query_cache_size:查詢緩存空間的總共可用的大小;單位是字節,必須是1024的整數倍;
        query_cache_strip_comments
        query_cache_type:緩存功能啟用與否;
            on:啟用;
            off:禁用;
            demand:按需緩存,僅緩存select語句中帶sql_cache的查詢結果;
        query_cache_wlock_invalidate:如果某表被其它連接鎖定,是否仍然可以從查詢緩存中返回查詢結果;默認為off,表示可以;on則表示不可以;
    
    狀態變量:
        mysql> show global status like ‘qcache%‘;
        +-------------------------+----------+
        | variable_name           | value    |
        +-------------------------+----------+
        | qcache_free_blocks      | 1        |
        | qcache_free_memory      | 16759688 |
        | qcache_hits             | 0        |
        | qcache_inserts          | 0        |
        | qcache_lowmem_prunes    | 0        |
        | qcache_not_cached       | 0        |
        | qcache_queries_in_cache | 0        |
        | qcache_total_blocks     | 1        |
        +-------------------------+----------+      
        
    命中率:
        qcache_hits/com_select 

數據庫的鎖

鎖用於並發控制:
    鎖:lock 
    鎖類型 :
        讀鎖:共享鎖,可被多個讀操作共享;
        寫鎖:排它鎖,獨占鎖;
    鎖粒度:
        表鎖:在表級別施加鎖,並發性較低;
        行鎖:在行級別施加鎖,並發性較高;維持鎖狀態的成本較大;
    鎖策略:在鎖粒度及數據安全性之間尋求一種平衡機制;
        存儲引擎:級別以及何時施加或釋放鎖由存儲引擎自行決定;
        mysql server:表級別,可自行決定,也允許顯式請求; 
    鎖類別:
        顯式鎖:用戶手動請求的鎖;
        隱式鎖:存儲引擎自行根據需要施加的鎖;
    
    顯式鎖的使用:
        (1) lock tables 
            lock tables  tbl_name  read|write, tbl_name read|write, ...
            unlock tables
        (2) flush tables
            flush tables tbl_name,... [with read lock];
            unlock tables;
        (3) select cluase
            [for update | lock in share mode]
    

數據庫的事務

1.事務的概念
    1)事務是一種機制,是一個操作序列,包含了一組數據庫操作命令,並且把所有的命令作為一個整體一起向系統提交或撤銷操作請求,即這一組的數據庫命令要麽都執行,要麽都不執行。
    2)事務是一個不可分割的工作邏輯單元,在數據庫系統上執行並發操作時,事務是最小的控制單元。
    3)事務適用於多用戶同時操作的數據庫系統的場景,通過事務的完整性以保證數據的一致性。
    4)事務是一組原子性的sql查詢、或者是一個或多個sql語句組成的獨立工作單元;
2.事務的ACID特點
    事務具有四個屬性:ACID
        A:原子性,atomicity
        C:一致性,consistency
        I:隔離性,isolation
        D:持久性,durability
    1)原子性
        事務是一個完整的操作,事務的各元素是不可分割的(原子的),事務的所有元素必須作為一個整體提交或回滾。如果事務中的任何元素失敗,則整個事務將失敗。
    2)一致性
        當事務完成時,數據必須處於一致狀態:在事務開始之前,數據庫匯總存儲的數據處於一致狀態;在正在進行的事務中,數據可能處於不一致的狀態;當事務完成時,數據必須再次回到已知的一致狀態。
    3)隔離性
        對數據進行修改的所有並發事務是彼此隔離的,這表明事務必須是獨立的,它不應該以任何方式依賴於或影響其他事務。修改數據的事務可以在另一個使用相同的數據的事務開始之前訪問這些數據,或者在另一個使用相同的數據的事務結束之後訪問這些數據。
    4)持久性
        事務的持久性指不管系統是否發生了故障,事務處理的結果都是永久的。一旦事務被提交,事務的效果會被永久地保留在數據庫中。

3.事務的操作
    默認情況下mysql的事務是自動提交的,當sql語句提交時,事務便自動提交。
    1)自動提交:單語句事務
        mysql> select @@autocommit;
        +------------------------+
        | @@autocommit |
        +------------------------+
        |            1               |
        +------------------------+
        mysql> set @@session.autocommit=0;
    
    2)手動對事務進行控制的方法:
        事務處理命令控制
        使用set設置事務處理方式
        1》事務處理命令控制事務
            start transaction ,begin:開始一個事務
            commit:提交一個事務
            rollback:回滾一個事務(撤銷)
            示例:
                MariaDB [none]> use auther;
                MariaDB [auther]> begin;
                MariaDB [auther]> insert into users values(‘list‘,password(‘123456‘));
                MariaDB [auther]> insert into users values(‘wang‘,password(‘123456‘));
                MariaDB [auther]> select * from users;
                +-----------+--------------------------------+
                | user_name | user_passwd                    |
                +-----------+--------------------------------+
                | list      | *6BB4837EB74329105EE4568DDA7DC |
                | shen      | *A4B6157319038724E3560894F7F93 |
                | wang      | *6BB4837EB74329105EE4568DDA7DC |
                +-----------+--------------------------------+
                MariaDB [auther]> commit;
                MariaDB [auther]> select * from users;
                +-----------+--------------------------------+
                | user_name | user_passwd                    |
                +-----------+--------------------------------+
                | list      | *6BB4837EB74329105EE4568DDA7DC |
                | shen      | *A4B6157319038724E3560894F7F93 |
                | wang      | *6BB4837EB74329105EE4568DDA7DC |
                +-----------+--------------------------------+
                MariaDB [auther]> begin;
                MariaDB [auther]> update users set user_passwd=password(‘‘) where user_name=‘list‘;
                MariaDB [auther]> select * from users;
                +-----------+--------------------------------+
                | user_name | user_passwd                    |
                +-----------+--------------------------------+
                | list      |                                |
                | shen      | *A4B6157319038724E3560894F7F93 |
                | wang      | *6BB4837EB74329105EE4568DDA7DC |
                +-----------+--------------------------------+
                MariaDB [auther]> rollback; ##從begin開始的所有命令都將被撤銷
                MariaDB [auther]> select * from users;
                +-----------+--------------------------------+
                | user_name | user_passwd                    |
                +-----------+--------------------------------+
                | list      | *6BB4837EB74329105EE4568DDA7DC |
                | shen      | *A4B6157319038724E3560894F7F93 |
                | wang      | *6BB4837EB74329105EE4568DDA7DC |
                +-----------+--------------------------------+
        
        2》使用set命令進行控制
            set autocommit=0:禁止自動提交,不管你輸入執行了幾條命令,在沒有輸入commit前都是一個事務。
            set autocommit=1 :開啟自動提交,每輸入執行一條命令,那麽就為一個事務。
        
4.補充
        事務日誌:
                innodb_log_files_in_group
                innodb_log_group_home_dir
                innodb_log_file_size    
                innodb_mirrored_log_groups
        事務支持savepoints:
                savepoint identifier
                rollback [work] to [savepoint] identifier
                release savepoint identifier                
            
        事務隔離級別:
            read-uncommitted:讀未提交 --> 臟讀;
            read-committed:讀提交--> 不可重復讀;
            repeatable-read:可重復讀 --> 幻讀;
            serializable:串行化;
            mysql> select @@session.tx_isolation;
            +----------------------------------+
            | @@session.tx_isolation |
            +----------------------------------+
            | repeatable-read         |
            +----------------------------------+
        
        查看innodb存儲引擎的狀態信息:
            show engine innodb status; 

數據庫的視圖

1.視圖
    1)視圖是從一個或多個表中導出來的表,是一種虛擬存在的表。
    2)視圖就像一個窗口,通過這個窗口可以看到系統專門提供的數據。這樣,用戶可以不用看到整個數據庫中的數據,而只關心對自己有用的數據。
    3)數據庫中只存放了視圖的定義,而沒有存放視圖中的數據,這些數據存放在原來的表中。
    4)使用視圖查詢數據時,數據庫系統會從原來的表中取出對應的數據。
    5)視圖中的數據依賴於原來表中的數據,一旦表中數據發生改變,顯示在視圖中的數據也會發生改變。
2.視圖的作用
    1)使操作簡單化,可以對經常使用的查詢定義一個視圖,使用戶不必為同樣的查詢操作指定條件
    2)增加數據的安全性,通過視圖,用戶只能查詢和修改指定的數據。
    3)提高表的邏輯獨立性,視圖可以屏蔽原有表結構變化帶來的影響。
    總而言之,使用視圖的大部分情況是為了保障數據安全性,提高查詢效率
    
3.創建視圖
    語法:
        help create view
            create
                [or replace]
                [algorithm = {undefined | merge | temptable}]
                [definer = { user | current_user }]
                [sql security { definer | invoker }]
                view view_name [(column_list)]
                as select_statement
                [with [cascaded | local] check option]
        algorithm:
            表示視圖選擇的算法(可選參數)
            undefined:mysql將自動選擇所要使用的算法
            merge:將視圖的語句與視圖定義合並起來,使得視圖定義的某一部分取代語句的對應部分
            temptable:將視圖的結果存入臨時表,然後使用臨時表執行語句
        column_list:
            表示視圖中的列名,默認與select查詢結果中的列名相同(可選參數)
        AS:
            表示將後面SELECT 語句中的查詢結果賦給前面的視圖中
        with check option:
            表示更新視圖時要保證在該試圖的權限範圍之內(可選參數)
            cascaded:更新視圖時要滿足所有相關視圖和表的條件
            local:更新視圖時,要滿足該視圖本身定義的條件即可
            創建試圖時最好加上with cascaded check option參數,這種方式比較嚴格,可以保證數據的安全性
    示例:
        1)在單表上創建視圖
             create view work_view(id,name,address) as select id,name,address from work;  
        2)在多表創建視圖
            create algorithm=merge view work_view2(id,name,salary) as select work.id,name,salary from work,salary where work.id=salary.id with local check option;
            在多表中創建視圖需要兩表有指定聯系,如上面的work.id=salary.id
        3)官方示例
            1>
                mysql> create table t (qty int, price int);
                mysql> insert into t values(3, 50);
                mysql> create view v as select qty, price, qty*price as value from t;
                mysql> select * from v;
                +------+-------+-------+
                | qty  | price | value |
                +------+-------+-------+
                |    3 |    50 |   150 |
                +------+-------+-------+
            2>
                mysql> create view v (mycol) as select ‘abc‘;
                mysql> set sql_mode = ‘‘;
                mysql> select "mycol" from v;
                +-------+
                | mycol |
                +-------+
                | mycol |
                +-------+
                mysql> set sql_mode = ‘ansi_quotes‘;
                mysql> select "mycol" from v;
                +-------+
                | mycol |
                +-------+
                | abc   |
                +-------+
4.查看視圖
    1)select 查看視圖
        SELECT * FROM view_name;
        此處的SELECT語句用法和其他表中的用法一樣,別忘了,視圖也是一張表,只不過它是虛擬的。
    2)describe查看視圖的基本信息
        ESCRIBE view_name;
    3)show table status查看視圖基本信息
         SHOW TABLE STATUS LIKE ‘view_name‘\G;
    4)show create view 查看視圖的詳細信息
         SHOW CREATE VIEW view_name\G;
    5)在views表中查看視圖的詳細信息
        SELECT * FROM information_schema.views\G;
        information_schema.views表內包含了所有的視圖定義信息
        
5.修改視圖
    修改視圖是指修改數據庫中已存在的表的定義,當基本表的某些字段發生改變時,可以通過修改視圖來保持視圖和基本表之間一致。
    1)create or replace view來修改視圖
         create or replace algorithm=temptable view view_name(id,name) as select id,name from tbl_name;
    2)alter來修改視圖
        alter view view_name(name,salary,addr) as select name,salary,address from tbl_name1,tbl_name2 where tbl_name1.id=tbl_name2.id;
        help alter view
            alter
                [algorithm = {undefined | merge | temptable}]
                [definer = { user | current_user }]
                [sql security { definer | invoker }]
                view view_name [(column_list)]
                as select_statement
                [with [cascaded | local] check option]
            
6.更新視圖
    更新視圖是指通過視圖來插入、更新和刪除表中的數據,以為視圖是一個虛擬表,其中沒有數據。
    通過視圖更新時,都是轉換到基本表來更新,相當於更新表:
        update view_name set salary=8888 where name=‘名字‘;
        等價於
        update salary set salary=8888 where id=‘數字‘;
        視圖中雖然可以更新數據,但是有很多限制,一般情況下,最好將視圖作為查詢數據的虛擬表,而不要通過視圖更新數據

7.刪除視圖
    刪除視圖是指刪除數據庫中已存在的視圖,刪除視圖時,只能刪除視圖的定義,不會刪除數據。
        drop view if exists view_name;
        drop view view_name;
        help drop view
            drop view [if exists] view_name [, view_name] ... [restrict | cascade]

數據庫的數據類型、索引、鎖、事務和視圖