一、創建表
MySQL不僅用於表數據操作,還可以用來執行數據庫和表的所有操作,包括表本身的創建和處理。
創建表一般有如下兩種方式:
①使用具有交互式創建和管理表的工具;
②直接使用MySQL語句操縱表;
1、表創建基礎
使用程序創建表,可使用SQL中的create table語句,需要以下兩個信息:
①新表的名字,在關鍵字create table后給出;
②表列的名字和定義,用逗號分隔;
例如:
create table usertables
(
user_id int not null auto_increment,
user_name char(50) null,
user_address char(50) null,
user_city char(50) null,
user_email char(50) null,
user_mobile char(50) null,
primary key (user_id)
)engine=InnoDB;
這條SQL語句中,表名usertables緊跟在create table之后,實際的表定義(所有列)括在圓括號內,各列間用逗號分隔,表的主鍵用primary key指定為user_id。
PS:創建新表時,指定的表名必須不存在(如果只想在一個表不存在時創建它,應在表名前給出if not exists:這樣做不檢查表模式是否與打算創建的表模式匹配,只檢查表名是否存在)。
2、使用null值
null就是沒有值或者缺值;允許null值的列也允許在插入行時不給出該列的值,不允許null值的列不接受該列沒有值的行(插入或更新行時,該列必須有值);
每個表列或者是null列,或者是not null列,這種狀態在創建時由表的定義規定,比如上面的例子;或者表中混合存在null和not null列。
PS:null為默認值,如果不指定not null,則認為指定的是null。
3、主鍵
主鍵值必須唯一,即表中的每個行必須具有唯一的主鍵值。如果主鍵使用單個列,則它的值必須唯一;如使用多個列,則這些列的組合值必須唯一。
創建表時,主鍵都用類似primary key的語句定義:primary key(column);創建由多個列組成的主鍵,應該以逗號分隔的列表給出各列名(主鍵可以在創建表時定義,或者在創建表之后定義)。
4、自動增量
例如:cust_id int nut null auto_increment,
auto_increment告訴MySQL,本列每當增加一行時自動增量;每次執行一個insert操作時,MySQL自動對該列增量,給該列賦予下一個可用的值;
每個表只允許一個auto_increment列,而且它必須被索引(比如,通過使它成為主鍵)
last_insert_id:此函數指示MySQL返回最后一個auto_increment值,然后可將它應用於后續MySQL語句。
5、指定默認值
如果在插入行時沒有給出值,MySQL允許指定此時使用的默認值;默認值用create table語句的列定義中的default關鍵字指定,例如:
create table usertables
(
user_id int not null,
user_name char(50) not null,
user_address char(50) not null,
user_city char(50) not null default shanghai,
user_email char(50) not null,
user_mobile char(50) not null,
primary key (user_id)
)engine=InnoDB;
這條語句中創建包含組成user信息的表,user_city列包含user的所在城市,該列的描述添加了default shanghai,在未給出城市的情況下使用上海(MySQL不允許使用函數作為默認值,它只支持常量)。
6、引擎類型
MySQL有一個具體管理和處理數據的內部引擎,使用create table語句時,該引擎具體創建表;使用select語句或進行其他數據庫處理時,該引擎內部處理請求(引擎隱藏在DBMS內,不需要過多關注)。
MySQL相比於其他DBMS的區別在於,它具有多種引擎;因為各個引擎有不同的功能和特性,為不同的任務選擇正確的引擎能獲得良好的功能和靈活性。
如果省略engine=語句,則使用默認引擎(很可能是MYISAM),但並不是所有情況都這樣,所以,engine語句很重要!
常見的幾種搜索引擎:
InnoDB:一個可靠的事務處理引擎,不支持全文本搜索;
MEMORY:在功能上等同於MyISAM,數據存儲在內存(不是磁盤),速度很快(特別適合臨時表);
MyISAM:一個性能極高的引擎,支持全文本搜索,但不支持事務處理;
PS:引擎類型可以混用,但缺陷在於:外鍵不能跨引擎,即:使用一個引擎的表不能引用具有使用不同引擎的表的外鍵。
二、更新表
為更新表定義,可以使用alter table語句(很少使用);為了更新表結構,必須給出如下信息:
①alter table之后給出要更改的表名(該表必須存在,否則會報錯)
②所做更改的列表;
例如:alter table usertable add user_country char(50);
這條SQL語句給usertable表增加了一個user_country的列,必須明確其數據類型。
刪除剛添加的列,可以這樣:
alter table usertable drop column user_country;
PS:alter table的一種常見用途是定義外鍵。
如果要多比較復雜的表進行更改,一般需要手動刪除過程,涉及的步驟如下:
①用新的列布局創建一個表;
②使用insert select語句從舊表復制數據到新表,如果有必要,可使用轉換函數和計算字段;
③檢驗包含所需數據的新表;
④重命名舊表(如果確定,可以刪除它);
⑤用舊表原來的名字重命名新表;
⑥根據需要,重新創建觸發器、存儲過程、索引和外鍵。
三、刪除表
刪除表(刪除整個表而不是其內容),使用drop table語句,例如:
drop table usertable;
這條語句刪除usertable表(假設它存在);刪除表沒有確認,也不能撤銷,執行這條語句將永久刪除該表。
還可以重命名表,例如:
rename table usertable to usertablebase;
這條語句用rename table語句重命名一個表;還可以對多個表進行重命名,每個表之間用逗號間隔。
四、全文本搜索
1、啟用索引
MySQL支持幾種基本的數據庫引擎,MySQL最長用的兩個引擎為:MyISAM和InnoDB:
MyISAM支持全文本搜索,查詢效率高;但局限在於不支持事務和外鍵;
InnoDB支持事務和外鍵,和MyISAM各有優劣;
與全文本搜索功能類似的有通配符和正則表達式匹配,但性能較低,通常會匹配表的所有行,而且這些搜索極少使用表索引,不能做到明確控制,且返回的結果不智能化;
在使用全文本搜索時,mysql不需要分別查看每個行,不需要分析和處理每個詞,只需索引被搜索的列(需要隨着數據的改變不斷重新索引)
一般在創建表時啟用全文本搜索(必須索引被搜索的列),create table語句接受fulltext子句,它給出被索引列的一個逗號分隔的列表;
例如:
CREATE TABLE productnotes
(
note_id int not null auto_incerement,
prod_id char(10) not null,
note_date datetime not null,
note_text text null,
primary key(note_id),
fulltext(note_text)
) engine = MyISAM;
這條create table語句定義表productnotes並列出它所包含的列即可;其中MySQL根據子句fulltext對(note_text)進行索引。
在定義之后,MySQL自動維護該索引;在增加、刪除、或更新行時,索引隨之自動更新。
PS:不要再導入數據時使用fulltext,這樣有助於更快的導入數據。
2、執行索引
啟用索引后,使用match()和against()執行全文本搜索;其中match()指定被搜索的列,against()指定要使用的搜索表達式。
例如:
select note_text
from productnotes
where match(note_text) against('rabbit');
這條select語句檢索單個列note_text,由於where子句,一個全文本搜索被執行;match(note_text)指示MySQL針對指定的列進行搜索,against('rabbit')指定rabbit作為搜索文本。
PS:傳遞給match()的值必須與fulltext()定義中的相同;如果指定多個列,則必須列出它們(次序正確);除非使用binary方式,否則全文本搜索不區分大小寫(上面的例子沒有使用該方式)。
like子句具有和全文本搜索相同的功能,但區別在於:全文本搜索的特點是對結果進行排序,具有較高等級的行先返回(如果排序多個搜索項,則包含多數匹配詞的行將具有更高的優先級)。
3、查詢擴展
作用:用來設法放寬所返回的全文本搜索結果的范圍(MySQL對數據和索引進行兩遍掃描來完成搜索)。
檢索過程:
①進行一個基本的全文本搜索,找出與搜索條件匹配的所有行;
②MySQL檢查這些匹配行並選擇所有有用的詞(將會簡要的解釋MySQL如何斷定什么有用什么無用);
③MySQL再次進行全文本搜索,這次不僅使用原來的條件,還是用所有有用的詞。
用法:where子句中against指定的搜索表達式后跟with query erpansion;
比如:where match(note_text) against('rabbit' with query erpansion);
PS:表中的行越多(行的文本越多),實用查詢擴展返回的結果越好。
4、布爾文本搜索
MySQL還支持另一種全文本搜索方式,稱為布爾方式(boolean mode);使用布爾方式需要提供一下條件:
①要匹配的詞;
②要排斥的詞(如果某行包含這個詞,則不返回,即使它包含其他指定的詞也是如此);
③排列提示(指定某些詞比其他詞重要,更重要的詞返回的等級更高);
④表達式分組;
⑤其他的內容。
PS:即使沒有fulltext索引也可以使用布爾方式(但這種方式很緩慢)。
例如:select note_text
from productnotes
where match(note_text) against('heavy -rope*' in bollean mode);
此全文本搜索檢索包含詞heavy的所有行,其中使用了in boolean mode以及布爾操作符,-rope*指示MySQL排除包含rope*(任何以rope開始的詞)的行。
全文本布爾操作符列表如下:
下面列舉幾個例子,說明這些操作符的使用:
①這個搜索匹配包含次rabbit和biat的行:
select note_text
from froductnotes
where match(note_text) against('+rabbit +bait' in boolean mode);
②沒有指定操作符,這個搜索匹配包含rabbit和bait中的至少一個詞的行:
select note_text
from froductnotes
where match(note_text) against('rabbit bait' in boolean mode);
③這個搜索匹配短語rabbit bait而不是匹配兩個詞rabbit和bait:
select note_text
from froductnotes
where match(note_text) against('"rabbit bait"' in boolean mode);
PS:在布爾方式中,不按照等級降序排序返回的行。
5、全文本搜索使用說明
①在索引全文本數據時,短詞被忽略且從索引中刪除(短詞定義為3個或3個以下字符的詞:如果需要可以更改);
②MySQL帶有一個內建的非用詞(stopword)列表,這些詞在索引全文本搜索時總被忽略(如果需要,可以覆蓋這個列表);
③MySQL50%規則:如果一個詞出現在50%以上的行中,則將它作為一個非用詞忽略;50%規則不用於in boolean mode;
④如果表中的行數少於3行,則全文本搜索不返回結果;
⑤忽略詞中的單引號,例如don't索引為dont;
⑥不具有詞分隔符的語言不能恰當的返回全文本搜索結果;
⑦僅在MyISAM數據庫引擎中支持全文本搜索。