MySQL(十)操縱表及全文本搜索


一、創建表

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數據庫引擎中支持全文本搜索。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM