国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

mysql存儲引擎之------InnoDB

2024-07-24 12:40:02
字體:
來源:轉載
供稿:網友

InnoDB概述

InnoDB給MySQL提供了具有提交,回滾和崩潰恢復能力的事務安全(ACID兼容)存儲引擎。InnoDB鎖定在行級并且也在SELECT語句提供一個Oracle風格一致的非鎖定讀。這些特色增加了多用戶部署和性能。沒有在InnoDB中擴大鎖定的需要,因為在InnoDB中行級鎖定適合非常小的空間。InnoDB也支持FOREIGN KEY強制。在SQL查詢中,你可以自由地將InnoDB類型的表與其它MySQL的表的類型混合起來,甚至在同一個查詢中也可以混合。

InnoDB是為處理巨大數據量時的最大性能設計。它的CPU效率可能是任何其它基于磁盤的關系數據庫引擎所不能匹敵的。

InnoDB存儲引擎被完全與MySQL服務器整合,InnoDB存儲引擎為在主內存中緩存數據和索引而維持它自己的緩沖池。InnoDB存儲它的表&索引在一個表空間中,表空間可以包含數個文件(或原始磁盤分區)。這與MyISAM表不同,比如在MyISAM表中每個表被存在分離的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被限制為2GB的操作系統上。

InnoDB默認地被包含在MySQL二進制分發中。Windows Essentials installer使InnoDB成為Windows上MySQL的默認表。

InnoDB被用來在眾多需要高性能的大型數據庫站點上產生。著名的Internet新聞站點Slashdot.org運行在InnoDB上。Mytrix, Inc.在InnoDB上存儲超過1TB的數據,還有一些其它站點在InnoDB上處理平均每秒800次插入/更新的負荷。

InnoDB配置

InnoDB存儲引擎是默認地被允許的。如果你不想用InnoDB表,你可以添加skip-innodb選項到MySQL選項文件。

被InnoDB存儲引擎管理的兩個重要的基于磁盤的資源是InnoDB表空間數據文件和它的日志文件。

如果你指定無InnoDB配置選項,MySQL將在MySQL數據目錄下創建一個名為ibdata1的10MB大小的自動擴展數據文件,以及兩個名為ib_logfile0和ib_logfile1的5MB大小的日志文件。

注釋:InnoDB給MySQL提供具有提交,回滾和崩潰恢復能力的事務安全(ACID兼容)存儲引擎。如果擬運行的操作系統和硬件不能如廣告說的那樣運行,InnoDB就不能實現如上能力。許多操作系統或磁盤子系統可能為改善性能而延遲或記錄寫操作。在一些操作系統上,就是系統調用(fsync()) 也要等著,直到所有未寫入已被刷新文件的數據在被刷新到穩定內存之前可以確實返回了。因為這個,操作系統崩潰或掉電可能損壞當前提交的數據,或者在最壞的 情況,因為寫操作已被記錄了,甚至破壞了數據庫。如果數據完整性對你很重要,你應該在用任何程序于生產中之前做一些“pull-the-plug”測試。Mac OS X 10.3 及以后版本,InnoDB使用一個特別的fcntl()文件刷新方法。在Linux下,建議禁止回寫緩存。

在ATAPI硬盤上,一個類似hdparm -W0 /dev/hda命令可能起作用。小心某些驅動器或者磁盤控制器可能不能禁止回寫緩存。

注釋:要獲得好的性能,你應該如下面例子所討論那樣,明確提供InnoDB參數。自然地,你應該編輯設置來適合你的硬件和要求。

要建立InnoDB表空間文件,在my.cnf選項文件里的[mysqld]節里使用innodb_data_file_path選項。在Windows上,你可以替代地使用my.ini文件。innodb_data_file_path的值應該為一個或多個數據文件規格的列表。如果你命名一個以上的數據文件,用 分號(‘;’)分隔它們:

innodb_data_file_path=datafile_spec1[;datafile_spec2]...
例如:把明確創建的具有相同特征的表空間作為默認設置的設置操作如下:

