數據庫主鍵及索引


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

二、索引的類型
MySQL提供多種索引類型供選擇:

普通索引
這是最基本的索引類型,而且它沒有唯一性之類的限制。普通索引可以通過以下幾種方式創建:
創建索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
創建表的時候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );

唯一性索引
這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一。唯一性索引可以用以下幾種方式創建:
創建索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
創建表的時候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) );

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

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

索引的缺點
到目前為止,我們討論的都是索引的優點。事實上,索引也是有缺點的。

首先,索引要占用磁盤空間。通常情況下,這個問題不是很突出。但是,如果你創建每一種可能列組合的索引,索引文件體積的增長速度將遠遠超過數據文件。如果你有一個很大的表,索引文件的大小可能達到操作系統允許的最大文件限制。

第二,對於需要寫入數據的操作,比如DELETE、UPDATE以及INSERT操作,索引會降低它們的速度。這是因為MySQL不僅要把改動數據寫入數據文件,而且它還要把這些改動寫入索引文件。

索引與主鍵的主要區別有
主鍵是一種約束,唯一索引是一種索引,兩者在本質上是不同的。

主鍵創建后一定包含一個唯一性索引,唯一性索引並不一定就是主鍵。

唯一性索引列允許空值,而主鍵列不允許為空值。

主鍵列在創建時,已經默認為空值 + 唯一索引了。

主鍵可以被其他表引用為外鍵,而唯一索引不能。

一個表最多只能創建一個主鍵,但可以創建多個唯一索引。

主鍵更適合那些不容易更改的唯一標識,如自動遞增列、身份證號等。

在 RBO 模式下,主鍵的執行計划優先級要高於唯一索引。 兩者可以提高查詢的速度。

 

-- 創建一張僅包含主鍵和唯一索引的表

CREATE TABLE test

(PrimaryKey VARCHAR2(20),

  UniqueKey  VARCHAR2(20)

);

-- 分別創建主鍵和唯一索引,語法不同

ALTER TABLE test ADD CONSTRAINT test_PrimaryKey PRIMARY KEY (PrimaryKey);

CREATE UNIQUE INDEX test_UniqueKey ON test (UniqueKey);

-- 在 USER_INDEXES 中可以看到兩個索引名稱

SELECT table_name,table_type,index_name,index_type,uniqueness

  FROM USER_INDEXES

  WHERE TABLE_NAME='TEST';

 

 

-- 在 USER_IND_COLUMNS 中可以看到兩個索引字段名稱

SELECT table_name,index_name,column_name,column_position

  FROM USER_IND_COLUMNS

  WHERE TABLE_NAME='TEST';

 

-- 在 USER_CONSTRAINTS 僅可以看到主鍵約束名稱

SELECT table_name,constraint_name,constraint_type

  FROM USER_CONSTRAINTS

  WHERE TABLE_NAME='TEST';

 

 

-- 在 USER_CONS_COLUMNS 僅可以看到主鍵約束字段名稱

SELECT table_name,constraint_name,column_name,position

  FROM USER_CONS_COLUMNS

  WHERE CONSTRAINT_NAME IN (SELECT CONSTRAINT_NAME

                             FROM USER_CONSTRAINTS

                             WHERE TABLE_NAME='TEST');

 

 

-- 為唯一索引增加一個非空約束

ALTER TABLE test MODIFY UniqueKey NOT NULL;

 

-- 在 USER_CONSTRAINTS 僅可以看到主鍵約束名稱和非空約束名稱

SELECT table_name,constraint_name,constraint_type

  FROM USER_CONSTRAINTS

  WHERE TABLE_NAME='TEST'

 

-- 在 USER_CONS_COLUMNS 僅可以看到主鍵約束字段名稱和非空約束字段名稱

SELECT table_name,constraint_name,column_name,position

  FROM USER_CONS_COLUMNS

  WHERE CONSTRAINT_NAME IN (SELECT CONSTRAINT_NAME

                             FROM USER_CONSTRAINTS

                            WHERE TABLE_NAME='TEST')


免責聲明!

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



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