mysql— SQL語法之數據定義語句DDL

1.?ALTER DATABASE語法

ALTER?{DATABASE?|?SCHEMA}?[db_name]????alter_specification?[,?alter_specification]?...alter_specification:  ????[DEFAULT]?CHARACTER?SET?charset_name  ??|?[DEFAULT]?COLLATE?collation_name

alter database用于更改數據庫的全局特性。這些特性儲存在數據庫目錄中的db.opt文件中。要使用alter database,您需要獲得數據庫alter權限。

CHARACTER SET子句用于更改默認的數據庫字符集。COLLATE子句用于更改默認的數據庫整序。

數據庫名稱可以忽略,此時,語句對應于默認數據庫。也可以使用ALTER SCHEMA。

2.?ALTER TABLE語法

ALTER?[IGNORE]?TABLE?tbl_name  ????alter_specification?[,?alter_specification]?...alter_specification:  ????ADD?[COLUMN]?column_definition?[FIRST?|?AFTER?col_name?]  ??|?ADD?[COLUMN]?(column_definition,...)  ??|?ADD?INDEX?[index_name]?[index_type]?(index_col_name,...)  ??|?ADD?[CONSTRAINT?[symbol]]  ????????PRIMARY?KEY?[index_type]?(index_col_name,...)  ??|?ADD?[CONSTRAINT?[symbol]]  ????????UNIQUE?[index_name]?[index_type]?(index_col_name,...)  ??|?ADD?[FULLTEXT|SPATIAL]?[index_name]?(index_col_name,...)  ??|?ADD?[CONSTRAINT?[symbol]]  ????????FOREIGN?KEY?[index_name]?(index_col_name,...)  ????????[reference_definition]  ??|?ALTER?[COLUMN]?col_name?{SET?DEFAULT?literal?|?DROP?DEFAULT}  ??|?CHANGE?[COLUMN]?old_col_name?column_definition  ????????[FIRST|AFTER?col_name]  ??|?MODIFY?[COLUMN]?column_definition?[FIRST?|?AFTER?col_name]  ??|?DROP?[COLUMN]?col_name  ??|?DROP?PRIMARY?KEY  ??|?DROP?INDEX?index_name  ??|?DROP?FOREIGN?KEY?fk_symbol  ??|?DISABLE?KEYS  ??|?ENABLE?KEYS  ??|?RENAME?[TO]?new_tbl_name  ??|?ORDER?BY?col_name  ??|?CONVERT?TO?CHARACTER?SET?charset_name?[COLLATE?collation_name]  ??|?[DEFAULT]?CHARACTER?SET?charset_name?[COLLATE?collation_name]  ??|?DISCARD?TABLESPACE  ??|?IMPORT?TABLESPACE  ??|?table_options  ??|?partition_options  ??|?ADD?PARTITION?partition_definition  ??|?DROP?PARTITION?partition_names  ??|?COALESCE?PARTITION?number  ??|?REORGANIZE?PARTITION?partition_names?INTO?(partition_definitions)  ??|?ANALYZE?PARTITION?partition_names  ??|?CHECK?PARTITION?partition_names  ??|?OPTIMIZE?PARTITION?partition_names  ??|?REBUILD?PARTITION?partition_names  ??|?REPAIR?PARTITION?partition_names

ALTER TABLE用于更改原有表的結構。例如,您可以增加或刪減列,創建或取消索引,更改原有列的類型,或重新命名列或表。您還可以更改表的評注和表的類型。

允許進行的變更中,許多子句的語法與CREATE TABLE中的子句的語法相近。其中包括table_options修改,選項有ENGINE, AUTO_INCREMENT和AVG_ROW_LENGTH等。

存儲引擎不支持有些操作,如果進行這些操作,會出現警告。使用SHOW WARNINGS可以顯示出這些警告。

如果您使用ALTER TABLE更改列規約,但是DESCRIBE?tbl_name提示您列規約并沒有改變,則可能是因為mysql忽略了您所做的更改。例如,如果您試圖把VARCHAR列更改為CHAR列,此時,如果表包含其它長度可變的列,則MySQL仍會使用VARCHAR。

ALTER TABLE運行時會對原表進行臨時復制,在副本上進行更改,然后刪除原表,再對新表進行重命名。在執行ALTER TABLE時,其它用戶可以閱讀原表,但是對表的更新和修改的操作將被延遲,直到新表生成為止。新表生成后,這些更新和修改信息會自動轉移到新表上。

注意,如果您在執行ALTER TABLE時使用除了RENAME以外的選項,則MySQL會創建一個臨時表。即使數據并不需要進行復制(例如當您更改列的名稱時),MySQL也會這么操作。對于MyISAM表,您可以通過把myisam_sort_buffer_size系統變量設置到一個較高的值,來加快重新創建索引(該操作是變更過程中速度最慢的一部分)的速度。

·?要使用ALTER TABLE,您需要獲得表的ALTER, INSERT和CREATE權限。

·?IGNORE是MySQL相對于標準SQL的擴展。如果在新表中有重復關鍵字,或者當STRICT模式啟動后出現警告,則使用IGNORE控制ALTER TABLE的運行。如果沒有指定IGNORE,當重復關鍵字錯誤發生時,復制操作被放棄,返回前一步驟。如果指定了IGNORE,則對于有重復關鍵字的行,只使用第一行,其它有沖突的行被刪除。并且,對錯誤值進行修正,使之盡量接近正確值。

·?您可以在一個ALTER TABLE語句里寫入多個ADD, ALTER, DROP和CHANGE子句,中間用逗號分開。這是MySQL相對于標準SQL的擴展。在標準SQL中,每個ALTER TABLE語句中每個子句只允許使用一次。例如,在一個語句中取消多個列:

mysql>?ALTER?TABLE?t2?DROP?COLUMN?c,?DROP?COLUMN?d;

·?CHANGE?col_name,?DROP?col_name和DROP INDEX是MySQL相對于標準SQL的擴展。

·?MODIFY是Oracle對ALTER TABLE的擴展。

·?COLUMN只是自選項目,可以忽略。

·?如果您使用ALTER TABLE?tbl_name?RENAME TO?new_tbl_name并且沒有其它選項,則MySQL只對與tabletbl_name相對應的文件進行重命名。不需要創建一個臨時表。(您也可以使用RENAME TABLE語句對表進行重命名。)

·?column_definition子句使用與CREATE TABLE中的ADD和CHANGE子句相同的語法。注意,此語法包括列名稱,而不只是列類型。

·?您可以使用CHANGE?old_col_name?column_definition子句對列進行重命名。重命名時,需給定舊的和新的列名稱和列當前的類型。例如:要把一個INTEGER列的名稱從a變更到b,您需要如下操作:

mysql>?ALTER?TABLE?t1?CHANGE?a?b?INTEGER;

如果您想要更改列的類型而不是名稱,?CHANGE語法仍然要求舊的和新的列名稱,即使舊的和新的列名稱是一樣的。例如:

mysql>?ALTER?TABLE?t1?CHANGE?b?b?BIGINT?NOT?NULL;

您也可以使用MODIFY來改變列的類型,此時不需要重命名:

mysql>?ALTER?TABLE?t1?MODIFY?b?BIGINT?NOT?NULL;

·?如果您使用CHANGE或MODITY縮短列長時,列中存在有索引,并且縮短后的列長小于索引長度,則MySQL會自動縮短索引的長度。

·?當您使用CHANGE或MODIFY更改列的類型時,MySQL會盡量把原有的列值轉化為新的類型。

·?您可以使用FIRST或AFTER?col_name在一個表行中的某個特定位置添加列。默認把列添加到最后。您也可以在CHANGE或MODIFY語句中使用FIRST和AFTER。

·?AFTER COLUMN用于指定列的新默認值,或刪除舊的默認值。如果舊的默認值被刪除同時列值為NULL,則新的默認值為NULL。如果列值不能為NULL,MySQL會指定一個默認值。

·?DROP INDEX用于取消索引。這是MySQL相對于標準SQL的擴展。

·?如果列從表中被取消了,則這些列也從相應的索引中被取消。如果組成一個索引的所有列均被取消,則該索引也被取消。

·?如果一個表只包含一列,則此列不能被取消。如果您想要取消表,應使用DROP TABLE。

·?DROP PRIMAY DEY用于取消主索引。注釋:在MySQL較早的版本中,如果沒有主索引,則DROP PRIMARY KEY會取消表中的第一個UNIQUE索引。在MySQL 5.1中不會出現這種情況。如果在MySQL 5.1中對沒有主鍵的表使用DROP PRIMARY KEY,則會出現錯誤信息。

如果您向表中添加UNIQUE KEY或PRIMARY KEY,則UNIQUE KEY或PRIMARY KEY會被儲存在非唯一索引之前,這樣MySQL就可以盡早地檢查出重復關鍵字。

·?ORDER BY用于在創建新表時,讓各行按一定的順序排列。注意,在插入和刪除后,表不會仍保持此順序。當您知道多數情況下您會按照特定的順序查詢各行時,可以使用這個選項;在對表進行了大的改動后,通過使用此選項,您可以提高查詢效率。在有些情況下,如果表按列排序,對于MySQL來說,排序可能會更簡單。

·?如果您對一個MyISAM表使用ALTER TABLE,則所有非唯一索引會被創建到一個單獨的批里(和REPAIR TABLE相同)。當您有許多索引時,這樣做可以使ALTER TABLE的速度更快。

這項功能可以明確激活。ALTER TABLE…DISABLE KEYS讓MySQL停止更新MyISAM表中的非唯一索引。然后使用ALTER TABLE … ENABLE KEYS重新創建丟失的索引。進行此操作時,MySQL采用一種特殊的算法,比一個接一個地插入關鍵字要快很多。因此,在進行成批插入操作前先使關鍵字禁用可以大大地加快速度。使用ALTER TABLE … DISABLE KEYS除了需要獲得以前提到的權限以外,還需要獲得INDEX權限。

·?Innodb存儲引擎支持FOREIGN KEY和REFERENCES子句。Innodb存儲引擎執行ADD [CONSTRAINT [symbol]] FOREIGN KEY (…) REFERENCES … (…)。對于其它存儲引擎,這些子句會被分析,但是會被忽略。對于所有的存儲引擎,CHECK子句會被分析,但是會被忽略。接受這些子句但又忽略子句的原因是為了提高兼容性,以便更容易地從其它SQL服務器中導入代碼,并運行應用程序,創建帶參考數據的表。

·?InnoDB支持使用ALTER TABLE來取消外鍵:

ALTER?TABLE?yourtablename?DROP?FOREIGN?KEY?fk_symbol;

·?ALTER TABLE忽略DATA DIRECTORY和INDEX DIRECTORY表選項。

·?如果您想要把表默認的字符集和所有字符列(CHAR, VARCHAR, TEXT)改為新的字符集,應使用如下語句:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

警告:前面的操作轉換了字符集之間的列類型。如果您有一列使用一種字符集(如latin1),但是存儲的值實際上使用了其它的字符集(如utf8),這種情況不是您想要的。此時,您必須對這樣的列進行以下操作。

ALTER?TABLE?t1?CHANGE?c1?c1?BLOB;  ALTER?TABLE?t1?CHANGE?c1?c1?TEXT?CHARACTER?SET?utf8;

這種方法能夠實現此功能的原因是,當您轉換到BLOB列或從BLOB列轉換過來時,并沒有發生轉換。

如果您指定CONVERT TO CHARACTER SET為二進制,則TEXT列被轉換到相應的二進制字符串類型(BINARY, VARBINARY, BLOB)。這意味著這些列將不再有字符集,接下來的CONVERT TO操作也將不適用于這些列。

要僅僅改變一個表的默認字符集,應使用此語句:

ALTER?TABLE?tbl_name?DEFAULT?CHARACTER?SET?charset_name;

詞語DEFAULT為自選項。如果您在向表中添加一個新列時(例如,使用ALTER TABLE…ADD column)沒有指定字符集,則此時使用的字符集為默認字符集。

警告:ALTER TABLE…DEFAULT CHARACTER SET和ALTER TABLE…CHARACTER SET是等價的,只用于更改默認的表字符集。

· 如果InnoDB表在創建時,使用了.ibd文件中的自己的表空間,則這樣的文件可以被刪除和導入。使用此語句刪除.ibd文件:

ALTER?TABLE?tbl_name?DISCARD?TABLESPACE;

此語句用于刪除當前的.ibd文件,所以應首先確認您有一個備份。如果在表空間被刪除后嘗試打開表格,則會出現錯誤。

要把備份的.ibd文件還原到表中,需把此文件復制到數據庫目錄中,然后書寫此語句:

ALTER?TABLE?tbl_name?IMPORT?TABLESPACE;

·?使用mysql_info()?C API函數,您可以了解有多少記錄已被復制,以及(當使用IGNORE時)有多少記錄由于重復關鍵字的原因已被刪除。

·?ALTER TABLE也可以用于對帶分區的表進行重新分區,功能包括添加、取消、合并和拆分各分區,還可以用于進行分區維護。

對帶分區的表使用partition_options子句和ALTER TABLE可以對表進行重新分區,使用時依據partition_options定義的分區方法。本子句以PARTITION BY為開頭,然后使用與用于CREATE TABLE的partition_options子句一樣的語法和規則。注釋:MySQL 5.1服務器目前接受此語法,但是不實際執行;等MySQL 5.1開發出來后,將執行此語法。

用于ALTER TABLE ADD PARTITION的partition_definition子句支持用于CREATE TABLE語句的partition_definition子句的同樣名稱的選項。例如,假設您有一個按照以下方式創建的帶分區的表:

CREATE?TABLE?t1?(  ????id?INT,  ????year_col?INT  )  PARTITION?BY?RANGE?(year_col)?(  ????PARTITION?p0?VALUES?LESS?THAN?(1991),  ????PARTITION?p1?VALUES?LESS?THAN?(1995),  ????PARTITION?p2?VALUES?LESS?THAN?(1999)  );

您可以在表中增加一個新的分區p3,該分區用于儲存小于2002的值。添加方法如下:

ALTER?TABLE?t1?ADD?PARTITION?p3?VALUES?LESS?THAN?(2002);

注釋:您不能使用ALTER TABLE向一個沒有進行分區的表添加分區。

DROP PARTITION用于取消一個或多個RANGE或LIST分區。此命令不能用于HASH或KEY?分區;用于這兩個分區時,應使用COALESCE PARTITION(見后)。如果被取消的分區其名稱列于partition_names清單中,則儲存在此分區中的數據也被取消。例如,如果以前已定義的表t1,您可以采用如下方法取消名稱為p0和p1的分區:

ALTER?TABLE?DROP?PARTITION?p0,?p1;

ADD PARTITION和DROP PARTITION目前不支持IF [NOT] EXISTS。也不可能對一個分區或一個已分區的表進行重命名。如果您希望對一個分區進行重命名,您必須取消分區,再重新建立;如果您希望對一個已分區的表進行重新命名,您必須取消所有分區,然后對表進行重命名,再添加被取消的分區。

COALESCE PARTITION可以用于使用HASH或KEY進行分區的表,以便使用number來減少分區的數目。例如,假設您使用下列方法創建了表t2:

CREATE?TABLE?t2?(  ????name?VARCHAR?(30),  ????started?DATE  )  PARTITION?BY?HASH(YEAR(started))  PARTITIONS?(6);

您可以使用以下命令,把t2使用的分區的數目由6個減少到4個:

ALTER?TABLE?t2?COALESCE?PARTITION?2;

包含在最后一個number分區中的數據將被合并到其余的分區中。在此情況下,分區4和分區5將被合并到前4個分區中(編號為0、1、2和3的分區)。

如果要更改部分分區,但不更改所有的分區,您可以使用REORGANIZE PARTITION。這個命令有多種使用方法:

o?把多個分區合并為一個分區。通過把多個分區的名稱列入partition_names清單,并為partition_definition提供一個單一的定義,可以實現這個功能。

o?把一個原有的分區拆分為多個分區。通過為partition_names命名一個分區,并提供多個partition_definitions,可以實現這個功能。

o?更改使用VALUES LESS THAN定義的分區子集的范圍或更改使用VALUES IN定義的分區子集的值清單。

注釋:對于沒有明確命名的分區,MySQL會自動提供默認名稱p0, p1, p2等。

·?????????多個附加子句用于提供分區維護和修補功能。這些功能與用于非分區表的功能類似。這些功能由CHECK TABLE和REPAIR TABLE等命令(這些命令不支持用于分區表)執行。這些子句包括ANALYZE PARTITION,?CHECK PARTITION,?OPTIMIZE PARTITION,?REBUILD PARTITION和REPAIR PARTITION.每個選項均為一個partition_names子句,包括一個或多個分區名稱。需要更改的表中必須已存在這些分區。多個分區名稱用逗號分隔。

以下例子展示了ALTER TABLE的使用。首先展示表t1。表t1采用如下方法創建:

mysql>?CREATE?TABLE?t1?(a?INTEGER,b?CHAR(10));

把表t1重新命名為t2:

mysql>?ALTER?TABLE?t1?RENAME?t2;

把列a從INTERGER更改為TINYINT NOT NULL(名稱保持不變),并把列b從CHAR(10)更改為CHAR(20),同時把列b重新命名為列c:

