《MySQL技術內幕:InnoDB存儲引擎》讀書筆記四-表(2)

4、表(2數據庫

1、約束安全

InnoDB提供瞭如下幾種約束:數據結構

l  Primary Key函數

l  Unique Key測試

l  Foreign Key優化

l  Defaultorm

l  NOT NULL索引

2、約束和索引的關係事務

*當你建立了一個惟一索引,就建立了一個惟一約束字符串

* 約束是一個邏輯的概念,用來保證數據的完整性

* 而索引是一個數據結構,有邏輯上的概念,在數據庫中更是一個物理存儲的方式

 

3ENUMSET約束

4、觸發器和約束

觸發器做用:在INSERT、DELETE和UPDATE命令以前或以後自動調用SQL命令或者存儲過程。

建立命令:

         CREATE

         [DEFINER = { user | CURRENT_USER }]

         TRIGGER trigger_name  DEFORE|AFTER  INSERT|UPDATE|DELETE

         ON tbl_name FOR EACH ROW trigger_stmt

 

5、外鍵

建立命令:

         [ CONSTRAINT [ symbol ] ] FOREIGN KEY

         [ index_name ] (index_col_name, … )

         REFERENCES tbl_name (index_col_name, …)

         [ ON DELETE reference_option ]

         [ ON UPDATE reference option ]

         reference_option:

         RESTRICT  | CASCADE | SET NULL | NOT ACTION

其中CASCADE: 當父表發生DELETE或UPDATE操做時,相應的子表中的數據也被DELETE或UPDATE

SET NULL: 當父表發生DELETE或UPDATE操做時,相應的子表中的數據被更新爲NULL值。固然,子表中相對應的列必須容許NULL值

NO ACTION:當。。。,拋出錯誤,不容許這種操做發生

RESTRICT:當。。。,拋出錯誤,不容許這種操做發生。若定義外鍵沒有指定ON DELETE或ON UPDATE,這就是默認操做

測試:

首先創建一張表,並向裏面插入幾條數據:

①:測試CASCADE

創建子表,設置ON DELECT CASCADE和ON UPDATE CASCADE約束

這時向表child插入幾條數據

1)插入父表中不存在的id,出現以下錯誤

2)插入父表存在的id。

3)這時,將父表中的id爲1的id更新爲6:

查看子表發現parent_id從1變成了6:

4)刪除父表中id爲3的行,同時能夠看到子表中parent_id爲3的行也被刪除。

 

六、視圖

做用:被用作一個抽象裝置,特別是對於一些應用程序,程序自己不須要關心基表的結構,只須要按照視圖定義來獲取數據或者更新數據,所以,視圖同時在必定程度上起到安全層的做用。

 

建立視圖:

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]

 

其中WITH CHECK OPTION表示:對於可更新的視圖,更新的值是否須要檢查。

 

①:想要查看當前數據庫下的基表:

SELECT * FROM information_schema.TABLES where table_type='BASE TABLE' and table_schema=database();

②:想要查看視圖的一些元數據,則能夠訪問information_schema表下的VIEWS表:

SELECT * FROM information_schema.VIEWS where table_schema=database();

6、分區表

水平分區:指同一表中不一樣行的記錄分配到不一樣的物理文件中

垂直分區:將同一表中不一樣的列分配到不一樣的物理文件中

 

MySQL不支持垂直分區,只支持水平分區。MySQL數據庫中的分區是局部分區索引,一個分區中既存放了數據由存放了索引。

經過命令SHOW PLUGINS \G可查看是否啓用分區功能。

 

分區主要用於高可用性,利於數據庫管理。

MySQL數據庫支持如下幾種分區:

RANGE分區:行數據基於屬於一個給定連續區間的列值放入分區;

LIST分區:和RANGE分區相似,只是LIST分區面向的是離散的值;

HASH分區:根據用戶自定義的表達式的返回值來進行分區;

KEY分區:根據MySQL數據庫提供的哈希函數來進行分區。

 

分區限制要求:

--不論建立何種類型的分區,若是表中存在主鍵或者惟一索引時,分區列必須是惟一索引的一個組成部分;

-- 惟一索引能夠容許是NULL值,而且分區列只要是惟一索引的一個組成部分;

-- 當建表時沒有指定主鍵,惟一索引時,能夠指定任何一個列爲分區列。

 

 

① RANGE分區:

建立RANGE分區:

啓用分區後,表再也不是一個ibd文件組成了,而是由創建分區時的各個分區ibd文件組成。

當插入分區範圍外的數據時,出現錯誤:

對於上圖這種狀況,可添加一個MAXVALUE分區。

 

l  可使用select * from information_schema.PARTITIONS where table_schema=database()查看每一個分區具體信息。

l  對於RANGE分區的查詢,優化器只能對YEAR(),TO_DAYS(),TO_SECONDS()和UNIX_TIMESTAMP()這類函數進行優化選擇,對自定義的表達式形式會進行全表搜索。

 

② LIST分區

和RANGE分區相似,只是分區列的值是離散的,而非連續的。

l  若是插入的值不在分區定義中,一樣會報錯

l  在使用INSERT插入多個行數據時的過程當中遇到分區未定義的值時,因爲InnoDB支持事務,因此會把這多條插入看做一次事務,不會有任何數據插入,MyISAM則不一樣,在錯誤以前的數據都插入

HASH分區

HASH分區的目的是將數據均勻地分佈到預先定義的各個分區中,保證各分區的數據數量大體都是相同的。

使用時須要在CREATE TABLE語句上添加一個「PARTITION BY HASH (expr)」,其中expr是一個返回一個整數的表達式。此外還要在後面添加一個「PARTITIONS num」,其中num爲分區數目。

 

以下圖以YEAR分區,共分紅4個分區,則在保存記錄時,分區使用以下表達式:

YEAR(year) MOD 4

④ KEY分區

與HASH分區類似,不一樣的是,HASH分區使用用戶自定義的函數進行分區,而KEY分區使用MySQL數據庫提供的函數進行分區。

⑤ COLUMNS分區

前面介紹的HASH、LIST、RANGE和KEY這四種分區中,分區條件必須是整數,若不是整數,則需化成整數,如YEAR(), TO_DAYS()等。MySQL5.5開始支持COLUMNS分區,分區根據直接比較可得,不須要轉化爲整數。其次,RANGE COLUMNS可對多個列的值進行分區。

COLUMNS支持如下類型:

         1)整數類型:INT、SMALLINT、TINYINT、BIGINT。

         2)日期類型:DATE、DATETIME

         3)字符串類型:CHAR、VARCHAR、BINARY和VARBINARY

子分區:

在分區的基礎上再進行分區。

須要注意的問題:

l  每一個子分區的數量必須相同

l  若是在一個分區表上的任何分區上使用SUBPARTITION來明肯定義任何子分區,那麼就必須定義全部的子分區。

l  每一個SUBPARTITION句必須包括子分區的一個名稱

l  在每一個分區內,子分區的名稱必須是惟一的。

相關文章
相關標籤/搜索