<output id="r87xx"></output>
    1. 
      
      <mark id="r87xx"><thead id="r87xx"><input id="r87xx"></input></thead></mark>
        •   

               當前位置:首頁>軟件介紹>MySQL數(shù)據(jù)庫的幾個概念:主鍵,外鍵,索引,唯一索引 查詢:
               
          MySQL數(shù)據(jù)庫的幾個概念:主鍵,外鍵,索引,唯一索引

                  主鍵:

                  主鍵是數(shù)據(jù)表的唯一索引,比如學生表里有學號和姓名,姓名可能有重名的,但學號確是唯一的,你要從學生表中搜索一條紀錄如查找一個人,就只能根據(jù)學號去查找,這才能找出唯一的一個,這就是主鍵;如:id int(10) not null primary key auto_increment ;自增長的類型 ;

                  外鍵:

                  定義數(shù)據(jù)表

                  假如某個電腦生產(chǎn)商,它的數(shù)據(jù)庫中保存著整機和配件的產(chǎn)品信息。用來保存整機產(chǎn)品信息的表叫做 Pc;用來保存配件供貨信息的表叫做Parts。在Pc表中有一個字段,用來描述這款電腦所使用的CPU型號;在Parts 表中相應有一個字段,描述的正是CPU的型號,我們可以把它想成是全部CPU的型號列表。

                  很顯然,這個廠家生產(chǎn)的電腦,其使用的CPU一定是供貨信息表(parts)中存在的型號。這時,兩個表中就存在一種約束關系(constraint)——Pc表中的CPU型號受到Parts 表中型號的約束。

                  首先我們來創(chuàng)建 parts 表:

                  CREATE TABLE parts (

                  ... 字段定義 ...,

                  model VARCHAR(20) NOT NULL,

                  ... 字段定義 ...

                  );

                  接下來是Pc表:

                  CREATE TABLE pc (

                  ... 字段定義 ...,

                  cpumodel VARCHAR(20) NOT NULL,

                  ... 字段定義 ...

                  };

                  設置索引

                  若要設置外鍵,在參照表(referencing table,即Pc表) 和被參照表 (referenced table,即parts表)

                  中,相對應的兩個字段必須都設置索引(index)。

                  對Parts表:

                  ALTER TABLE parts ADD INDEX idx_model (model);

                  這句話的意思是,為 parts 表增加一個索引,索引建立在 model 字段上,給這個索引起個名字叫

                  idx_model。

                  對Pc表也類似:

                  ALTER TABLE pc ADD INDEX idx_cpumodel (cpumodel);

                  事實上這兩個索引可以在創(chuàng)建表的時候就設置。這里只是為了突出其必要性。

                  定義外鍵

                  下面為兩張表之間建立前面所述的那種“約束”。因為pc的CPU型號必須參照parts表中的相應型號,所以我們將Pc表的cpumodel字段設置為“外鍵”(FOREIGN KEY),即這個鍵的參照值來自于其他表。

                  ALTER TABLE pc ADD CONSTRAINT fk_cpu_model

                  FOREIGN KEY (cpumodel)

                  REFERENCES parts(model);

                  第一行是說要為Pc表設置外鍵,給這個外鍵起一個名字叫做fk_cpu_model;第二行是說將本表的cpumodel字段設置為外鍵;第三行是說這個外鍵受到的約束來自于Parts表的model字段。這樣,我們的外鍵就可以了。如果我們試著CREATE一臺Pc,它所使用的CPU的型號是Parts表中不存在的,那么MySQL會禁止這臺PC被CREATE出來。

                  級聯(lián)操作

                  考慮以下這種情況:

                  技術人員發(fā)現(xiàn),一個月之前輸入到 parts 表中的某個系列的 cpu (可能有很多款)的型號全都輸錯了一個字母,現(xiàn)在需要改正。我們希望的是,當 parts 表中那些 Referenced Column 有所變化時,相應表中的 Referencing Column 也能自動更正。

                  可以在定義外鍵的時候,在最后加入這樣的關鍵字:

                  ON UPDATE CASCADE; 即在主表更新時,子表(們)產(chǎn)生連鎖更新動作,似乎有些人喜歡把這個叫“級聯(lián)”操作。:)

                  如果把這語句完整的寫出來,就是:

                  ALTER TABLE pc ADD CONSTRAINT fk_cpu_model

                  FOREIGN KEY (cpumodel)

                  REFERENCES parts(model)

                  ON UPDATE CASCADE;

                  除了 CASCADE 外,還有 RESTRICT(禁止主表變更)、SET NULL(子表相應字段設置為空)等操作索引:

                  索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形式保存。如果沒有索引,執(zhí)行查詢時MySQL必須從第一個記錄開始掃描整個表的所有記錄,直至找到符合要求的記錄。表里面的記錄數(shù)量越多,這個操作的代價就越高。如果作為搜索條件的列上已經(jīng)創(chuàng)建了索引,MySQL無需掃描任何記錄即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查找記錄至少要比順序掃描記錄快100倍。

                  假設我們創(chuàng)建了一個名為people的表:

                  CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );

                  然后,我們完全隨機把1000個不同name值插入到people表。下圖顯示了people表所在數(shù)據(jù)文件的一小部分:

                  可以看到,在數(shù)據(jù)文件中name列沒有任何明確的次序。如果我們創(chuàng)建了name列的索引,MySQL將在索引中排序name列:

                  對于索引中的每一項,MySQL在內(nèi)部為它保存一個數(shù)據(jù)文件中實際記錄所在位置的“指針”。因此,如果我們要查找name等于“Mike”記錄的peopleid(SQL命令為“SELECT peopleid FROMpeople WHERE name='Mike';”),MySQL能夠在name的索引中查找“Mike”值,然后直接轉(zhuǎn)到數(shù)據(jù)文件中相應的行,準確地返回該行的peopleid(999)。在這個過程中,MySQL只需處理一個行就可以返回結果。如果沒有“name”列的索引,MySQL要掃描數(shù)據(jù)文件中的所有記錄,即個行就可以返回結果。如果沒有“name”列的索引,MySQL要掃描數(shù)據(jù)文件中的所有記錄,即1000個記錄!顯然,需要MySQL處理的記錄數(shù)量越少,則它完成任務的速度就越快。索引的類型MySQL提供多種索引類型供選擇:

                  普通索引

                  這是最基本的索引類型,而且它沒有唯一性之類的限制。普通索引可以通過以下幾種方式創(chuàng)建:

                  創(chuàng)建索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);創(chuàng)建表的時候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表一性索引

                  這種索引和前面的“普通索引”基本相同,但有一個區(qū)別:索引列的所有值都只能出現(xiàn)一次,即必須唯一。唯一性索引可以用以下幾種方式創(chuàng)建:

                  創(chuàng)建索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);創(chuàng)建表的時候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表)

                  主鍵

                  主鍵是一種唯一性索引,但它必須指定為“PRIMARY KEY”。如果你曾經(jīng)用過AUTO_INCREMENT類型的列,你可能已經(jīng)熟悉主鍵之類的概念了。主鍵一般在創(chuàng)建表的時候指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,我們也可以通過修改表的方式加入主鍵,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每個表只能有一個主鍵。

                  全文索引

                  MySQL從3.23.23版開始支持全文索引和全文檢索。在MySQL中,全文索引的索引類型為FULLTEXT。全文索引可以在VARCHAR或者TEXT類型的列上創(chuàng)建。它可以通過CREATE TABLE命令創(chuàng)建,也可以通過ALTER TABLE或CREATE INDEX命令創(chuàng)建。對于大規(guī)模的數(shù)據(jù)集,通過ALTER TABLE(或者CREATE INDEX)命令創(chuàng)建全文索引要比把記錄插入帶有全文索引的空表更快。本文下面的討論不再涉及全文索引,要了解更多信息,請參見MySQL documentation。

                  單列索引與多列索引

                  索引可以是單列索引,也可以是多列索引。下面我們通過具體的例子來說明這兩種索引的區(qū)別。

                  假設有這樣一個people表:

                  CREATE TABLE people ( peopleid SMALLINT NOT NULL AUTO_INCREMENT, firstname

                  CHAR(50)

                  NOT NULL, lastname CHAR(50) NOT NULL, age SMALLINT NOT NULL, townid SMALLINT

                  NOT

                  NULL, PRIMARY KEY (peopleid) );

                  下面是我們插入到這個people表的數(shù)據(jù):

                  這個數(shù)據(jù)片段中有四個名字為“Mikes”的人(其中兩個姓Sullivans,兩個姓McConnells),有兩個年齡為17歲的人,還有一個名字與眾不同的Joe Smith。

                  這個表的主要用途是根據(jù)指定的用戶姓、名以及年齡返回相應的peopleid。例如,我們可能需要查找姓名為Mike Sullivan、年齡17歲用戶的peopleid(SQL命令為SELECT peopleid FROM peopleWHERE firstname='Mike' AND lastname='Sullivan' AND age=17;)。由于我們不想讓MySQL每次執(zhí)行查詢就去掃描整個表,這里需要考慮運用索引。

                  首先,我們可以考慮在單個列上創(chuàng)建索引,比如firstname、lastname或者age列。如果我們創(chuàng)建firstname列的索引(ALTER TABLE people ADD INDEX firstname (firstname);),MySQL將通過這個索引迅速把搜索范圍限制到那些firstname='Mike'的記錄,然后再在這個“中間結果集”上進行其他條件的搜索:它首先排除那些lastname不等于“Sullivan”的記錄,然后排除那些age不等于17的記錄。當記錄滿足所有搜索條件之后,MySQL就返回最終的搜索結果。

                  由于建立了firstname列的索引,與執(zhí)行表的完全掃描相比,MySQL的效率提高了很多,但我們要求MySQL掃描的記錄數(shù)量仍舊遠遠超過了實際所需要的。雖然我們可以刪除firstname列上的索引,再創(chuàng)建lastname或者age列的索引,但總地看來,不論在哪個列上創(chuàng)建索引搜索效率仍舊相似。

                  為了提高搜索效率,我們需要考慮運用多列索引。如果為firstname、lastname和age這三個列創(chuàng)建一個多列索引,MySQL只需一次檢索就能夠找出正確的結果!下面是創(chuàng)建這個多列索引的SQL命令:ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);

                  由于索引文件以B-樹格式保存,MySQL能夠立即轉(zhuǎn)到合適的firstname,然后再轉(zhuǎn)到合適的lastname,最后轉(zhuǎn)到合適的age。在沒有掃描數(shù)據(jù)文件任何一個記錄的情況下,MySQL就正確地找出了搜索的目標記錄!

                  找出了搜索的目標記錄!

                  那么,如果在firstname、lastname、age這三個列上分別創(chuàng)建單列索引,效果是否和創(chuàng)建一個firstname、lastname、age的多列索引一樣呢?答案是否定的,兩者完全不同。當我們執(zhí)行查詢的時候,MySQL只能使用一個索引。如果你有三個單列的索引,MySQL會試圖選擇一個限制最嚴格的索引。但是,即使是限制最嚴格的單列索引,它的限制能力也肯定遠遠低于firstname、lastname、age這三個列上的多列索引。

                  最左前綴

                  多列索引還有另外一個優(yōu)點,它通過稱為最左前綴(Leftmost Prefixing)的概念體現(xiàn)出來。繼續(xù)考慮前面的例子,現(xiàn)在我們有一個firstname、lastname、age列上的多列索引,我們稱這個索引為fname_lname_age。當搜索條件是以下各種列的組合時,MySQL將使用fname_lname_age索引:

                  firstname,lastname,age

                  firstname,lastname

                  firstname

                  從另一方面理解,它相當于我們創(chuàng)建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)這些列組合上的索引。下面這些查詢都能夠使用這個fname_lname_age索引:

                  SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND

                  age='17'; SELECT peopleid FROM people WHERE firstname='Mike' AND

                  lastname='Sullivan'; SELECT peopleid FROM people WHERE firstname='Mike'; The

                  following queries cannot use the index at all: SELECT peopleid FROM people WHERE

                  lastname='Sullivan'; SELECT peopleid FROM people WHERE age='17'; SELECT peopleid

                  FROM people WHERE lastname='Sullivan' AND age='17';

                  選擇索引列

                  在性能優(yōu)化過程中,選擇在哪些列上創(chuàng)建索引是最重要的步驟之一??梢钥紤]使用索引的主要有兩種類型的列:在WHERE子句中出現(xiàn)的列,在join子句中出現(xiàn)的列。請看下面這個查詢:

                  SELECT age ## 不使用索引 FROM people WHERE firstname='Mike' ## 考慮使用索引 AND lastname='Sullivan' ## 考慮使用索引

                  這個查詢與前面的查詢略有不同,但仍屬于簡單查詢。由于age是在SELECT部分被引用,MySQL不會用它來限制列選擇操作。因此,對于這個查詢來說,創(chuàng)建age列的索引沒有什么必要。下面是一個更復雜的例子:

                  SELECT people.age, ##不使用索引 town.name ##不使用索引 FROM people LEFT JOIN town ON

                  people.townid=town.townid ##考慮使用索引 WHERE firstname='Mike' ##考慮使用索引 ANDlastname='Sullivan' ##考慮使用索引與前面的例子一樣,由于firstname和lastname出現(xiàn)在WHERE子句中,因此這兩個列仍舊有創(chuàng)建索引的必要。除此之外,由于town表的townid列出現(xiàn)在join子句中,因此我們需要考慮創(chuàng)建該列的索引。

                  唯一索引:

                  通索引允許被索引的數(shù)據(jù)列包含重復的值。比如說,因為人有可能同名,所以同一個姓名在同一個“員工個人資料”數(shù)據(jù)表里可能出現(xiàn)兩次或更多次。

                  如果能確定某個數(shù)據(jù)列將只包含彼此各不相同的值,在為這個數(shù)據(jù)列創(chuàng)建索引的時候就應該用關鍵字UNIQUE把它定義為一個唯一索引。這么做的好處:一是簡化了MySQL對這個索引的管理工作,這個索引也因此而變得更有效率;二是MySQL會在有新記錄插入數(shù)據(jù)表時,自動檢查新記錄的這個字段的值是否已經(jīng)在某個記錄的這個字段里出現(xiàn)過了;如果是,MySQL將拒絕插入那條新記錄。也就是說,唯一索引可以保證數(shù)據(jù)記錄的唯一性。事實上,在許多場合,人們創(chuàng)建唯一索引的目的往往不是為了提高訪問速度,而只是為了避免數(shù)據(jù)出現(xiàn)重復。

                  


          PHP變量基本語法PHP開發(fā)語文介紹
          PHP是一種腳本語言最初產(chǎn)生動態(tài)網(wǎng)頁設計常用的CSS hack方式
          OA與RTX騰訊通集成方案中小企業(yè)ERP失敗的三大原因
          php redis中文手冊NoSQL緩存技術
          Redis、Memcache和MongoDB的區(qū)別MySQL數(shù)據(jù)庫性能優(yōu)化
          MySQL索引和查詢優(yōu)化MySQL索引優(yōu)化
          高并發(fā)訪問量Web接口服務設計與開發(fā)session與cookie的區(qū)別和聯(lián)系
          主流php框架優(yōu)劣比較數(shù)據(jù)庫存儲引擎
          信息發(fā)布:廣州名易軟件有限公司 http://m.jetlc.com
          • 勁爆價:
            不限功能
            不限用戶
            1998元/年

          • 微信客服

            <output id="r87xx"></output>
          1. 
            
            <mark id="r87xx"><thead id="r87xx"><input id="r87xx"></input></thead></mark>
              • 中文字幕第6页 | 欧美精品免費黃色視网 | 琪琪在线视频 | AV夜夜看 | 无码九九九 | 欧美成人免费观看视频 | 天天日天天爽 | 国产内射免费在线观看 | 777777国产7777777 | www.avzaixian |