mysql>?ALTER?TABLE?t2?MODIFY?a?TINYINT?NOT?NULL,?CHANGE?b?c?CHAR(20);

添加一個新的TIMESTAMP列,名稱為d:

mysql>?ALTER?TABLE?t2?ADD?d?TIMESTAMP;

在列d和列a中添加索引:

mysql>?ALTER?TABLE?t2?ADD?INDEX?(d),?ADD?INDEX?(a);

刪除列c:

mysql>?ALTER?TABLE?t2?DROP?COLUMN?c;

添加一個新的AUTO_INCREMENT整數列,名稱為c:

mysql>?ALTER?TABLE?t2?ADD?c?INT?UNSIGNED?NOT?NULL?AUTO_INCREMENT,????->?ADD?PRIMARY?KEY?(c);

注意我們為c編制了索引(作為PRIMARY KEY),因為AUTO_INCREMENT列必須編制索引。同時我們定義c為NOT NULL,因為主鍵列不能為NULL。

當您添加一個AUTO_INCREMENT列時,列值被自動地按序號填入。對于MyISAM表,您可以在ALTER TABLE之前執行SET INSERT_ID=value來設置第一個序號,也可以使用AUTO_INCREMENT=value表選項來設置。

如果值大于AUTO_INCREMENT列中的最大值,則您可以使用用于InnoDB表的ALTER TALBE…AUTO_INCREMENT=value表選項,來為新行設置序號。如果值小于列中當前的最大值,不會出現錯誤信息,當前的序列值也不改變。

使用MyISAM表時,如果您不更改AUTO_INCREMENT列,則序列號不受影響。如果您取消一個AUTO_INCREMENT列,然后添加另一個AUTO_INCREMENT列,則序號重新排列,從1開始。

3.?CREATE DATABASE語法

CREATE?{DATABASE?|?SCHEMA}?[IF?NOT?EXISTS]?db_name  ????[create_specification?[,?create_specification]?...]  create_specification:  ????[DEFAULT]?CHARACTER?SET?charset_name  ??|?[DEFAULT]?COLLATE?collation_name

CREATE DATABASE用于創建數據庫,并進行命名。如果要使用CREATE DATABASE,您需要獲得數據庫CREATE權限。

如果存在數據庫,并且您沒有指定IF NOT EXISTS,則會出現錯誤。

create_specification選項用于指定數據庫的特性。數據庫特性儲存在數據庫目錄中的db.opt文件中。CHARACTER SET子句用于指定默認的數據庫字符集。COLLATE子句用于指定默認的數據庫整序。

有些目錄包含文件,這些文件與數據庫中的表對應。MySQL中的數據庫的執行方法與這些目錄的執行方法相同。因為當數據庫剛剛被創建時,在數據庫中沒有表,所以CREATE DATABASE只創建一個目錄。這個目錄位于MySQL數據目錄和db.opt文件之下。

如果您手動在數據目錄之下創建一個目錄(例如,使用mkdir),則服務器會認為這是一個數據庫目錄,并在SHOW DATABASES的輸出中顯示出來。

也可以使用CREATE SCHEMA。

您還可以使用mysqladmin程序創建數據庫。

4.?CREATE INDEX語法

CREATE?[UNIQUE|FULLTEXT|SPATIAL]?INDEX?index_name  ????[USING?index_type]  ???ON?tbl_name?(index_col_name,...)  index_col_name:  ????col_name?[(length)]?[ASC?|?DESC]

CREATE INDEX被映射到一個ALTER TABLE語句上,用于創建索引。

通常,當使用CREATE TABLE創建表時,也同時在表中創建了所有的索引。CREATE INDEX允許您向已有的表中添加索引。

格式為(col1, col2,…)的一個列清單創建出一個多列索引。通過串接給定列中的值,確定索引值的格式。

對于CHAR和VARCHAR列,只用一列的一部分就可創建索引。創建索引時,使用col_name(length)語法,對前綴編制索引。前綴包括每列值的前length個字符。BLOB和TEXT列也可以編制索引,但是必須給出前綴長度。

此處展示的語句用于創建一個索引,索引使用列名稱的前10個字符。

CREATE?INDEX?part_of_name?ON?customer?(name(10));

因為多數名稱的前10個字符通常不同,所以此索引不會比使用列的全名創建的索引速度慢很多。另外,使用列的一部分創建索引可以使索引文件大大減小,從而節省了大量的磁盤空間,有可能提高INSERT操作的速度。

前綴最長為255字節。對于MyISAM和InnoDB表,前綴最長為1000字節。注意前綴的限長以字節計,而CREATE INDEX語句中的前綴長度指的是字符的數目。對于使用多字節字符集的列,在指定列的前綴長度時,要考慮這一點。

在MySQL 5.1中:

·?只有當您正在使用MyISAM, InnoDB或BDB表類型時,您可以向有NULL值的列中添加索引。

·?只有當您正在使用MyISAM, BDB或InnoDB表類型時,您可以向BLOB或TEXT列中添加索引。

一個index_col_name規約可以以ASC或DESC為結尾。這些關鍵詞將來可以擴展,用于指定遞增或遞減索引值存儲。目前,這些關鍵詞被分析,但是被忽略;索引值均以遞增順序存儲。

部分儲存引擎允許在創建索引時指定索引類型。index_type指定語句的語法是USING?type_name。不同的儲存引擎所支持的type_name值已顯示在下表中。如果列有多個索引類型,當沒有指定index_type時,第一個類型是默認值。

存儲引擎 ? ?允許的索引類型 ? ?

MyISAM ? ?BTREE ? ?

InnoDB ? ?BTREE ? ?

MEMORY/HEAP ? ?HASH,?BTREE ? ?

示例:

CREATE?TABLE?lookup?(id?INT)?ENGINE?=?MEMORY;  CREATE?INDEX?id_index?USING?BTREE?ON?lookup?(id);

TYPE?type_name可以作為USING?type_name的同義詞,用于指定索引類型。但是,USING是首選的格式。另外,在索引規約語法中,位于索引類型前面的索引名稱不能使用TYPE。這是因為,與USING不同,TYPE不是保留詞,因此會被認為是一個索引名稱。

如果您指定的索引類型在給定的儲存引擎中不合法,但是有其它的索引類型適合引擎使用,并且不會影響查詢功能,則引擎應使用此類型。

FULLTEXT索引只能對CHAR, VARCHAR和TEXT列編制索引,并且只能在MyISAM表中編制。

SPATIAL索引只能對空間列編制索引,并且只能在MyISAM表中編制。

5.?CREATE TABLE語法

5.1. 沉寂的列規格變更

CREATE?[TEMPORARY]?TABLE?[IF?NOT?EXISTS]?tbl_name  ????[(create_definition,...)]  ????[table_options]?[select_statement]

或:

CREATE?[TEMPORARY]?TABLE?[IF?NOT?EXISTS]?tbl_name  ????[(]?LIKE?old_tbl_name?[)];  create_definition:  ????column_definition  ??|?[CONSTRAINT?[symbol]]?PRIMARY?KEY?[index_type]?(index_col_name,...)  ??|?KEY?[index_name]?[index_type]?(index_col_name,...)  ??|?INDEX?[index_name]?[index_type]?(index_col_name,...)  ??|?[CONSTRAINT?[symbol]]?UNIQUE?[INDEX]  ????????[index_name]?[index_type]?(index_col_name,...)  ??|?[FULLTEXT|SPATIAL]?[INDEX]?[index_name]?(index_col_name,...)  ??|?[CONSTRAINT?[symbol]]?FOREIGN?KEY  ????????[index_name]?(index_col_name,...)?[reference_definition]  ??|?CHECK?(expr)  column_definition:  ????col_name?type?[NOT?NULL?|?NULL]?[DEFAULT?default_value]  ????????[AUTO_INCREMENT]?[UNIQUE?[KEY]?|?[PRIMARY]?KEY]  ????????[COMMENT?'string']?[reference_definition]  type:  ????TINYINT[(length)]?[UNSIGNED]?[ZEROFILL]  ??|?SMALLINT[(length)]?[UNSIGNED]?[ZEROFILL]  ??|?MEDIUMINT[(length)]?[UNSIGNED]?[ZEROFILL]  ??|?INT[(length)]?[UNSIGNED]?[ZEROFILL]  ??|?INTEGER[(length)]?[UNSIGNED]?[ZEROFILL]  ??|?BIGINT[(length)]?[UNSIGNED]?[ZEROFILL]  ??|?REAL[(length,decimals)]?[UNSIGNED]?[ZEROFILL]  ??|?DOUBLE[(length,decimals)]?[UNSIGNED]?[ZEROFILL]  ??|?FLOAT[(length,decimals)]?[UNSIGNED]?[ZEROFILL]  ??|?DECIMAL(length,decimals)?[UNSIGNED]?[ZEROFILL]  ??|?NUMERIC(length,decimals)?[UNSIGNED]?[ZEROFILL]  ??|?DATE  ??|?TIME  ??|?TIMESTAMP  ??|?DATETIME  ??|?CHAR(length)?[BINARY?|?ASCII?|?UNICODE]  ??|?VARCHAR(length)?[BINARY]  ??|?TINYBLOB  ??|?BLOB  ??|?MEDIUMBLOB  ??|?LONGBLOB  ??|?TINYTEXT?[BINARY]  ??|?TEXT?[BINARY]  ??|?MEDIUMTEXT?[BINARY]  ??|?LONGTEXT?[BINARY]  ??|?ENUM(value1,value2,value3,...)  ??|?SET(value1,value2,value3,...)  ??|?spatial_type  index_col_name:  ????col_name?[(length)]?[ASC?|?DESC]  reference_definition:  ????REFERENCES?tbl_name?[(index_col_name,...)]  ???????????????[MATCH?FULL?|?MATCH?PARTIAL?|?MATCH?SIMPLE]  ???????????????[ON?DELETE?reference_option]  ???????????????[ON?UPDATE?reference_option]  reference_option:  ????RESTRICT?|?CASCADE?|?SET?NULL?|?NO?ACTION  table_options:?table_option?[table_option]?...  table_option:  ????{ENGINE|TYPE}?=?engine_name  ??|?AUTO_INCREMENT?=?value  ??|?AVG_ROW_LENGTH?=?value  ??|?[DEFAULT]?CHARACTER?SET?charset_name?[COLLATE?collation_name]  ??|?CHECKSUM?=?{0?|?1}  ??|?COMMENT?=?'string'  ??|?CONNECTION?=?'connect_string'  ??|?MAX_ROWS?=?value  ??|?MIN_ROWS?=?value  ??|?PACK_KEYS?=?{0?|?1?|?DEFAULT}  ??|?PASSWORD?=?'string'  ??|?DELAY_KEY_WRITE?=?{0?|?1}  ??|?ROW_FORMAT?=?{DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}  ??|?UNION?=?(tbl_name[,tbl_name]...)  ??|?INSERT_METHOD?=?{?NO?|?FIRST?|?LAST?}  ??|?DATA?DIRECTORY?=?'absolute?path?to?directory'  ??|?INDEX?DIRECTORY?=?'absolute?path?to?directory'  partition_options:  ????PARTITION?BY  ???????????[LINEAR]?HASH(expr)  ????????|??[LINEAR]?KEY(column_list)  ????????|??RANGE(expr)  ????????|??LIST(column_list)  ????[PARTITIONS?num]  ????[??SUBPARTITION?BY  ???????????[LINEAR]?HASH(expr)  ?????????|?[LINEAR]?KEY(column_list)  ??????[SUBPARTITIONS(num)]  ????]  ????[(partition_definition),?[(partition_definition)],?...]  partition_definition:  ????PARTITION?partition_name  ???????[VALUES?{  ??????????????????LESS?THAN?(expr)?|?MAXVALUE  ????????????????|?IN?(value_list)?}]  ????????[[STORAGE]?ENGINE?[=]?engine-name]  ????????[COMMENT?[=]?'comment_text'?]  ????????[DATA?DIRECTORY?[=]?'data_dir']  ????????[INDEX?DIRECTORY?[=]?'index_dir']  ????????[MAX_ROWS?[=]?max_number_of_rows]  ????????[MIN_ROWS?[=]?min_number_of_rows]  ????????[TABLESPACE?[=]?(tablespace_name)]  ????????[NODEGROUP?[=]?node_group_id]  ????????[(subpartition_definition),?[(subpartition_definition)],?...]  subpartition_definition:  ????SUBPARTITION?logical_name  ????????[[STORAGE]?ENGINE?[=]?engine-name]  ????????[COMMENT?[=]?'comment_text'?]  ????????[DATA?DIRECTORY?[=]?'data_dir']  ????????[INDEX?DIRECTORY?[=]?'index_dir']  ????????[MAX_ROWS?[=]?max_number_of_rows]  ????????[MIN_ROWS?[=]?min_number_of_rows]  ????????[TABLESPACE?[=]?(tablespace_name)]  ????????[NODEGROUP?[=]?node_group_id]  select_statement:  ????[IGNORE?|?REPLACE]?[AS]?SELECT?...???(Some?legal?select?statement)

CREATE TABLE用于創建帶給定名稱的表。您必須擁有表CREATE權限。

默認的情況是,表被創建到當前的數據庫中。如果表已存在,或者如果沒有當前數據庫,或者如果數據庫不存在,則會出現錯誤。

表名稱被指定為db_name.tbl_name,以便在特定的數據庫中創建表。不論是否有當前數據庫,都可以通過這種方式創建表。如果您使用加引號的識別名,則應對數據庫和表名稱分別加引號。例如,`mydb`.`mytbl`是合法的,但是`mydb.mytbl`不合法。

在創建表格時,您可以使用TEMPORARY關鍵詞。只有在當前連接情況下,TEMPORARY表才是可見的。當連接關閉時,TEMPORARY表被自動取消。這意味著兩個不同的連接可以使用相同的臨時表名稱,同時兩個臨時表不會互相沖突,也不與原有的同名的非臨時表沖突。(原有的表被隱藏,直到臨時表被取消時為止。)您必須擁有CREATE TEMPORARY TABLES權限,才能創建臨時表。

如果表已存在,則使用關鍵詞IF NOT EXISTS可以防止發生錯誤。注意,原有表的結構與CREATE TABLE語句中表示的表的結構是否相同,這一點沒有驗證。注釋:如果您在CREATE TABLE…SELECT語句中使用IF NOT EXISTS,則不論表是否已存在,由SELECT部分選擇的記錄都會被插入。

MySQL通過數據庫目錄中的.frm表格式(定義)文件表示每個表。表的存儲引擎也可能會創建其它文件。對于MyISAM表,存儲引擎可以創建數據和索引文件。因此,對于每個MyISAM表tbl_name,有三個磁盤文件:

文件 ? ?作用 ? ?

tbl_name.frm ? ?表格式(定義)文件 ? ?

tbl_name.MYD ? ?數據文件 ? ?

tbl_name.MYI ? ?索引文件 ? ?

·?如果沒有指定是NULL或是NOT NULL,則列在創建時假定指定為NULL。

·?一個整數列可以擁有一個附加屬性AUTO_INCREMENT。當您向一個已編入索引的AUTO_INCREMENT列中插入一個NULL值(建議)或0時,此列被設置為下一個序列的值。通常情況下為value+1,此處value是當前在表中的列的最大值。AUTO_INCREMENT序列從1開始。

為–sql-mode服務器選項或sql_mode系統變量指定NO_AUTO_VALUE_ON_ZERO特征位,這樣可以把0存儲到AUTO_INCREMENT列中,同時不生成一個新的序列值。

注釋:有時候,每個表只有一個AUTO_INCREMENT列,此列必須編制索引,不能有DEFAULT值。一個AUTO_INCREMENT列只有在只包含正數的情況下,才能運行正常。插入一個負數會被認為是插入了一個非常大的正數。這樣做是為了避免當數字由正數轉為負數時出現精度問題,同時也為了確保AUTO_INCREMENT列中不會包含0。

對于MyISAM和BDB表,您可以在一個多列關鍵字中指定一個AUTO_INCREMENT次級列。

為了讓MySQL與部分ODBC應用軟件相兼容,您可以使用以下查詢方法找到最后一個插入行的AUTO_INCREMENT值:

SELECT?*?FROM?tbl_name?WHERE?auto_col?IS?NULL

·?字符列的定義可以包括一個CHARACTER SET屬性,用來指定字符集,也可以指定列的整序。CHARSET是CHARACTER SET的同義詞。

CREATE?TABLE?t?(c?CHAR(20)?CHARACTER?SET?utf8?COLLATE?utf8_bin);

MySQL 5.1理解,在字符列定義中的長度規約以字符為單位。(有些早期版本以字節為單位。)

·?DEFAULT子句用于為列指定一個默認值。默認值必須為一個常數,不能為一個函數或一個表達式,有一種情況例外。例如,一個日期列的默認值不能被設置為一個函數,如NOW()或CURRENT_DATE。不過,有一種例外,您可以對TIMESTAMP列指定CURRENT_TIMESTAMP為默認值。

BLOB和TEXT列不能被賦予默認值。

如果在列定義中沒有明確的DEFAULT值,則MySQL按照如下規則確定默認值:

如果列可以使用NULL作為值,則使用DEFAULT NULL子句對列進行定義。(在MySQL的早期版本中也如此。)

如果列不能使用NULL作為值,則MySQL對列進行定義時不使用DEFAULT子句。輸入數據時,如果INSERT或REPLACE語句不包括列的值,則MySQL依據當時的有效的SQL模式操作列:

o?如果嚴格模式沒有被啟用,則MySQL會根據列數據類型,把列設置為明確的默認值。

o?如果嚴格模式已被啟用,則事務表會出現錯誤,語句被回滾。對于非事務表,會出現錯誤,不過,如果錯誤出現在一個多行語句中的第二行或后續行,則以前的各行將被插入。

假設表t按下面的方法進行定義:

CREATE?TABLE?t?(i?INT?NOT?NULL);

在這種情況下,i沒有明確的默認值,所以在嚴格模式中,每個后續語句都會產生一個錯誤,并且沒有行被插入。當未使用嚴格模式時,只有第三個語句產生錯誤;明確的默認值被插入到前兩個語句中,但是第三個語句會出現錯誤,因為DEFAULT(i)不會產生一個值:

INSERT?INTO?t?VALUES();  INSERT?INTO?t?VALUES(DEFAULT);  INSERT?INTO?t?VALUES(DEFAULT(i));

對于一個給定的表,您可以使用SHOW CREATE TABLE語句來查看那些列有明確的DEFAULT子句。

·?對于列的評注可以使用COMMENT選項來進行指定。評注通過SHOW CREATE TABLE和SHOW FULL COLUMNS語句顯示。

·?屬性SERIAL可以用作BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的別名。

·?KEY通常是INDEX同義詞。如果關鍵字屬性PRIMARY KEY在列定義中已給定,則PRIMARY KEY也可以只指定為KEY。這么做的目的是與其它數據庫系統兼容。

·?在UNIQUE索引中,所有的值必須互不相同。如果您在添加新行時使用的關鍵字與原有行的關鍵字相同,則會出現錯誤。例外情況是,如果索引中的一個列允許包含NULL值,則此列可以包含多個NULL值。此例外情況不適用于BDB表。在BDB中,帶索引的列只允許一個單一NULL。

·?PRIMARY KEY是一個唯一KEY,此時,所有的關鍵字列必須定義為NOT NULL。如果這些列沒有被明確地定義為NOT NULL,MySQL應隱含地定義這些列。一個表只有一個PRIMARY KEY。如果您沒有PRIMARY KEY并且一個應用程序要求在表中使用PRIMARY KEY,則MySQL返回第一個UNIQUE索引,此索引沒有作為PRIMARY KEY的NULL列。

·?在已創建的表中,PRIMARY KEY的位置最靠前,然后是所有的UNIQUE索引,然后是非唯一索引。這可以幫助MySQL優化程序選擇優先使用哪個索引,并且更快速的檢測出重復的UNIQUE關鍵字。

·?PRIMARY KEY可以是一個多列索引。但是,在列規約中使用PRIMARY KEY關鍵字屬性無法創建多列索引。這么做只能把一個列標記為主列。您必須使用一個單獨的PRIMARY KEY(index_col_name, …)子句。

·?如果PRIMARY KEY或UNIQUE索引只包括一個列,并且此列為整數類型,則您也可以在SELECT語句中把此列作為_rowid引用。

·?在MySQL中,PRIMARY KEY的名稱為PRIMARY。對于其它索引,如果您沒有賦予名稱,則索引被賦予的名稱與第一個已編入索引的列的名稱相同,并自選添加后綴(_2, _3,…),使名稱為唯一名稱。您可以使用SHOW INDEX FROM?tbl_name來查看表的索引名稱。

·?部分存儲引擎允許您在創建索引時指定索引類型。index_type指示語句的語法是USING type_name。

示例:

CREATE?TABLE?lookup  ??(id?INT,?INDEX?USING?BTREE?(id))  ??ENGINE?=?MEMORY;

·?在MySQL 5.1中,只有MyISAM,InnoDB, BDB和MEMORY存儲引擎支持在含有NULL值的列中編索引。在其它情況下,您必須定義已編索引的列為NOT NULL,否則會出現錯誤。

·?在一個索引規約中使用col_name(length)語法,您可以創建一個索引,此索引只使用一個CHAR或VARCHAR列的第一個length字符。只對列值的前綴編制索引可以使索引文件大大減小。

MyISAM和InnoDB存儲引擎也支持對BLOB和TEXT列編索引。當對BLOB或TEXT列編索引時,您必須為索引指定一個前綴長度。例如:

CREATE?TABLE?test?(blob_col?BLOB,?INDEX(blob_col(10)));

對于MyISAM和InnoDB表,前綴最長可以為1000字節,對于其它表格類型,最長可以為255字節。注意前綴長度限值以字節為單位,而在CREATE TABLE語句中的前綴長度用字符數目來表述。當為一個使用多字節字符集的列指定前綴長度時,一定要考慮到這一點。

·?一個index_col_name規約可以以ASC或DESC結尾。這些關鍵詞可以在將來進行擴展,用于指定升序或降序的索引值存儲。當前,這些關鍵詞被分析但是被忽略;索引值均以升序儲存。

·?當您在SELECT中的TEXT列或BLOB列中使用ORDER BY或GROUP BY時,服務器只使用初始的字節數目對值進行分類。字節數目由max_sort_length系統變量進行指示。

·?您可以創建特殊的FULLTEXT索引,用于全文搜索。只有MyISAM表類型支持FULLTEXT索引。FULLTEXT索引只可以從CHAR, VARCHAR和TEXT列中創建。整個列都會被編入索引;不支持對部分列編索引。如果已指定,前綴長度會被忽略。

·?您可以為空間列類型創建SPATIAL索引。只有MyISAM表支持空間類型,已編索引的列必須聲明為NOT NULL。

·?InnoDB表支持對外鍵限制條件進行檢查。注意,在InnoDB中,FOREIGN KEY語法比本節開始時介紹的CREATE TABLE語句的語法更嚴格:被引用的表中的列必須有明確的命名。InnoDB支持外鍵的ON DELETE和ON UPDATE兩種操作。

對于其它存儲引擎,MySQL服務器對CREATE TABLE語句中的FOREIGN KEY和REFERENCES語法進行分析,但不采取進一步的行動。所有的存儲引擎均對CHECK子句進行分析,但是忽略CHECK子句。

·?對于MyISAM表,每個NULL列要多占用一位,進位到距離最近的字節。最大記錄長度(以字節為單位)按照如下方法計算:

row?length?=?1  +?(sum?of?column?lengths)  +?(number?of?NULL?columns?+?delete_flag?+?7)/8  +?(number?of?variable-length?columns)

對于采用靜態記錄格式的表,delete_flag為1。靜態表在行記錄中使用一位用作位標記。位標記指示該行是否已被刪除。對于動態表,delete_flag為0,因為在動態行標題中已存儲了位標記。

這些計算方法不適用于InnoDB表。對于InnoDB表,NULL列的存儲量與NOT NULL列的存儲量沒有區別。

ENGINE和TYPE選項用于為表指定存儲引擎。ENGINE是首選的選項名稱。

ENGINE和TYPE選項采用以下值:

存儲引擎 ? ?說明 ? ?

ARCHIVE ? ?檔案存儲引擎。請參見“ARCHIVE存儲引擎”。 ? ?

BDB ? ?帶頁面鎖定的事務安全表。也稱為BerkeleyDB。請參見“BDB (BerkeleyDB)存儲引擎”。 ? ?

CSV ? ?值之間用逗號隔開的表。請參見“CSV存儲引擎。 ? ?

EXAMPLE ? ?示例引擎。請參見“EXAMPLE存儲引擎”。 ? ?

FEDERATED ? ?可以訪問遠程表的存儲引擎。請參見“FEDERATED存儲引擎”。 ? ?

HEAP ? ?見“MEMORY (HEAP)存儲引擎”。 ? ?

(OBSOLETE)ISAM ? ?在MySQL 5.1中沒有此引擎。如果您要從以前的版本升級到MySQL 5.1,您應該在進行升級前把原有的ISAM表轉換為MyISAM表。請參見存儲引擎和表類型。 ? ?

InnoDB ? ?帶行鎖定和外鍵的事務安全表。請參見“InnoDB存儲引擎”。 ? ?

MEMORY ? ?本表類型的數據只保存在存儲器里。(在早期MySQL版本中被稱為HEAP。) ? ?

MERGE ? ?MyISAM表的集合,作為一個表使用。也稱為MRG_MyISAM。請參見“MERGE存儲引擎”。 ? ?

MyISAM ? ?二進制輕便式存儲引擎,此引擎是MySQL所用的默認存儲引擎。請參見“MyISAM存儲引擎”。 ? ?

NDBCLUSTER ? ?成簇表,容錯表,以存儲器為基礎的表。也稱為NDB。請參見MySQL簇。 ? ?

如果被指定的存儲引擎無法利用,則MySQL使用MyISAM代替。例如,一個表定義包括ENGINE=BDB選項,但是MySQL服務器不支持BDB表,則表被創建為MyISAM表。這樣,如果您在主機上有事務表,但在從屬機上創建的是非交互式表(以加快速度)時,可以進行復制設置。在MySQL 5.1中,如果沒有遵守存儲引擎規約,則會出現警告。

其它表選項用于優化表的性質。在多數情況下,您不必指定表選項。這些選項適用于所有存儲引擎,另有說明除外:

·?AUTO_INCREMENT

表的初始AUTO_INCREMENT值。在MySQL 5.1中,本選項只適用于MyISAM和MEMORY表。InnoDB也支持本選項。如果引擎不支持AUTO_INCREMENT表選項,則要設置引擎的第一個auto-increment值,需插入一個“假”行。該行的值比創建表后的值小一,然后刪除該假行。

對于在CREATE TABLE語句中支持AUTO_INCREMENT表選項的引擎,您也可以使用ALTER TABLE?tbl_nameAUTO_INCREMENT =?n來重新設置AUTO_INCREMENT值。

·?AVG_ROW_LENGTH

表中平均行長度的近似值。只需要對含尺寸可變的記錄的大型表進行此項設置。

當創建一個MyISAM表時,MySQL使用MAX_ROWS和AVG_ROW_LENGTH選項的乘積來確定得出的表有多大。如果有一個選項未指定,則表的最大尺寸為65,536TB數據。(如果操作系統不支持這么大的文件,則表的尺寸被限定在操作系統的限值處。)如果您想縮小指針尺寸使索引更小,速度更快,并且您不需要大文件,則您可以通過設置myisam_data_pointer_size系統變量來減少默認指針的尺寸。如果您希望所有的表可以擴大,超過默認限值,并且愿意讓表稍微慢點,并稍微大點,則您可以通過設置此變量增加默認指針的尺寸。

·?[DEFAULT] CHARACTER SET

用于為表指定一個默認字符集。CHARSET是CHARACTER SET的同義詞。

對于CHARACTER SET.

·?COLLATE

用于為表指定一個默認整序。

·?CHECKSUM

如果您希望MySQL隨時對所有行進行實時檢驗求和(也就是,表變更后,MySQL自動更新檢驗求和),則應把此項設置為1。這樣做,表的更新速度會略微慢些,但是更容易尋找到受損的表。CHECKSUM TABLE語句用于報告檢驗求和(僅限于MyISAM)。

·?COMMENT

表的注釋,最長60個字符。

·?CONNECTION

