MySQL基礎常見問題集錦
MySQL基礎常見問題集錦
-
sql設定主鍵中一般規則?
- 不更新主鍵列的值 ( 要設定主鍵的列不可被更新)
- 不重用主鍵列的值 (主鍵值必須在整個主鍵列中唯一)
- 不在主鍵列中使用可能會更改的值 (主鍵列不可與其它列存在繫結更新關係)
-
不能部分使用
distinct
關鍵字 ?-
distinct
關鍵字應用於所有列而不僅是前置它的列.(
distinct
關鍵字區分粒度為的查詢結果的行 , 如果一行資料顯示不同則顯示 , 相同則只顯示一行資料)mysql> SELECT DISTINCT student_id ,student_name,student_birthday FROM student; +------------+--------------+------------------+ | student_id | student_name | student_birthday | +------------+--------------+------------------+ | 1 | java | 2021-11-01 | | 2 | python | 2021-11-01 | | 3 | c | 2021-11-01 | | 4 | java | 2021-11-02 | | 5 | java | 2021-11-02 | +------------+--------------+------------------+ 5 rows in set (0.00 sec) mysql> SELECT DISTINCT student_name,student_birthday FROM student; +--------------+------------------+ | student_name | student_birthday | +--------------+------------------+ | java | 2021-11-01 | | python | 2021-11-01 | | c | 2021-11-01 | | java | 2021-11-02 | +--------------+------------------+ 4 rows in set (0.00 sec)
-
-
limit 1,1
實際表示?limit 1,1
表示從第 2 行開始,顯示 1 行 , limit 檢索第一行為行 0 .- Mysql5.0以後
limit 4 offset 3
表示 : 表示從第 3 行開始,顯示 4 行 .
-
exist
和not exist
效率高於in
和not in
-
like '1000'
和regexp '1000'
like '1000'
匹配時匹配整列 , 即使列中包含 1000 也不會返回結果regexp '1000'
匹配時匹配整列 , 列中包含 1000 即返回結果
-
多數DBMS拼接使用
+
或||
, MySQL使用Concat(A,B,C...)
-
DATEDIFF(NOW(),'1995-12-01')
函式可計算指定日期與現在相差天數 -
STR_TO_DATE('1995,12,01','%Y,%m,%d')
函式可將指定字串轉成日期格式 -
count( 1 )
表示在查詢結果的基礎上為每行新增一列 1 的填充列 , 計算 增加1的個數達到統計效果 -
group by
使用時除聚合計算以外,select
語句中每個列都必須在group by
子句中給出 -
where
用於分組後組外過濾 ,having
用於分組時組內過濾 -
union
用於組合相同的返回列, 並去除組合後重復值 ,union all
組合後不去除重複值 -
MyISAM
引擎支援全文搜尋(僅作了解)-
程式碼
-- 建表 CREATE TABLE class( class_id INT, class_name VARCHAR(20), PRIMARY KEY (class_id), FULLTEXT(class_name) -- 指定全文搜尋需要建立的索引列 )ENGINE=MYISAM; --使用全文搜尋 SELECT class_name FROM class WHERE MATCH(class_name) AGAINST('p1');
-
-
insert into
中間可新增關鍵字LOW_PRIORITY
以降低插入資料優先順序, 保證select
優先順序 -
insert select
中語句不要求返回列名一致 , 但要求返回查詢結果返回順序與插入一致 -
update
語句更新多行時, 如果一行出現錯誤可導致整體更新失敗 ,update ignore tablename
中ignore
可跳過失敗繼續更新 -
alter table 的常用用法
-
給表新增一列
ALTER TABLE student ADD remark VARCHAR(20);
-
給表修改列名
ALTER TABLE student CHANGE remark intro varchar(30);
-
刪除列
ALTER TABLE student DROP intro;
-
修改列型別
ALTER TABLE student MODIFY remark VARCHAR(100);
-
-
SQL客戶端寫儲存過程時, 需要用
DELIMITER
命令設定結束符DELIMITER // --設定操作符 CREATE PROCEDURE query_student_info_arg( OUT student_id INT, OUT class_id INT, OUT school_id INT ) BEGIN SELECT MAX(student.`student_id`) INTO student_id FROM student ; SELECT MAX(class.`class_id`) INTO class_id FROM class ; SELECT MAX(school.`school_id`) INTO school_id FROM school ; END// DELIMITER ; -- 在將操作符設定回 ;
-
使用
EXPLAIN
命令檢視執行計劃時 ,type
列執行效率依次從最優到最差分別為:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
-
使用
EXPLAIN
命令檢視執行計劃時 ,Extra
列重要值及優化方案分別為:distinct: 一旦mysql找到了與行相聯合匹配的行,就不再搜尋了 Using index:這發生在對錶的請求列都是同一索引的部分的時候,返回的列資料只使用了索引中的資訊,而沒有再去訪問表中的行記錄。是效能高的表現。 Using where:mysql伺服器將在儲存引擎檢索行後再進行過濾。就是先讀取整行資料,再按 where 條件進行檢查,符合就留下,不符合就丟棄。 Using temporary:mysql需要建立一張臨時表來處理查詢。出現這種情況一般是要進行優化的,首先是想到用索引來優化。 Using filesort:mysql 會對結果使用一個外部索引排序,而不是按索引次序從表裡讀取行。此時mysql會根據聯接型別瀏覽所有符合條件的記錄,並儲存排序關鍵字和行指標,然後排序關鍵字並按順序檢索行資訊。這種情況下一般也是要考慮使用索引來優化的。
阿里編碼規約中關於MySQL資料庫部分
建表規約
- 【強制】 表達是與否概念的欄位,必須使用 is_xxx 的方式命名,資料型別是 unsigned tinyint
( 1 表示是, 0 表示否)。 - 【強制】 表名、欄位名必須使用小寫字母或數字, 禁止出現數字開頭,禁止兩個下劃線中間只
出現數字。資料庫欄位名的修改代價很大,因為無法進行預釋出,所以欄位名稱需要慎重考慮。 - 【強制】 表名不使用複數名詞。
- 【強制】 禁用保留字,如 desc、 range、 match、 delayed 等, 請參考 MySQL 官方保留字。
- 【強制】 主鍵索引名為 pk_欄位名;唯一索引名為 uk_欄位名; 普通索引名則為 idx_欄位名。
- 【強制】 小數型別為 decimal,禁止使用 float 和 double。
- 【強制】 如果儲存的字串長度幾乎相等,使用 char 定長字串型別。
- 【強制】 varchar 是可變長字串,不預先分配儲存空間,長度不要超過 5000,如果儲存長度
大於此值,定義欄位型別為 text,獨立出來一張表,用主鍵來對應,避免影響其它欄位索引效
率。 - 【強制】 表必備三欄位: id, gmt_create, gmt_modified。
- 【推薦】 表的命名最好是遵循“業務名稱_表的作用” 。
- 【推薦】 庫名與應用名稱儘量一致。
- 【推薦】 如果修改欄位含義或對欄位表示的狀態追加時,需要及時更新欄位註釋。
- 【推薦】 欄位允許適當冗餘,以提高查詢效能,但必須考慮資料一致。冗餘欄位應遵循:
1) 不是頻繁修改的欄位。
2) 不是唯一索引的欄位。
3) 不是 varchar 超長欄位,更不能是 text 欄位。 - 【推薦】 單錶行數超過 500 萬行或者單表容量超過 2GB,才推薦進行分庫分表。
- 【參考】 合適的字元儲存長度,不但節約資料庫表空間、節約索引儲存,更重要的是提升檢索
速度。
索引規約
- 【強制】 業務上具有唯一特性的欄位,即使是組合欄位,也必須建成唯一索引。
- 【強制】 超過三個表禁止 join。需要 join 的欄位,資料型別保持絕對一致; 多表關聯查詢時,
保證被關聯的欄位需要有索引 - 【強制】 在 varchar 欄位上建立索引時,必須指定索引長度,沒必要對全欄位建立索引,根據
實際文字區分度決定索引長度。 - 【強制】 頁面搜尋嚴禁左模糊或者全模糊,如果需要請走搜尋引擎來解決。
- 【推薦】 如果有 order by 的場景,請注意利用索引的有序性。 order by 最後的欄位是組合索
引的一部分,並且放在索引組合順序的最後,避免出現 file_sort 的情況,影響查詢效能。 - 【推薦】 利用覆蓋索引來進行查詢操作, 避免回表。
- 【推薦】 利用延遲關聯或者子查詢優化超多分頁場景。
- 【推薦】 SQL 效能優化的目標:至少要達到 range 級別, 要求是 ref 級別, 如果可以是 consts最好。
- 【推薦】 建組合索引的時候,區分度最高的在最左邊。
- 【推薦】 防止因欄位型別不同造成的隱式轉換, 導致索引失效。
文章部分筆記來源 : 《MySQL必知必會》by Ben Forta 、《Java開發手冊(泰山版)》by Alibaba
文章部落格其他地址 :
[STR_TO_DATE 函式轉換日期格式說明]: https://www.cnblogs.com/feiwenstyle/p/9531571.html "STR_TO_DATE 函式轉換日期格式說明"
[mysql explain命令說明及優化方案]: https://cloud.tencent.com/developer/article/1093229 "mysql explain詳解"