[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend
這個設置配置一個可擴展大小的尺寸為10MB的單獨文件,名為ibdata1。沒有給出文件的位置,所以默認的是在MySQL的數據目錄內。

尺寸大小用M或者G后綴來指定說明單位是MB或者GB。

一個表空間,它在數據目錄里包含一個名為ibdata1的固定尺寸50MB的數據文件和一個名為ibdata2大小為50MB的自動擴展文件,其可以像這樣被配置:

[mysqld]
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
一個指定數據文件的完全后綴包括文件名,它的尺寸和數個可選屬性:

file_name:file_size[:autoextend[:max:max_file_size]]
autoextend屬性和后面跟著的屬性只可被用來對innodb_data_file_path行里最后一個數據文件。

如果你對最后的數據文件指定autoextend選項。如果數據文件耗盡了表空間中的自由空間,InnoDB就擴展數據文件。擴展的幅度是每次8MB。

InnoDB并不感知最大文件尺寸,所以要小心文件系統,在那上面最大的文件尺寸是2GB。要為一個自動擴展數據文件指定最大尺寸,請使用max屬性。下列配置允許ibdata1漲到極限的500MB:

[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend:max:500M

InnoDB默認地在MySQL數據目錄創建表空間文件。要明確指定一個位置,請使用innodb_data_home_dir選項。比如,要使用兩個名為ibdata1和ibdata2的文件,但是要把他們創建到/ibdata,像如下一樣配置InnoDB:

[mysqld]
innodb_data_home_dir = /ibdata
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend

注釋:InnoDB不創建目錄,所以在啟動服務器之前請確認/ibdata目錄的確存在。這對你配置的任何日志文件目錄來說也是真實的。使用Unix或DOS的mkdir命令來創建任何必需的目錄。

通過把innodb_data_home_dir的值原原本本地部署到數據文件名,并在需要的地方添加斜杠或反斜杠,InnoDB為每個數據文件形成目錄路徑。如果innodb_data_home_dir選項根本沒有在my.cnf中提到,默認值是“dot”目錄 ./,這意思是MySQL數據目錄。

處理InnoDB初始化問題

如果InnoDB在一個文件操作中打印一個操作系統錯誤,通常問題是如下中的一個:

?         你沒有創建一個InnoDB數據文件目錄或InnoDB日志目錄。

?         mysqld沒有訪問這些目錄的權限以創建文件。

?         mysqld不能恰當地讀取my.cnf或my.ini選項文件,因此不能看到你指定的選項。

?         磁盤已滿,或者超出磁盤配額。

?         你已經創建一個子目錄,它的名字與你指定的數據文件相同。

?         在innodb_data_home_dir或innodb_data_file_path有一個語法錯誤。

當InnoDB試著初始化它的表空間或日志文件之時,如果出錯了,你應該刪除InnoDB創建的所有文件。這意味著是所有ibdata文件和所有ib_logfiles文件。萬一你創建了一些InnoDB表,為這些表也從MySQL數據庫目錄刪除相應的.frm文件(如果你使用多重表空間的話,也刪除任何.ibd文件)。然后你可以試著再次創建InnoDB數據庫。最好是從命令提示符啟動MySQL服務器,以便你可以查看發生了什么。

AUTO_INCREMENT列在InnoDB里如何工作

如果你為一個表指定AUTO_INCREMENT列,在數據詞典里的InnoDB表句柄包含一個名為自動增長計數器的計數器,它被用在為該列賦新值。自動增長計數器僅被存儲在主內存中,而不是存在磁盤上。

InnoDB使用下列算法來為包含一個名為ai_col的AUTO_INCREMENT列的表T初始化自動增長計數器:服務器啟動之后,當一個用戶對表T做插入之時,InnoDB執行等價如下語句的動作:

SELECT MAX(ai_col) FROM T FOR UPDATE;
語句取回的值逐次加一,并被賦給列和自動增長計數器。如果表是空的,值1被賦予該列。如果自動增長計數器沒有被初始化,而且用戶調用為表T顯示輸出的SHOW TABLE STATUS語句,則計數器被初始化(但不是增加計數)并被存儲以供隨后的插入使用。注意,在這個初始化中,我們對表做一個正常的獨占讀鎖定,這個鎖持續到事務的結束。

InnoDB對為新創建表的初始化自動增長計數器允許同樣的過程。

注意,如果用戶在INSERT中為AUTO_INCREMENT列指定NULL或者0,InnoDB處理行,就仿佛值還沒有被指定,且為它生成一個新值。

自動增長計數器被初始化之后,如果用戶插入一個明確指定該列值的行,而且該值大于當前計數器值,則計數器被設置為指定列值。如果沒有明確指定一個值,InnoDB給計數器增加一,并且賦新值給該列。

當訪問自動增長計數器之時,InnoDB使用專用的表級的AUTO-INC鎖定,該鎖持續到當前SQL語句的結束而不是到業務的結束。引入了專用鎖釋放策略,來為對一個含AUTO_INCREMENT列的表的插入改善部署。兩個事務不能同時對同一表有AUTO-INC鎖定。

注意,如果你回滾從計數器獲得數的事務,你可能會在賦給AUTO_INCREMENT列的值的序列中發現間隙。

如果用戶給列賦一個賦值,或者,如果值大過可被以指定整數格式存儲的最大整數,自動增長機制的行為不被定義。

在CREATE TABLE和ALTER TABLE語句中,InnoDB支持AUTO_INCREMENT = n 表選項來設置計數器初始值或變更當前計數器值。因在本節早先討論的原因,這個選項的影響在服務器重啟后就無效了。

外鍵約束

InnoDB也支持外鍵約束。InnoDB中對外鍵約束定義的語法看起來如下:

[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name, ...)
    [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
    [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
外鍵定義服從下列情況:

?         所有tables必須是InnoDB型,它們不能是臨時表。

?         在引用表中,必須有一個索引,外鍵列以同樣的順序被列在其中作為第一列。這樣一個索引如果不存在,它必須在引用表里被自動創建。

?         在引用表中,必須有一個索引,被引用的列以同樣的順序被列在其中作為第一列。

?         不支持對外鍵列的索引前綴。這樣的后果之一是BLOB和TEXT列不被包括在一個外鍵中,這是因為對這些列的索引必須總是包含一個前綴長度。

?         如果CONSTRAINTsymbol被給出,它在數據庫里必須是唯一的。如果它沒有被給出,InnoDB自動創建這個名字。

InnoDB拒絕任何試著在子表創建一個外鍵值而不匹配在父表中的候選鍵值的INSERT或UPDATE操作。一個父表有一些匹配的行的子表,InnoDB對任何試圖更新或刪除該父表中候選鍵值的UPDATE或DELETE操作有所動作,這個動作取決于用FOREIGN KEY子句的ON UPDATE和ON DETETE子句指定的referential action。當用戶試圖從一個父表刪除或更新一行之時,且在子表中有一個或多個匹配的行,InnoDB根據要采取的動作有五個選擇:

?         CASCADE: 從父表刪除或更新且自動刪除或更新子表中匹配的行。ON DELETE CASCADE和ON UPDATE CASCADE都可用。在兩個表之間,你不應定義若干在父表或子表中的同一列采取動作的ON UPDATE CASCADE子句。

?         SET NULL: 從父表刪除或更新行,并設置子表中的外鍵列為NULL。如果外鍵列沒有指定NOT NULL限定詞,這就是唯一合法的。ON DELETE SET NULL和ON UPDATE SET NULL子句被支持。

?         NO ACTION: 在ANSI SQL-92標準中,NO ACTION意味這不采取動作,就是如果有一個相關的外鍵值在被參考的表里,刪除或更新主要鍵值的企圖不被允許進行(Gruber, 掌握SQL, 2000:181)。 InnoDB拒絕對父表的刪除或更新操作。

?         RESTRICT: 拒絕對父表的刪除或更新操作。NO ACTION和RESTRICT都一樣,刪除ON DELETE或ON UPDATE子句。(一些數據庫系統有延期檢查,并且NO ACTION是一個延期檢查。在MySQL中,外鍵約束是被立即檢查的,所以NO ACTION和RESTRICT是同樣的)。

?         SET DEFAULT: 這個動作被解析程序識別,但InnoDB拒絕包含ON DELETE SET DEFAULT或ON UPDATE SET DEFAULT子句的表定義。

當父表中的候選鍵被更新的時候,InnoDB支持同樣選擇。選擇CASCADE,在子表中的外鍵列被設置為父表中候選鍵的新值。以同樣的方式,如果在子表更新的列參考在另一個表中的外鍵,更新級聯。

注意,InnoDB支持外鍵在一個表內引用,在這些情況下,子表實際上意味這在表內附屬的記錄。

InnoDB需要對外鍵和被引用鍵的索引以便外鍵檢查可以快速進行且不需要一個表掃描。對外鍵的索引被自動創建。這是相對于一些老版本,在老版本中索引必須明確創建,否則外鍵約束的創建會失敗。

在InnoDB內,外鍵里和被引用列里相應的列必須有類似的內部數據類型,以便它們不需類型轉換就可被比較。整數類型的大小和符號必須相同。字符串類型的長度不需要相同。如果你指定一個SET NULL動作,請確認你沒有在子表中宣告該列為為NOT NULL。

如果MySQL從CREATE TABLE語句報告一個錯誤號1005,并且錯誤信息字符串指向errno 150,這意思是因為一個外鍵約束被不正確形成,表創建失敗。類似地,如果ALTER TABLE失敗,且它指向errno 150, 那意味著對已變更的表,外鍵定義會被不正確的形成。你可以使用SHOW INNODB STATUS來顯示一個對服務器上最近的InnoDB外鍵錯誤的詳細解釋。

注釋:InnoDB不對那些外鍵或包含NULL列的被引用鍵值檢查外鍵約束。

對SQL標準的背離:如果在父表內有數個行,其中有相同的被引用鍵值,然后InnoDB在外鍵檢查中采取動作,就仿佛其它有相同鍵值的父行不存在一樣。例如,如果你已定義一個RESTRICT類型的約束,并且有一個帶數個父行的子行,InnoDB不允許任何對這些父行的刪除。

居于對應外鍵約束的索引內的記錄,InnoDB通過深度優先選法施行級聯操作。

對SQL標準的背離: 如果ON UPDATE CASCADE或ON UPDATE SET NULL遞歸更新相同的表,之前在級聯過程中該表一被更新過,它就象RESTRICT一樣動作。這意味著你不能使用自引用ON UPDATE CASCADE或者ON UPDATE SET NULL操作。這將阻止級聯更新導致的無限循環。另一方面,一個自引用的ON DELETE SET NULL是有可能的,就像一個自引用ON DELETE CASCADE一樣。級聯操作不可以被嵌套超過15層深。

對SQL標準的背離: 類似一般的MySQL,在一個插入,刪除或更新許多行的SQL語句內,InnoDB逐行檢查UNIQUE和FOREIGN KEY約束。按照SQL的標準,默認的行為應被延遲檢查,即約束僅在整個SQL語句被處理之后才被檢查。直到InnoDB實現延遲的約束檢查之前,一些事情是不可能的,比如刪除一個通過外鍵參考到自身的記錄。

注釋:當前,觸發器不被級聯外鍵的動作激活。

一個通過單列外鍵聯系起父表和子表的簡單例子如下:

CREATE TABLE parent(id INT NOT NULL,
                    PRIMARY KEY (id)
) TYPE=INNODB;
CREATE TABLE child(id INT, parent_id INT,
                   INDEX par_ind (parent_id),
                   FOREIGN KEY (parent_id) REFERENCES parent(id)
                     ON DELETE CASCADE
) TYPE=INNODB;
如下是一個更復雜的例子,其中一個product_order表對其它兩個表有外鍵。一個外鍵引用一個product表中的雙列索引。另一個引用在customer表中的單行索引:

CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
                      price DECIMAL,
                      PRIMARY KEY(category, id)) TYPE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
                      PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
                      product_category INT NOT NULL,
                      product_id INT NOT NULL,
                      customer_id INT NOT NULL,
                      PRIMARY KEY(no),
                      INDEX (product_category, product_id),
                      FOREIGN KEY (product_category, product_id)
                        REFERENCES product(category, id)
                        ON UPDATE CASCADE ON DELETE RESTRICT,
                      INDEX (customer_id),
                      FOREIGN KEY (customer_id)
                        REFERENCES customer(id)) TYPE=INNODB;
InnoDB允許你用ALTER TABLE往一個表中添加一個新的外鍵約束:

ALTER TABLE yourtablename
    ADD [CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name, ...)
    [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
    [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
記住先創建需要的索引。你也可以用ALTER TABLE往一個表添加一個自引用外鍵約束。

InnoDB也支持使用ALTER TABLE來移除外鍵:

ALTER TABLE yourtablename DROP FOREIGN KEY fk_symbol;
當年創建一個外鍵之時,如果FOREIGN KEY子句包括一個CONSTRAINT名字,你可以引用那個名字來移除外鍵。另外,當外鍵被創建之時,fk_symbol值被InnoDB內部保證。當你想要移除一個外鍵之時,要找出標記,請使用SHOW CREATE TABLE語句。例子如下:

mysql> SHOW CREATE TABLE ibtest11cG
*************************** 1. row ***************************
       Table: ibtest11c
Create Table: CREATE TABLE `ibtest11c` (
  `A` int(11) NOT NULL auto_increment,
  `D` int(11) NOT NULL default '0',
  `B` varchar(200) NOT NULL default '',
  `C` varchar(175) default NULL,
  PRIMARY KEY  (`A`,`D`,`B`),
  KEY `B` (`B`,`C`),
  KEY `C` (`C`),
  CONSTRAINT `0_38775` FOREIGN KEY (`A`, `D`)
REFERENCES `ibtest11a` (`A`, `D`)
ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `0_38776` FOREIGN KEY (`B`, `C`)
REFERENCES `ibtest11a` (`B`, `C`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB CHARSET=latin1
1 row in set (0.01 sec)
 
mysql> ALTER TABLE ibtest11c DROP FOREIGN KEY 0_38775;
InnoDB解析程序允許你在FOREIGN KEY ... REFERENCES ...子句中用`(backticks)把表和列名名字圍起來。InnoDB解析程序也考慮到lower_case_table_names系統變量的設置。

InnoDB返回一個表的外鍵定義作為SHOW CREATE TABLE語句輸出的一部分:

SHOW CREATE TABLE tbl_name;
從這個版本起,mysqldump也將表的正確定義生成到轉儲文件中,且并不忘記外鍵。

你可以如下對一個表顯示外鍵約束:

SHOW TABLE STATUS FROM db_name LIKE 'tbl_name';
外鍵約束被列在輸出的Comment列。

當執行外鍵檢查之時,InnoDB對它照看著的子或父記錄設置共享的行級鎖。InnoDB立即檢查外鍵約束,檢查不對事務提交延遲。

要使得對有外鍵關系的表重新載入轉儲文件變得更容易,mysqldump自動在轉儲輸出中包括一個語句設置FOREIGN_KEY_CHECKS為0。這避免在轉儲被重新裝載之時,與不得不被以特別順序重新裝載的表相關的問題。也可以手動設置這個變量:

mysql> SET FOREIGN_KEY_CHECKS = 0;
mysql> SOURCE dump_file_name;
mysql> SET FOREIGN_KEY_CHECKS = 1;
如果轉儲文件包含對外鍵是不正確順序的表,這就以任何順序導入該表。這樣也加快導入操作。設置FOREIGN_KEY_CHECKS為0,對于在LOAD DATA和ALTER TABLE操作中忽略外鍵限制也是非常有用的。

InnoDB不允許你刪除一個被FOREIGN KEY表約束引用的表,除非你做設置SET FOREIGN_KEY_CHECKS=0。當你移除一個表的時候,在它的創建語句里定義的約束也被移除。

如果你重新創建一個被移除的表,它必須有一個遵從于也引用它的外鍵約束的定義。它必須有正確的列名和類型,并且如前所述,它必須對被引用的鍵有索引。如果這些不被滿足,MySQL返回錯誤號1005 并在錯誤信息字符串中指向errno 150。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 霞浦县| 雷山县| 武穴市| 嘉黎县| 邹平县| 洛阳市| 饶河县| 会同县| 昭平县| 睢宁县| 涞水县| 广河县| 云龙县| 佳木斯市| 卢龙县| 垦利县| 南皮县| 北京市| 晋江市| 吉隆县| 宁安市| 潞城市| 富裕县| 都匀市| 磐安县| 昂仁县| 金阳县| 泊头市| 手机| 子长县| 岚皋县| 荥阳市| 红安县| 梁山县| 东兰县| 铅山县| 平顶山市| 宜兴市| 潞城市| 建平县| 辽宁省|