1. 程式人生 > 其它 >MySQL基礎常見問題集錦

MySQL基礎常見問題集錦

sql中設定主鍵中一般規則/不能對部分使用 `distinct` 關鍵字/SQL客戶端寫儲存過程時, 需要用 `DELIMITER ` 命令設定結束符/alter table 的常用用法/like '1000' 和 regexp '1000'的區別/EXPLAIN命令檢視執行計劃/

MySQL基礎常見問題集錦

  1. sql設定主鍵中一般規則?

    1. 不更新主鍵列的值 ( 要設定主鍵的列不可被更新)
    2. 不重用主鍵列的值 (主鍵值必須在整個主鍵列中唯一)
    3. 不在主鍵列中使用可能會更改的值 (主鍵列不可與其它列存在繫結更新關係)
  2. 不能部分使用 distinct 關鍵字 ?

    1. 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)
      
  3. limit 1,1 實際表示?

    1. limit 1,1 表示從第 2 行開始,顯示 1 行 , limit 檢索第一行為行 0 .
    2. Mysql5.0以後 limit 4 offset 3 表示 : 表示從第 3 行開始,顯示 4 行 .
  4. existnot exist 效率高於 innot in

  5. like '1000'regexp '1000'

    1. like '1000' 匹配時匹配整列 , 即使列中包含 1000 也不會返回結果
    2. regexp '1000' 匹配時匹配整列 , 列中包含 1000 即返回結果
  6. 多數DBMS拼接使用 + || , MySQL使用Concat(A,B,C...)

    函式實現

  7. DATEDIFF(NOW(),'1995-12-01') 函式可計算指定日期與現在相差天數

  8. STR_TO_DATE('1995,12,01','%Y,%m,%d') 函式可將指定字串轉成日期格式

  9. count( 1 )表示在查詢結果的基礎上為每行新增一列 1 的填充列 , 計算 增加1的個數達到統計效果

  10. group by 使用時除聚合計算以外, select語句中每個列都必須在group by子句中給出

  11. where 用於分組後組外過濾 , having用於分組時組內過濾

  12. union 用於組合相同的返回列, 並去除組合後重復值 , union all 組合後不去除重複值

  13. MyISAM引擎支援全文搜尋(僅作了解)

    1. 程式碼

      -- 建表
      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');
      
  14. insert into中間可新增關鍵字LOW_PRIORITY以降低插入資料優先順序, 保證select優先順序

  15. insert select 中語句不要求返回列名一致 , 但要求返回查詢結果返回順序與插入一致

  16. update語句更新多行時, 如果一行出現錯誤可導致整體更新失敗 , update ignore tablenameignore可跳過失敗繼續更新

  17. alter table 的常用用法

    1. 給表新增一列

      ALTER TABLE student ADD remark VARCHAR(20);
      
    2. 給表修改列名

      ALTER TABLE student CHANGE remark intro varchar(30);
      
    3. 刪除列

      ALTER TABLE student DROP intro;
      
    4. 修改列型別

      ALTER TABLE student MODIFY remark VARCHAR(100);
      
  18. 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 ; -- 在將操作符設定回 ;
    
  19. 使用EXPLAIN命令檢視執行計劃時 , type 列執行效率依次從最優到最差分別為:

    system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
    
  20. 使用EXPLAIN命令檢視執行計劃時 , Extra列重要值及優化方案分別為:

    distinct: 一旦mysql找到了與行相聯合匹配的行,就不再搜尋了
    Using index:這發生在對錶的請求列都是同一索引的部分的時候,返回的列資料只使用了索引中的資訊,而沒有再去訪問表中的行記錄。是效能高的表現。
    Using where:mysql伺服器將在儲存引擎檢索行後再進行過濾。就是先讀取整行資料,再按 where 條件進行檢查,符合就留下,不符合就丟棄。
    Using temporary:mysql需要建立一張臨時表來處理查詢。出現這種情況一般是要進行優化的,首先是想到用索引來優化。
    Using filesort:mysql 會對結果使用一個外部索引排序,而不是按索引次序從表裡讀取行。此時mysql會根據聯接型別瀏覽所有符合條件的記錄,並儲存排序關鍵字和行指標,然後排序關鍵字並按順序檢索行資訊。這種情況下一般也是要考慮使用索引來優化的。
    