FEDERATED表的連接字符串。( 注釋:較早版本的MySQL使用COMMENT選項用于連接字符串。

·?MAX_ROWS

您打算儲存在表中的行數目的最大值。這不是一個硬性限值,而更像一個指示語句,指示出表必須能存儲至少這么多行。

·?MIN_ROWS

您打算存儲在表中的行數目的最小值。

·?PACK_KEYS

如果您希望索引更小,則把此選項設置為1。這樣做通常使更新速度變慢,同時閱讀速度加快。把選項設置為0可以取消所有的關鍵字壓縮。把此選項設置為DEFAULT時,存儲引擎只壓縮長的CHAR或VARCHAR列(僅限于MyISAM)。

如果您不使用PACK_KEYS,則默認操作是只壓縮字符串,但不壓縮數字。如果您使用PACK_KEYS=1,則對數字也進行壓縮。

在對二進制數字關鍵字進行壓縮時,MySQL采用前綴壓縮:

o?每個關鍵字需要一個額外的字節來指示前一個關鍵字中有多少字節與下一個關鍵字相同。

o?指向行的指針以高位字節優先的順序存儲在關鍵字的后面,用于改進壓縮效果。

這意味著,如果兩個連續行中有許多相同的關鍵字,則后續的“相同”的關鍵字通常只占用兩個字節(包括指向行的指針)。與此相比,常規情況下,后續的關鍵字占用storage_size_for_key + pointer_size(指針尺寸通常為4)。但是,只有在許多數字相同的情況下,前綴壓縮才有好處。如果所有的關鍵字完全不同,并且關鍵字不能含有NULL值,則每個關鍵字要多使用一個字節。(在這種情況中,儲存壓縮后的關鍵字的長度的字節與用于標記關鍵字是否為NULL的字節是同一字節。)

·?PASSWORD

使用密碼對.frm文件加密。在標準MySQL版本中,本選項不起任何作用。

·?DELAY_KEY_WRITE

如果您想要延遲對關鍵字的更新,等到表關閉后再更新,則把此項設置為1(僅限于MyISAM)。

·?ROW_FORMAT

定義各行應如何儲存。當前,此選項只適用于MyISAM表。對于靜態行或長度可變行,此選項值可以為FIXED或DYNAMIC。myisampack用于把類型設置為COMPRESSED。

在默認情況下,InnoDB記錄以壓縮格式存儲(ROW_FORMAT=COMPACT)。通過指定ROW_FORMAT=REDUNDANT,仍然可以申請用于較早版本的MySQL中的非壓縮格式。

·?RAID_TYPE

在MySQL 5.0中,RAID支持被刪除了。要了解有關RAID的說明,請參見http://dev.mysql.com/doc/refman/4.1/en/create-table.html。

·?UNION

當您想要把一組相同的表當作一個表使用時,采用UNION。UNION僅適用于MERGE表。

對于您映射到一個MERGE表上的表,您必須擁有SELECT, UPDATE和DELETE權限。(注釋:以前,所有被使用的表必須位于同一個數據庫中,并作為MERGE表。這些限制不再適用。)

·?INSERT_METHOD

如果您希望在MERGE表中插入數據,您必須用INSERT_METHOD指定應插入行的表。INSERT_METHOD選項僅用于MERGE表。使用FIRST或LAST把行插入到第一個或最后一個表中;或者使用NO,阻止插入行。

·?DATA DIRECTORY,?INDEX DIRECTORY

通過使用DATA DIRECTORY=’directory’或INDEX DIRECTORY=’directory’,您可以指定MyISAM存儲引擎放置表格數據文件和索引文件的位置。注意,目錄應是通向目錄的完整路徑(不是相對路徑)。

僅當您沒有使用–skip-symbolic-links選項時,DATA DIRECTORY,?INDEX DIRECTORY才能使用。操作系統必須有一個正在工作的、線程安全的realpath()調用。要了解全面信息,

·?對于用CREATE TABLE創建的表,可以使用partition_options控制分區。如果使用了partition_options,則其中必須包含至少一個PARTITION BY子句。本子句包含用于確定分區的函數;該函數會返回一個整值,范圍從1到num。此處num為分區的數目。此函數中可以使用的選項顯示在下面的清單中。 要點:在本節開始時介紹的用于partition_options的語法中顯示的選項,并不是都能用于所有分區類型。要了解各種類型具體的信息 ,請參見以下各類型的清單。

o?HASH(expr):用于混編一個或多個列,創建一個關鍵字,用于放置行,并確定行的位置。expr是一個表達式,使用一個或多個表中的列。該表達式可以是任何能夠生成單一整值的合法的MySQL表達式(包括MySQL函數)。例如,這些都是有效的CREATE TABLE語句,語句中使用了PARTITION BY HASH:

CREATE?TABLE?t1?(col1?INT,?col2?CHAR(5))  ????????PARTITION?BY?HASH(col1);  CREATE?TABLE?t1?(col1?INT,?col2?CHAR(5))  ????????PARTITION?BY?HASH(?ORD(col2)?);  CREATE?TABLE?t1?(col1?INT,?col2?CHAR(5),?col3?DATETIME)  ????????PARTITION?BY?HASH?(?YEAR(col3)?);

VALUES LESS THAN或VALUES IN子句不能和PARTITION BY HASH一起使用。

PARTITION BY HASH使用expr被分區數目所除后的余數(也就是模數)。

LENEAR關鍵詞需要一種不同的算法。在這種情況下,通過一次或多次邏輯AND運算得出的結果,計算出存儲記錄的分區的數目。

o?KEY(column_list):與HASH近似,除了有一點不一樣,即MySQL提供了混編函數,以保證均勻的數據分布。column_list自變量只是各列的一個清單。本示例顯示了由關鍵字進行分區的一個簡單的表,分為4個分區:

CREATE?TABLE?tk?(col1?INT,?col2?CHAR(5),?col3?DATE)  ????????????PARTITION?BY?KEY(col3)  ????????????PARTITIONS?4;

采用LINEAR關鍵詞,您可以對由關鍵字分區的表進行線形分區。這與由HASH進行分區的表格有同樣的效果;也就是說,使用&操作符查找分區數目,而不是使用模數。本示例采用了關鍵字線形分區,用來在5個分區之間分配數據:

CREATE?TABLE?tk?(col1?INT,?col2?CHAR(5),?col3?DATE)  ????PARTITION?BY?LINEAR?KEY(col3)  ????PARTITIONS?5;

VALUES LESS THAN或VALUES IN子句不能和PARTITION BY KEY一起使用。

o?RANGE:在此情況下,expr使用一套VALUES LESS THAN操作符顯示了某一范圍內的值。當使用范圍分區時,您必須使用VALUES LESS THAN定義至少一個分區。VALUES IN不能和范圍分區一起使用。

VALUES LESS THAN可以與一個文字值同時使用,或者與一個可以求算單一值的表達式同時使用。

舉例說明,假設您有一個表,您希望采用以下方法對包含年份值的一列進行分區:

分區編號: ? ?年份范圍: ? ?

0 ? ?1990以前 ? ?

1 ? ?1991 – 1994 ? ?

2 ? ?1995 – 1998 ? ?

3 ? ?1999 – 2002 ? ?

4 ? ?2003 – 2005 ? ?

5 ? ?2006年以后 ? ?

采用這種分區方法的表可以通過如下CREATE TABLE語句實現:

CREATE?TABLE?t1?(  ????year_col?INT,  ????some_data?INT  )  PARTITION?BY?RANGE?(year_col)?(  ????PARTITION?p0?VALUES?LESS?THAN?(1991),  ????PARTITION?p1?VALUES?LESS?THAN?(1995),  ????PARTITION?p2?VALUES?LESS?THAN?(1999),  ????PARTITION?p3?VALUES?LESS?THAN?(2002),  ????PARTITION?p4?VALUES?LESS?THAN?(2006),  ????PARTITION?p5?VALUES?LESS?THAN?MAXVALUE  );

PARTITION … VALUES LESS THAN …語句按順序執行。VALUES LESS THAN MAXVALUE的作用是指定大于最大值的“其余”的值。

注意,VALUES LESS THAN子句按順序執行,執行方式類似于switch … case語段的一部分(許多編程語言,如C, Java和PHP也如此)。也就是說,子句必須按照這樣一種方法排列,每一個后續的VALUES LESS THAN中指定的上限值大于前一個VALUES LESS THAN中指定的上限值,并在清單的最后加一個參照性的MAXVALUE。

VALUES IN與一系列的值同時使用。舉例說明,您可以創建如下的分區方法:

CREATE?TABLE?client_firms?(  ????id?INT,  ????name?VARCHAR(35)  )  PARTITION?BY?RANGE?(id)?(  ????PARTITION?r0?VALUES?IN?(1,?5,?9,?13,?17,?21),  ????PARTITION?r1?VALUES?IN?(2,?6,?10,?14,?18,?22),  ????PARTITION?r2?VALUES?IN?(3,?7,?11,?15,?19,?23),  ????PARTITION?r3?VALUES?IN?(4,?8,?12,?16,?20,?24)  );

當前,與VALUES IN…同時使用的值必須只包含整數值。

(因為此表只使用VALUES IN表達式進行分區,您也可以用PARTITION BY LIST代替,而不是使用PARTITION BY RANGE。請參見下一條。)

在使用VALUES LESS THAN或VALUES IN情況下,每個分區使用PARTITION?name定義,此處name是分區的標識名,后面接VALUES…子句。

o?LIST(expr):當根據含有一系列限定性值(例如州代碼或國家代碼)的列進行分區時使用。在這種情況下,所有與特定的州或國家有關的記錄都被分配到一個單一分區中,或者可以預留出一個分區,用于一系列特定的州或國家。LIST(expr)與RANGE類似,除了一點以外,即只有VALUES IN可以被用于為每個分區指定值。

當使用清單分區時,您必須使用VALUES IN定義至少一個分區。VALUES LESS THAN不能與PARTITION BY LIST一起使用。

o?分區數目可以使用PARTITION?num子句,自選進行指定,此處,num是分區的數目。如果本子句和其它PARTITION子句同時使用,則num必須與使用PARTITION子句說明的分區的總數相等。

注釋:不論您在創建一個由RANGE或LIST進行分區的表時是否使用了PARTITIONS子句,您必須在表定義中包括至少一個PARTITION VALUES(見后)。

o?一個分區可以自選分隔成多個子分區。使用自選的SUBPARTITION BY子句可以指示。子分區可以由HASH或KEY進行分隔。兩種方法建立的子分區均為LINEAR。分隔子分區時的操作方式與以前描述的分區類型的操作方式一樣。(無法由LIST或RANGE進行子分區分隔。)

使用SUBPARTITIONS關鍵詞,后面接一個整值,可以對子分區的數目進行指示。

·?使用一個partition_definition子句可以對每個分區分別進行定義。下面是組成這個子句的各個部分:

o?PARTITION?partition_name:用于為分區指定一個邏輯名稱。

o?VALUE子句:對于范圍分區,每個分區必須包括一個VALUES LESS THAN子句;對于清單分區,您必須為每個分區指定一個VALUES IN子句。本子句用于確定哪些行將被存儲到此分區中。

o?自選的COMMENT子句可以用于描述分區。注釋必須加單引號。舉例說明:? ? ? ? ? ?

??????COMMENT?=?'Data?for?the?years?previous?to?1999'

o?DATA DIRECTORY和INDEX DIRECTORY可以被用于指示本分區的數據和索引各自的存儲位置的目錄。data_dir和index_dir都必須是絕對系統路徑。例如:

CREATE?TABLE?th?(id?INT,?name?VARCHAR(30),?adate?DATE)  ????????PARTITION?BY?LIST(YEAR(adate))  ????????(  ?????????????PARTITION?p1999?VALUES?IN?(1995,?1999,?2003)?DATA?DIRECTORY?=?'/var/appdata/95/data'?INDEX?DIRECTORY?=?'/var/appdata/95/idx',  ?????????????PARTITION?p2000?VALUES?IN?(1996,?2000,?2004)?DATA?DIRECTORY?=?'/var/appdata/96/data'?INDEX?DIRECTORY?=?'/var/appdata/96/idx',  ?????????????PARTITION?p2001?VALUES?IN?(1997,?2001,?2005)?DATA?DIRECTORY?=?'/var/appdata/97/data'?INDEX?DIRECTORY?=?'/var/appdata/97/idx',  ?????????????PARTITION?p2000?VALUES?IN?(1998,?2002,?2006)?DATA?DIRECTORY?=?'/var/appdata/98/data'?INDEX?DIRECTORY?=?'/var/appdata/98/idx'  ????????);

DATA DIRECTORY和INDEX DIRECTORY的操作方法與CREATE TABLE語句中的table_option子句的操作方法一樣。此table_option子句用于位于MyISAM表管理程序下的各表。

可以為每個分區指定一個數據目錄和一個索引目錄。如果不指定,則數據和索引被存儲在默認的MySQL數據目錄中。

o?MAX_ROWS和MIN_ROWS分別用于將被存儲在分區中的行數目最大值和行數目最小值。max_number_of_rows和min_number_of_rows的值必須為正整數。和具有同樣名稱的桌面選項一樣,max_number_of_rows和min_number_of_rows只作為對服務器的“建議”值,并不是硬性限值。

o?自選的TABLESPACE子句可以用于為分區指定一個桌面空間。僅用于MySQL Cluster。

o?自選的[STORAGE] ENGINE子句可以把本分區中表的類型改為指定的類型。表的類型可以是本MySQL服務器支持的所有類型。STORAGE關鍵字和等號(=)均為自選項。如果沒有使用此選項設置分區存儲引擎,則適用于整個表的引擎可以用于此分區。

注釋:分區管理程序對于PARTITION和SUBPARTITION均接受[STORAGE] ENGINE選項。目前,此子句的使用方式僅限于對所有的分區或子分區設置同一個存儲引擎,如果試圖在同一個表內對不同的分區或子分區設置不同的存儲引擎,則會出現錯誤ERROR 1469 (HY000):在本版本的MySQL中,不允許在各分區中混用管理程序。我們打算在將來的MySQL 5.1版本中加入這種對分區的限定。

o?NODEGROUP選項可以用于使本分區可以作為節點組的一部分,節點組使用node_group_id識別。本選項僅適用于MySQL Cluster。

o?分區定義可以自選地包含一個或多個subpartition_definition子句。每個這種子句至少包括SUBPARTITION?name,此處,name是子分區的識別名稱。除了用SUBPARTITION代替PARTITION關鍵詞外,用于子分區定義的語法與用于分區定義的語法一樣。

子分區必須由HASH或KEY完成,并且只能對RANGE或LIST分區進行子分區。

·?分區可以修改、合并、添加到表中,或從表中刪去。

您可以在CREATE TABLE語句的末尾添加一個SELECT語句,在一個表的基礎上創建表。

CREATE TABLE new_tbl SELECT * FROM orig_tbl;

MySQL會對SELECT中的所有項創建新列。舉例說明:

mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,??? ->?PRIMARY KEY (a), KEY(b))??? ->?TYPE=MyISAM SELECT b,c FROM test2;

本語句用于創建含三個列(a, b, c)的MyISAM表。注意,用SELECT語句創建的列附在表的右側,而不是覆蓋在表上。參考以下示例:

mysql>?SELECT?*?FROM?foo;+---+  |?n?|  +---+  |?1?|  +---+  mysql>?CREATE?TABLE?bar?(m?INT)?SELECT?n?FROM?foo;Query?OK,?1?row?affected?(0.02?sec)

Records: 1? Duplicates: 0? Warnings: 0

mysql>?SELECT * FROM bar;
+——+—+
| m??? | n |
+——+—+
| NULL | 1 |
+——+—+
1 row in set (0.00 sec)

對應于表foo中的每一行,在表bar中插入一行,含有表foo中的值以及新列中的默認值。

在由CREATE TABLE…SELECT生成的表中,只在CREATE TABLE部分中命名的列首先出現。在兩個部分中都命名的列和只在SELECT部分中命名的列隨后出現。也可以通過指定CREATE TABLE部分中的列覆蓋SELECT列中的數據類型。

如果在把數據復制到表中時出現錯誤,則表會自動被取消,不會被創建。

CREATE TABLE…SELECT不會自動創建任何索引。索引需要專門創建,以便使語句的靈活性更強。如果您希望為已創建的表建立索引,您應在SELECT語句前指定索引。

mysql>?CREATE?TABLE?bar?(UNIQUE?(n))?SELECT?n?FROM?foo;

列的類型會發生部分轉化。例如,AUTO_INCREAMENT屬性不會被保留,VARCHAR列會變成CHAR列。

當使用CREATE…SELECT創建表時,在查詢時一定要對功能調用和表達式起別名。如果不起別名,則CREATE語句會出現錯誤或者生成不符合需要的列名稱。

CREATE?TABLE?artists_and_works  SELECT?artist.name,?COUNT(work.artist_id)?AS?number_of_works  FROM?artist?LEFT?JOIN?work?ON?artist.id?=?work.artist_id  GROUP?BY?artist.id;

您也可以明確地為一個已生成的列指定類型:

CREATE?TABLE?foo?(a?TINYINT?NOT?NULL)?SELECT?b+1?AS?a?FROM?bar;

根據其它表的定義(包括在原表中定義的所有的列屬性和索引),使用LIKE創建一個空表:

CREATE?TABLE?new_tbl?LIKE?orig_tbl;

CREATE TABLE…LIKE不會復制對原表或外鍵定義指定的DATA DIRECTORY或INDEX DIRECTORY表選項。

您可以在SELECT前增加IGNORE或REPLACE,指示如何對復制唯一關鍵字值的記錄進行操縱。使用IGNORE后,如果新記錄復制了原有的唯一關鍵字值的記錄,則新記錄被丟棄。使用REPLACE后,新記錄替換具有相同的唯一關鍵字值的記錄。如果沒有指定IGNORE或REPLACE,則出現多重唯一關鍵字值時會導致發生錯誤。

為了確保更新日志/二進位日志可以被用于再次創建原表,MySQL不允許在CREATE TABLE…SELECT過程中進行聯合插入。

5.1.?沉寂的列規格變更

在有些情況下,較早版本的MySQL會靜默地更改在CREATE TABLE或ALTER TABLE語句中給定的列規約。在MySQL 5.1中不會進行這類變更。如果使用指定的數據類型無法創建列,則會出現錯誤。

6.?DROP DATABASE語法

DROP?{DATABASE?|?SCHEMA}?[IF?EXISTS]?db_name

DROP DATABASE用于取消數據庫中的所用表格和取消數據庫。使用此語句時要非常小心!如果要使用DROP DATABASE,您需要獲得數據庫DROP權限。

IF EXISTS用于防止當數據庫不存在時發生錯誤。

也可以使用DROP SCHEMA。

如果您對一個帶有符號鏈接的數據庫使用DROP DATABASE,則鏈接和原數據庫都被取消。

DROP DATABASE會返回已被取消的表的數目。此數目相當于被取消的.frm文件的數目。

在正常操作中MySQL自身會創建出一些文件和目錄。DROP DATABASE語句會從給定的數據庫目錄中取消這些文件和目錄:

· ?所有帶這些擴展名的文件:

.BAK ? ?.DAT ? ?.HSH ? ?

.MRG ? ?.MYD ? ?.ISD ? ?

.MYI ? ?.db ? ?.frm ? ?

·?名稱中包含兩位16進制數00-ff的所有子目錄。這些子目錄用于RAID表。(當對RAID表的支持被取消時,在MySQL 5.0中,這些目錄不會被取消。您應該在升級到MySQL 5.0或更新的版本前轉化原有的RAID表,并人工取消這些目錄。請參見MySQL 5.0參考手冊中有關從較早版本升級到MySQL 5.0的章節。MySQL 5.0參考手冊可以從MySQL網站中獲取。)

·?db.opt文件

如果在MySQL取消了上述這些文件之后,在數據庫目錄中仍保留有其它文件和目錄,則數據庫目錄不能被取消。在這種情況下,您必須人工取消所有保留下的文件或目錄,并再次發送DROP DATABASE語句。

您還可以使用mysqladmin來取消文件。

7.?DROP INDEX語法

DROP?INDEX?index_name?ON?tbl_name

DROP INDEX用于從表tbl_name中取消名稱為index_name的索引。本語句被映射到一個ALTER TABLE語句中,用于取消索引。

8.?DROP TABLE語法

DROP?[TEMPORARY]?TABLE?[IF?EXISTS]  ????tbl_name?[,?tbl_name]?...  ????[RESTRICT?|?CASCADE]

DROP TABLE用于取消一個或多個表。您必須有每個表的DROP權限。所有的表數據和表定義會被取消,所以使用本語句要小心!

注意,對于一個帶分區的表,DROP TABLE會永久性地取消表定義,取消各分區,并取消儲存在這些分區中的所有數據。DROP TABLE還會取消與被取消的表有關聯的分區定義(.par)文件。

對與不存在的表,使用IF EXISTS用于防止錯誤發生。當使用IF EXISTS時,對于每個不存在的表,會生成一個NOTE。

RESTRICT和CASCADE可以使分區更容易。目前,RESTRICT和CASCADE不起作用。

注釋:除非您使用TEMPORARY關鍵詞,DROP TABLE會自動提交當前的有效的事務。

TEMPORARY關鍵詞具有以下作用:

·?語句只取消TEMPORARY表。

·?語句不會終止正在進行中的事務。

·?不會查驗存取權。(TEMPORARY表僅對于創建該表的客戶端是可見的,所以查驗是不必要的。)

使用TEMPORARY是確保您不會意外取消一個非TEMPORARY表的良好方法。

9.?RENAME TABLE語法

RENAME?TABLE?tbl_name?TO?new_tbl_name  ????[,?tbl_name2?TO?new_tbl_name2]?...

本語句用于對一個或多個表進行重命名。

重命名操作自動進行,這意味著當重命名正在運行時,其它線程不能讀取任何表。例如,如果您有一個原有的表old_table,您可以創建另一個具有相同結構的空表new_table,然后用此空表替換原有的表:

CREATE?TABLE?new_table?(...);  RENAME?TABLE?old_table?TO?backup_table,?new_table?TO?old_table;

如果此語句用于對多個表進行重命名,則重命名操作從左至右進行。如果您想要交換兩個表的名稱,您可以這樣做(假設不存在名稱為tmp_table的表):

RENAME?TABLE?old_table?TO?tmp_table,  ????????????new_table?TO?old_table,  ????????????tmp_table?TO?new_table;

只要兩個數據庫位于同一文件系統中,您還可以對表進行重命名,把表從一個數據庫中移動到另一個數據庫中:

RENAME TABLE current_db.tbl_name TO other_db.tbl_name;

當您執行RENAME時,您不能有被鎖定的表,也不能有處于活性狀態的事務。您還必須擁有原表的ALTER和DROP權限,以及新表的CREATE和INSERT權限。

如果MySQL對多個表進行重命名時遇到了錯誤,MySQL會對所有已被重命名的表進行反向重命名,返回到原來的狀態。

只要您不嘗試通過重命名把視圖加入另一個數據庫中,則RENAME TABLE也可以用于視圖。

? 版權聲明
THE END
喜歡就支持一下吧
點贊9 分享