《Mysql》必知必会读书笔记
Mysql知識匯總
1.基本操作知識:
-
用root用戶登錄:mysql -u root -p;
-
創建數據庫:create database bank(庫名);
-
退出:quit;
-
創建用戶gp,并賦予bank數據庫權限:grant all privileges on bank.* to ‘gp’@‘localhost’ identified by ‘xyz’;(xyz為密碼)
-
查詢當前日期:select now();
-
查看服務器所支持的字符集:show character set;
2.操作與修改表:
-
創建表:create table 表名(變量名 數據類型 【其他設定】);
-
查看表:desc 表名;
-
插入數據:insert into 表名 (變量名) values (對應的值);
-
查看表的數據:select *(變量名)from 表名 條件;
-
還可以加上如:select distinct 變量名 from 表名(distinct表示返回不同的值);
-
限制結果:select 變量名 from 表名 limit 行數 (限制輸出不超過5行) (limit 3,4 表示從行4開始的4行數據);
-
完全限定列名或表名:select products.prod_name from cashcourse.products;(完全限定了數據庫cashcourse中的products表);
-
排序檢索數據:
-
使用order by 子句進行排序:select 變量名(可多個,用 , 隔開) from 表名 order by 變量名(當為數字時默認進行升序排序);
-
指定排序方向:order by 變量名 DESC(降序排序)(對于多列變量需要每一個都加上DESC或ASC升序等等);
-
過濾數據:(where語句)
-
使用between檢測時,注意:select * from account where price between 5 and 10;
-
使用空值時,注意:select * from account where price is null;
-
and操作符和or操作符連接where (例如:select * from account where price = 5 and account_id = 10;);同時注意and操作符的優先級更高;
-
in操作符,說明:select * from account where price in (5, 10);作用與or相同。
-
not 操作符,例如和in聯合使用:select * from account where price not in (5,10);
-
通配符過濾數據:
? 1. like 操作符:%表示任何字符出現的任意次數(例子:select id from test where id like ‘1%’; 此例表示搜索任何以1開頭的詞);
-
'%ansjhdi%'則表示匹配任何包含ansjhdi的值;
-
下劃線 _ 通配符:用途和%一樣,不過 _ 表示的是只匹配單個字符;
-
用正則表達式進行搜索:
-
REGEXP字符匹配:select id from test where id REGEXP ‘.000’; ’ . '表示匹配任何一個字符,與文字正文1000或2000等匹配的正則表達式;
-
OR進行匹配:| 為正則表達式的OR操作符;select id from test where id EXGEXP ‘1000 | 2000’;
-
另一種or語句,匹配一組字符:用 [ ] 將想要包含的字符括起來;select id from test where id EXGEXP ‘[ 123 ]’ ;表示匹配1或2或3;[^123]則表示匹配除了123以外的任何東西;
-
匹配范圍:[1-9]表示匹配數字1到9;
-
匹配特殊字符,必須用 \ \ 為前導,例如 \ \ -表示查找 - ,\ \ . 表示查找 . 。
匹配字符類:
8. 匹配多個實例:
例子:[ [ : digit ] ] { 4 } 匹配連在一起的任意4個數字;又如:\ \ ([0 - 9 ] sticks ?\ \ ) 其中的 \ \ (匹配 )[ 0 - 9 ] 匹配任意數字,sticks?匹配stick和sticks;
定位符:
3.創建計算字段:
3.1概念
? 計算字段不是從數據庫中直接提取出來的數據,而是將從數據庫中檢索出來的數據進行轉換,計算或者格式化而形成的數據。
3.2拼接字段
? 在Mysql的select語句中,可使用Concat()函數進行拼接兩個列。例如:select Concat( RTrim(vend_name), ’ (’ , RTrim(vend_country), ‘)’ ) 其中的RTrim()函數去掉右邊的所有空格,還有LTrim(),Trim。
? 上面的例子表示的是將vend_name所包含的數據與用()連接的vend_country進行拼接;
3.3使用別名
? 使用AS關鍵字,例如:select pcp as name from 表,則將查找出來的pcp數據以name作為標題顯示出來;
3.4執行算術計算
? 支持 + ,- , * , / 四則運算。例如:select pid , price , price * pid as Allprice from 表名;
4.使用數據處理函數:
4.1文本處理函數
? Upper()將文本轉換為大寫,例如:select name , Upper(usernaem) as LBJ from 表名;
?
? SOUNDEX是一個將任何文本串轉換為描述其語音表示的字母數字模式的算法(例子:select cust_name from customers where Soundex(cust_contact) = Soundex(‘Y Lie’);
4.2 日期和時間處理函數
?
4.3 數值處理函數
?
5.匯總數據:
5.1聚集函數
- ? AVG()函數:select AVG(prod_price) AS avg_price from products;求出包含在products中的所有產品的平均價格;
- ? COUNT()函數:select COUNT(*) AS num_cust from customers;表示從customers表中取出num_cust的所有列的總和,無論是否為NULL;
- ? 使用COUNT(參數)則會將值為NULL的省略掉不加;
- ? MAX(),MIN()以及SUM()這三個函數的用法和前面就基本一樣;
5.2聚集不同值
? 可以使用DISTINCT于COUNT()上,但不可用于COUNT(*),使用DISTINCT時后面必須帶參數;
5.3組合聚集函數
? select語句中可以使用多個聚集函數;
6 分組數據:
6.1 創建分組
? 分組是在SELECT語句的GROUP BY字句中建立的。
? select pid , COUNT(*) AS num_prods from products GROUP BY vend_id; 該語句指示了按vend_id為計算字段,對不同的vend_id分別進行計算,實現多組分行;
? 注意:GROUP BY字句必須出現在WHERE字句后面,ORDER BY字句之前;
6.2 過濾分組
? 使用HAVING字句對組的數據進行過濾;WHERE用于過濾行;
? 例子:select cust_id , COUNT() AS orders FROM orders GROUP BY cust_id HAVING COUNT( * ) >= 2;
? 該例子過濾掉了COUNT(* )>=2 的那些分組;
6.3 分組和排序
? ORDER BY 排序產生的輸出,GROUP BY分組行,輸出可能不是分組的順序(不排序,僅分組);
? 例子:SELECT order_num , SUM(quality * price) AS ordertotal from orderitems GROUP BY order_num HAVING SUM(quality * price)>= 50 ORDER BY ordertotal;
? 該例子中,GROUP BY字句按照訂單號分組數據,以便SUM(*)函數算出總計訂單價格,HAVING字句過濾數據,使得只返回總訂單價格大于等于50的訂單,最后用ORDER BY字句排序出來。
7.使用子查詢:
7.1利用子查詢進行過濾
? 例子:SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = ’TNT');
? 首先執行括號里面的SELECT語句,即為子查詢語句,查詢完后將值代入IN()函數中進行另一個查詢;
7.2作為計算字段使用子查詢
? 例子:SELECT cust_name, cust_state, (SELECT COUNT(*)FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;
? 注意到WHERE子句中使用了完全限定的方法,將子查詢放在了外部,成為相關子查詢。
8.聯結表:
8.1 關系表
? 相同的數據出現多次并不好,關系表的設計就是保證把信息分解成多個表,一類數據一個表,各表通過某些常用的值互相聯系;
? 外鍵:為某一個表中的一列,它包含另一個表的主鍵值。1表的主鍵即使2表的外鍵。
8.2 創建聯結
? 例子:SELECT vend_name,prod_name,prod_price FROM vendors,products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name,prod_name;
? vend_name屬于其中一張表,而prod_name,prod_price屬于另一張表,所以在使用WHERE過濾語句時需要使用完全限定的方法。 即通過WHERE字句進行創建聯結;
8.3 內部聯結
之前的聯結都為等值聯結,它基于兩個表間的相等測試,這種聯結也稱為內部聯結,可以使用下面的方法實現和之前一樣的作用:? SELECT vend_name ,prod_name,prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id;
? 此處用INNER JOIN,則后面需要用ON進行聯結,不能用WHERE。
8.4 聯結多個表
? 例子:SELECT prod_name , vend_name,prod_price,quantity FROM orderitems,products,vendors WHERE products.vend_id = vendors.vend_id AND orderitems.prof_id = products.prod_id AND order_num = 20005;
? 使用多表聯動查詢比多個子查詢的結合效率要高。
9.創建高級聯動:
9.1使用表別名
? 可以為表起別名,方便使用,例如:SELECT cust_contact,cust_name FROM customers AS c,orders AS o,orderitems AS oi WHERE c.cust_id = o.cust_id AND…;
9.2 使用不同類型的聯動
9.2.1 自聯動
? 例子:SELECT p1.prod_id , p1.prod_name FROM products AS p1, products AS p2 WHERE p1.prod_id = p2.prod_id AND p2.prod_id = ‘DTNTR’;
9.2.2 自然聯動(返回所有的數據,甚至相同多次出現的數據,用自然聯結可排除多次出現)
? 例子:SELECT c.* ,order_num FROM customers AS c, orders AS o WHERE c.cust_id = o.cust_id…;
9.2.3 外部聯結(聯結包含了那些在相關表中沒有關聯行的行)
? 例子:SELECT customer.cust_id,orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id;
? 在使用OUTER JOIN語法時,必須使用RIGHT或LEFT關鍵字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右邊的表,LEFT則為左邊的表);
9.3 使用帶聚集函數的聯動
? 例子:SELECT customers.cust_name ,COUNT(orders.order_num) AS num_ord FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id…;
10.組合查詢
10.1創建組合查詢
? 使用UNION可給出多條SELECT語句;例子:SELECT vend_id , prod_price FROM products WHERE prod_price <= 5 UNION SELECT vend_id , prod_price FROM products WHERE vend_id IN (1001,1002);
? 給出每條SELECT語句,然后用UNION進行組合連接,并把結果輸出組合成單個查詢結果集;
10.2 包含或取消重復行
? UNION從查詢結果中自動去除了重復的行,這是UNION的默認屬性,如需要改變,可以使用UNION ALL返回所有匹配行;
10.3 對組合查詢結果進行排序
? UNION組合查詢是,只使用一條ORDER BY字句,其必須出現在SELECT語句的最后面,不允許使用多條ORDER BY字句;
? 例如:SELECT id, price from products WHERE price <= 5 UNION SELECT prod_id from products WHERE vend_id IN (1001,1002) order BY vend_id,price;
11.全文本搜索
11.1 概念
? 在使用全文本搜索時,Mysql不需要分別查詢每個行,不需要分析和處理每個詞,Mysql創建指定列中的各詞的一個索引,搜索可以針對這些詞進行。
11.2使用全文本搜索
? 在索引后,SELECT 可與Match()和Against()一起使用以實際執行搜索
11.2.1 啟用全文本搜索支持
? 一般在創建表時啟用全文本搜索。CREATE TABLE 語句接受FULLTEXT字句;
? 例子:CREATE TABLE products
? (note_id int NOT NULL ,
? prod_id char(10) NOT NULL,
? FULLTEXT(note_id)
? )ENGINE=MyISAM;
? Mysql對note_id進行索引創建,在增加,更新或刪除行時,索引會隨之自動更新;
11.2.2 進行全文本搜索
? 索引后,使用Match()和Against()執行全文本搜索,其中Match()指定被搜索的咧,Against()指定要使用的搜索表達式;
? 例子:SELECT note_text FROM productnotes WHERE Match(note_text) Against(‘rabbit’);
? 搜索指定的note_text這一列,然后指定詞rabit作為搜索文本。全文本搜索還對結果進行了一個排序的作用;具有較高等級的行先返回。
11.2.3 查詢拓展搜索
? 例子:SELECT note FROM product WHERE Match(note_text)Against(‘anvils’ WHITH QUERY EXPANSION)
? 不僅返回含有’anvils‘的行,還會返回其他有相關性詞的行等;
11.2.4 布爾文本搜索
? 沒有FULLTEXT索引也可以使用,不過操作緩慢;
? 例子:ELECT note FROM product WHERE Match(note_text)Against(‘anvils’ IN BOOLEAN MODE);
? 該語句沒有指定布爾操作符,所以結果和不使用的一樣;
?
?
? 例子:SELECT note_text FROM productnote WHERE Match(note_text) Against(’+rabbit+bait’ IN BOOLEAN MODE);
? 該語句匹配包含詞rabbit,bait的行;
12.插入數據
12.1 插入完整的行
? INSERT INTO Customers VALUES (NULL,‘Pepper’…);
? 也可以指定列名進行插入,例如:INSERT INTO customers(cust_name, cust_email)VALUES (‘PEP’,‘USA’);
·
12.2 插入多個行
? 例子:INSERT INTO customers(cust_name, cust_email)VALUES (‘PEP’,‘USA’),(‘KCP’,‘CHINA’);
12.3 插入檢索出的數據
? 例子:INSERT INTO customers(cust_name, cust_email)SELECT 變量名 from 表名;
13. 更新和刪除數據
13.1 更新數據
? UPDATE可以更新表中的行或列的數據;
? 例子:UPDATE 表名 SET 變量名 = 值 ,變量名 = 值 WHERE…;
? IGNORE關鍵字:更新時發生錯誤,也繼續更新,例子:UPDATE IGNORE 表名…;
13.2 刪除數據
? 例子:DELETE FROM 表名 WHERE 變量名 = 值;
? 使用TRUNCATE TABLE語句刪除整個表的數據,其原理是刪除整個表并重新建立一個新的表;
14.創建和操作表
14.1創建表的基礎
? 例子:CREATE TABLE 表名(變量 類型 其他指令,變量… , PRIMARY KEY(變量名))ENGINE = InnoDB;
? PRIMARY KEY(變量名)創建了該表的主鍵(指定列的唯一性);可以有多個主鍵;
? NOT NULL將會阻止插入沒有值得列;
? AUTO_INCREMENT 可以使得 每當增加一行時自動增量,可以用于主鍵值,每個表只允許一個AUTO_INCREMENT列,而且必須被索引(通過它成為主鍵);
? SELECT last_insert_id()函數可以獲得AUTO_INCREMENT列的最后一個值;
? 指定默認值:插入行時沒喲給有給出指定值,使用DEFAULT關鍵詞(例如:變量 類型 DEFAULT 值);
14.2 引擎類型
? 例子:ENGINE = InnoDB;
? InnoDB是一個可靠的事務處理引擎,不支持全文本搜索;
? MEMORY數據存儲在內存,而不是磁盤,速度快(適合臨時表);
? MyISAM支持全文本搜索,不支持事務處理;(默認引擎)
14.3 更改表
? ALTER TABLE 表名 ADD 變量名 類型;(增加表列)
? ALTER TABLE 表名 DROP COLUMN 變量名;(刪除表列)
? ALTER TABLE 定義外鍵,例子:ALTER TABLE 表名 ADD CONSTRAINT 變量名 FOREIGN KEY (變量名1)REFERENCES 表名(變量名1);
14.4 刪除表
? DROP TABLE 表名;
14.5 重命名表
? 例子:RENAME TABLE 新表名 TO 原表名;
15.視圖
15.1概念
? 視圖是虛擬的表,只包含使用時動態檢索數據的查詢,用來查詢存儲在別處的數據;
15.2 視圖基本操作
? CREATE VIEW(創建視圖);
? SHOW CREATE VIEW 視圖名;(查看試圖)
? DROP VIEW 視圖名(刪除視圖);
? CREATE OR REPLACE VIEW(更新試圖);
? 例子:CREATE VIEW 視圖名 AS SELECT 變量名,變量名… FROM 表名,表名…WHERE 條件;
? 視圖同表一樣,可以過濾數據等等;
16.使用存儲過程
16.1使用存儲過程
? CALL productpricing(@變量名,@變量名… );(使用存儲過程)
? CREATE PROCEDURE 存儲過程名(
? OUT 變量名 數據類型(OUT表示從存儲過程傳出),
? IN 變量名 數據類型 (IN 傳遞給存儲過程),
? INOUT 變量名 數據類型 (傳入和傳出),
? )
? BEGIN
? SELECT Avg(price) AS priceaverage
? FROM products;
? END;(創建存儲過程)
? DROP PROCEDURE 存儲過程名(刪除存儲過程);
? 檢索出存儲的數據。使用SELECT @變量名;
16.2 檢查存儲過程
? SHOW CREATE PROCEDURE ordertotal;獲取存儲過程列表的詳細信息;
17.游標
17.1創建游標
? 例子:CREATE PROCEDURE processorders()
? BEGIN
? DECLARE ordernumbers CURSOR
? FOR
? SELECT order_num FROM orders;
? END;
? 其中的DECLARE語句用于定義和命名游標;、
17.2 打開和關閉游標
? OPEN CURSOR 打開游標;例子:OPEN ordernumber;
? 關閉游標:CLOSE ordernumber;
17.3 使用游標數據(FETCH)
? 例子:CREATE PROCEDURE processorders()
? BEGIN
? DECLARE o INT;
? DECLARE ordernumbers CURSOR
? FOR
? SELECT order_num FROM orders;
? OPEN ordernumbers;
? FETCH ordernumber INTO o;
? CLOSE ordernumbers;
? END;
18.使用觸發器
? 只有DELETE,INSERT,UPDATE這三個語句才能使用觸發器;
18.1創建觸發器
? 例子:CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH SELECT 'Product added ';
? CREATE TRIGGER 表示創建觸發器,AFTER INSERT 表示此觸發器將在INSERT語句執行成功后再執行,FOR EACH ROW 對每一插入行執行;
18.2 刪除觸發器
? DROP TRIGGER 觸發器名;
18.3 使用觸發器
18.3.1 INSERT觸發器
? AFTER(BEFORE) TRIGGER;
? 可以使用一個名為NEW的虛擬表訪問被插入的行;
18.3.2 DELETE觸發器
? 可以使用一個名為OLD 的虛擬表訪問被刪除的行;
19.管理事務處理
控制事務處理
? 使用ROLLBACK來回退(撤銷)sql語句(可用來管理INSERT,UPDATE和DELETE語句);
? 提交使用COMMIT;語句;
? 回退部分事務處理:可以使用占用符(保留點),可以使用SAVEPOINT語句來創建占位符;
? 例SAVEPOINT delete;
? ROLLBACK TO delete;(使用一條ROLLBACK后自動釋放保留點,COMMIT也可以);
? set autocommit = 0表示不自動提交,可以進行更改以實現自動提交;
20.全球化與本地化
使用字符集和校對順序
? 查看字符集完整列表:SHOW CHARACTER SET;
? 查看所支持校對的完整列表:SHOW COLLATION;
? 給表指定字符集和校對:例子:CREATE TABLE table(column INT )DEFAULT CHARACTER SET Hebrew COLLATE hebrew_general_ci;
? 如果既不指定CHARACTER SET,也不指定COLLATE,則使用數據庫默認。還可指定每個列設置他們(name varchar(10)CHARACTER SET Latin1 COLLATE Latin1_general_ci;
21.安全管理
21.1 創建用戶賬號
? CREATE USER ben IDENTIFIED BY password 使用后面的口令對該賬號進行加密;
21.2 刪除用戶賬號
? DROP USER username;
21.3設置訪問權限
? 使用SHOW GRANT FOR用戶名 (可以查看用戶權限);
? USAGE 表示沒有任何權限;
? GRANT SELECT ON crashcourse . * TO 用戶名;(crashcourse表示數據庫上的所有表)有使用SELECT的權限;
? REVOKE SELECT ON crashcourse . * FROM 用戶名;(撤銷特定權限);
21.4 更改口令
? set PASSWORD for 用戶名 = PASSWORD(‘密碼’);此句用于更換密碼。
? SET PASSWORD = Password(‘密碼’)用于更新當前登陸用戶的口令;
22.數據庫維護
22.1進行維護
? ANALYZE TABLE 數據庫名;用于檢查表鍵是否正確;
? 若訪問產生不正確和不一致的結果,需要使用REPAIR TABLE 來修復相應的表;
? 如果需要從一個表中刪除大量數據,應該使用OPTIMIZE TABLE來收回所用的空間,從而優化表的性能;
22.2 查看日志文件
? 使用FLUSH LOGS語句來刷新和重新開始所有的日志文件;
23.改善性能
? 使用SHOW PROCESSLIST顯示所有進程,用KILL終結某個特定的進程;
24.數據庫索引(重點)
24.1概念
? 索引是尋找資源中特定項目的一種機制(作用就是便捷化檢索表中行和列的子集,而不需要檢查表中的每行數據)
24.2創建索引
? 在數據庫中添加索引:ALTER TABLE department ADD INDEX dept_name_idx(name);
? 索引所在列的數據具有唯一性;
24.3 索引類型
1.聚簇索引:
? 也叫簇類索引,是一種對磁盤上的數據重新組織以按指定的一個或多個列的值排序,聚簇索引的索引頁面指針指向數據頁面,所以速度快。同時每張表只能建立一個聚簇索引,所需的空間大;
? 1.1.特點:聚簇索引也稱為聚集索引,聚類索引,簇集索引,聚簇索引確定表中數據的物理順序。聚簇索引類似于電話簿,后者按姓氏排列數據。由于聚簇索引規定數據在表中的物理存儲順序,因此一個表只能包含一個聚簇索引。但該索引可以包含多個列(組合索引),就像電話簿按姓氏和名字進行組織一樣。漢語字典也是聚簇索引的典型應用,在漢語字典里,索引項是字母+聲調,字典正文也是按照先字母再聲調的順序排列。
? 聚簇索引對于那些經常要搜索范圍值的列特別有效。使用聚簇索引找到包含第一個值的行后,便可以確保包含后續索引值的行在物理相鄰。例如,如果應用程序執行的一個查詢經常檢索某一日期范圍內的記錄,則使用聚集索引可以迅速找到包含開始日期的行,然后檢索表中所有相鄰的行,直到到達結束日期。這樣有助于提高此類查詢的性能。同樣,如果對從表中檢索的數據進行排序時經常要用到某一列,則可以將該表在該列上聚簇(物理排序),避免每次查詢該列時都進行排序,從而節省成本。
? 優點:
- 聚簇索引的可以把相關的數據保存在一起;
- 使得數據訪問更快;
? 缺點:
- 雖然最大限度地提高了I/O密集型應用的性能,但如果數據全部都放在內存中,則訪問的順序就沒那么重要了,此時聚簇索引也就沒什么優勢;
- 更新聚簇索引列的代價很高,因為會強制InnoDB將每個被更新的行移動到新的位置;
- 聚簇索引可能導致全表掃描變慢,尤其是行比較稀疏,或者由于頁分裂導致數據存儲不連續的時候;
?
? 1.2.注意點:在一個頻繁發生插入操作的表上建立聚簇索引時,不要建在具有單調上升值的列(如IDENTITY)上,否則會經常引起封鎖沖突;
? 使用AUTO_INCREMENT自增列,這樣可以保證數據行是按順序寫入,對于根據主鍵做關聯操作的性能也會更好;
? 1.3. mysql中,不同的存儲引擎對索引的實現方式不同,InnoDB引擎采用的便是聚簇索引;
? InnoDB 的數據文件本身就是索引文件,B+Tree的葉子節點上的data就是數據本身,key為主鍵,這是聚簇索引。
2. 二級索引:
? 也稱為非聚簇索引(輔助索引),葉子節點上的data是主鍵 (所以聚簇索引的key,不能過長)。為什么存放的主鍵,而不是記錄所在地址呢,因為記錄所在地址并不能保證一定不會變,但主鍵可以保證。
``Mysql中的MyISAM引擎便是采用該索引,MyISAM的B+Tree的葉子節點上的data,并不是數據本身,而是數據存放的地址。在MyISAM引擎中的主索引和輔助索引沒有什么大區別,只是主索引中的key一定得是唯一的。這里的索引都是非聚簇索引。
MyISAM還采用壓縮機制存儲索引,比如,第一個索引為“her”,第二個索引為“here”,那么第二個索引會被存儲為“3,e”,這樣的缺點是同一個節點中的索引只能采用順序查找。
3.聯合索引:(最左前綴原理)
? 又稱復合索引,Mysql從左到右的使用索引中的字段,一個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3種組合進行查找,但不支持 b,c進行查找 .當最左側字段是常量引用時,索引就十分有效
? 聯合索引(復合索引)
? 聯合索引相對于一般索引只有一個字段,聯合索引可以為多個字段創建一個索引。它的原理也很簡單,比如,我們在(a,b,c)字段上創建一個聯合索引,則索引記錄會首先按照A字段排序,然后再按照B字段排序然后再是C字段,因此,聯合索引的特點:
-
第一個字段一定是有序的
-
當第一個字段值相等的時候,第二個字段又是有序的,比如下表中當A=2時所有B的值是有序排列的,依次類推,當同一個B值得所有C字段是有序排列的
| A | B | C |
| 1 | 2 | 3 |
| 1 | 4 | 2 |
| 1 | 1 | 4 |
| 2 | 3 | 5 |
| 2 | 4 | 4 |
| 2 | 4 | 6 |
| 2 | 5 | 5 |其實聯合索引的查找就跟查字典是一樣的,先根據第一個字母查,然后再根據第二個字母查,或者只根據第一個字母查,但是不能跳過第一個字母從第二個字母開始查。這就是所謂的最左前綴原理。
4.哈希索引
哈希索引(hash index)基于哈希表實現,只有精確匹配索引所有列的查詢才有效。對于每一行數據,存儲引擎都會對所有的索引列計算一個哈希碼(hash code),哈希碼是一個較小的值,并且不同鍵值的行計算出來的哈希碼也不一樣。哈希索引將所有的哈希碼存儲在索引中,同時在哈希表中保存指向每個數據行的指 針。哈希索引的限制:1.哈希索引只支持等值比較,包括=,<>,IN()。不支持任何范圍的查詢;2.哈希索引并不是按照索引值順序存儲的,所以也就無法用于排序;3。哈希索引只包含哈希值和行指針,而不存儲字段,所以不能使用索引的值來避免讀取行24.4 各索引的應用
除復合索引外,什么情況下索引被使用,什么情況下不會被使用
- 建立索引的目的就是幫助查詢,如果查尋用不到則索引就沒有必要建立。
- 如果表是經常需要更新的也不適合做索引 。頻繁更新會導致索引也會頻繁更新,降低寫的效率。
- 唯一性差的字段不適合創建索引。
- 當給一個字段創建了索引的話,而這個字段要進行like模糊查詢的話,那么這個值左邊不可以有%,因為索引查詢是要從左到右的,你如果給它加上%后,左邊的值不是確定的話,它會找不到這個索引。所以在使用like模糊查詢的時候,值得左邊不可以有%。
- order by 不可以使用在索引當中;
- or 當前后2個字段都有索引時才可以索引出來 否則不可以。
- 如果數據表過大(5w以上)則有些字段(字符型長度超過(40))不適合作為索引。查詢大量數據時,索引有效,但是慢
場景:
- 當數據多而字段值有相同的值的時候建議使用非聚簇索引;
- 當數據多而字段值沒有重復的值的時候建議使用聚簇索引;
- 當有多個字段名都經常被查詢的話建議使用復合索引;
- 普通索引不支持空值,唯一索引支持空值;
- 若是一張表的增刪改查較多而且查詢較少的話,則推薦不要創建引擎;
- 不會出現在where條件中的字段不該建立索引;
24.5 聚簇索引和非聚簇索引的區別:
?
? 注:聚簇索引中的每個葉子節點包含主鍵值、事務ID、回滾指針(rollback pointer用于事務和MVCC)和余下的列(如col2)。
? InnoDB的的二級索引的葉子節點存放的是KEY字段加主鍵值。因此,通過二級索引查詢首先查到是主鍵值,然后InnoDB再根據查到的主鍵值通過主鍵索引找到相應的數據塊。
24.6高效的索引策略
- 查詢的列如果不是獨立的,那么Mysql不會使用索引。“獨立的列”指的是索引列不能是表達式的一部分,也不能是函數的參數。(例如:WHERE 后面的表達式不能有像prod + 1 = 5 這樣的表達式,必須獨立);
- 選擇索引的列順序的法則:將選擇性最高的列放在索引最前列;
24.7 案例分析
? 我們選擇將SEX以及COUNTRY作為索引,雖然這兩個變量的選擇性不高,但是可能很多查詢會用到,還有,即使用戶查詢沒有使用SEX列,也可以通過
? 在查詢條件中新增AND SEX IN(‘m’,‘f’)來讓Mysql選擇該索引。這樣寫并不會過濾掉任何行;然后再考慮其他常見的WHERE條件的組合,像(SEX,
? country,age)上的索引,可能還需要(SEX,country,region, age)等這樣的組合索引,而如果想減少這樣的組合索引,可以使用前面的IN()的
? 技巧來避免同時需要像(SEX,country,region, age)和(SEX,country,age)這樣的索引;對于那些生僻的搜索條件,則可以忽略它們,讓Mysql
? 多掃描一些額外的行即可
25 數據庫設計的三大范式及ER圖四個成分
25.1 概念
- 設計關系數據庫時,遵從不同的規范要求,設計出合理的關系型數據庫,這些不同的規范要求被稱為不同的范式,各種范式呈遞次規范,越高的范式數據庫冗余越小。
- 數據庫的實體屬性和關系:實體(表),屬性(表中的數據),關系(各個表之間的關系);
- 第一范式:當關系模式R的所有屬性不能再被分解成更基本的數據單位(原子性)時,則稱R滿足第一范式(1NF);
- 第二范式:如果關系模式R滿足第一范式,并且R的所有非主屬性都完全依賴于R的每一個候選關鍵屬性,稱R滿足第二范式,簡記為2NF;
- 第三范式:設R是一個滿足第一范式條件的關系模式,X是R的任意屬性集,如果X非傳遞依賴于R的任意一個候選關鍵字,稱R滿足第三范式,簡記為3NF;
25.2 第一范式
? 1.每一列的屬性都是不可再分的屬性值,確保每一列的原子性(例如:聯系人的電話,郵箱等等都是不可再分的屬性);
? 2.對兩列相近的屬性,盡量進行合并,(例如:可以將聯系人的所在省份,城市等合并成地址);
25.3 第二范式
? 1.滿足1NF后,要求表的所有列都必須依賴于主鍵,而不能有任何一列與主鍵無關,及一張表描述一件事;
? 2.例如:訂單只描述訂單的信息,所有的字段都與訂單的id有關,就不能出現像產品信息這樣的與訂單無關的數據;
? 3.還有像一個人提交了多份訂單,則在訂單中就會出現該聯系人信息過多重復的情況,此時可以將該聯系人的編號提出來,和該聯系人的具體信息分開在 兩張表上,才不會造成數據冗雜;
25.4 第三范式
? 1.第三范式需要確保數據表中的每一列數據都和主鍵存在直接相關,而不能是間接相關;
? 2.比如說:Student表(學號,姓名,年齡,性別,所在院校,院校地址,院校電話)這樣一個表結構,就存在上述關系。 學號–> 所在院校 --> (院校地 址,院校電話) 這樣的表結構,我們應該拆開來,如下,(學號,姓名,年齡,性別,所在院校)–(所在院校,院校地址,院校電話);
? 3.再比如說:對于一份訂單而言,我們需要知道的是訂單號,訂單數目,賣家等,而不需要將客戶的信息添加上去,至少需要一個客戶的訂單號即可直接 與客戶信息進行連接;
?
25.5 ER圖的四個成分
? 在ER圖中有如下四個成分:
? 矩形框:表示實體,在框中記入實體名。(譬如:公司,廠商等)
? 菱形框:表示聯系,在框中記入聯系名。(譬如:屬于,擁有等)
? 橢圓形框:表示實體或聯系的屬性,將屬性名記入框中。對于主屬性名,則在其名稱下劃一下劃線。(譬如:廠家地址,公司代碼等)
? 連線:實體與屬性之間;實體與聯系之間;聯系與屬性之間用直線相連,并在直線上標注聯系的類型。(對于一對一聯系,要在兩個實體連線方向各寫 1; 對于一對多聯系,要在一的一方寫1,多的一方寫N;對于多對多關系,則要在兩個實體連線方向各寫N,M。)
總結
以上是生活随笔為你收集整理的《Mysql》必知必会读书笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第11篇 2D绘图(一)绘制简单图形
- 下一篇: SQL必知必会读书笔记