阿里編碼規約中關於MySQL資料庫部分

建表規約

  1. 【強制】 表達是與否概念的欄位,必須使用 is_xxx 的方式命名,資料型別是 unsigned tinyint
    ( 1 表示是, 0 表示否)。
  2. 【強制】 表名、欄位名必須使用小寫字母或數字, 禁止出現數字開頭,禁止兩個下劃線中間只
    出現數字。資料庫欄位名的修改代價很大,因為無法進行預釋出,所以欄位名稱需要慎重考慮。
  3. 【強制】 表名不使用複數名詞。
  4. 【強制】 禁用保留字,如 desc、 range、 match、 delayed 等, 請參考 MySQL 官方保留字。
  5. 【強制】 主鍵索引名為 pk_欄位名;唯一索引名為 uk_欄位名; 普通索引名則為 idx_欄位名。
  6. 【強制】 小數型別為 decimal,禁止使用 float 和 double。
  7. 【強制】 如果儲存的字串長度幾乎相等,使用 char 定長字串型別。
  8. 【強制】 varchar 是可變長字串,不預先分配儲存空間,長度不要超過 5000,如果儲存長度
    大於此值,定義欄位型別為 text,獨立出來一張表,用主鍵來對應,避免影響其它欄位索引效
    率。
  9. 【強制】 表必備三欄位: id, gmt_create, gmt_modified。
  10. 【推薦】 表的命名最好是遵循“業務名稱_表的作用” 。
  11. 【推薦】 庫名與應用名稱儘量一致。
  12. 【推薦】 如果修改欄位含義或對欄位表示的狀態追加時,需要及時更新欄位註釋。
  13. 【推薦】 欄位允許適當冗餘,以提高查詢效能,但必須考慮資料一致。冗餘欄位應遵循:
    1) 不是頻繁修改的欄位。
    2) 不是唯一索引的欄位。
    3) 不是 varchar 超長欄位,更不能是 text 欄位。
  14. 【推薦】 單錶行數超過 500 萬行或者單表容量超過 2GB,才推薦進行分庫分表。
  15. 【參考】 合適的字元儲存長度,不但節約資料庫表空間、節約索引儲存,更重要的是提升檢索
    速度。

索引規約

  1. 【強制】 業務上具有唯一特性的欄位,即使是組合欄位,也必須建成唯一索引。
  2. 【強制】 超過三個表禁止 join。需要 join 的欄位,資料型別保持絕對一致; 多表關聯查詢時,
    保證被關聯的欄位需要有索引
  3. 【強制】 在 varchar 欄位上建立索引時,必須指定索引長度,沒必要對全欄位建立索引,根據
    實際文字區分度決定索引長度。
  4. 【強制】 頁面搜尋嚴禁左模糊或者全模糊,如果需要請走搜尋引擎來解決。
  5. 【推薦】 如果有 order by 的場景,請注意利用索引的有序性。 order by 最後的欄位是組合索
    引的一部分,並且放在索引組合順序的最後,避免出現 file_sort 的情況,影響查詢效能。
  6. 【推薦】 利用覆蓋索引來進行查詢操作, 避免回表。
  7. 【推薦】 利用延遲關聯或者子查詢優化超多分頁場景。
  8. 【推薦】 SQL 效能優化的目標:至少要達到 range 級別, 要求是 ref 級別, 如果可以是 consts最好。
  9. 【推薦】 建組合索引的時候,區分度最高的在最左邊。
  10. 【推薦】 防止因欄位型別不同造成的隱式轉換, 導致索引失效。

文章部分筆記來源 : 《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詳解"