一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫 - Mysql - 學(xué)習(xí) MySQL 的 28 個小技巧

學(xué)習(xí) MySQL 的 28 個小技巧

2022-01-04 22:47Lucifer三思而后行Lucifer Mysql

無論是運維、開發(fā)、測試,還是架構(gòu)師,數(shù)據(jù)庫技術(shù)都是一個 必備加薪神器,那么,一直說學(xué)習(xí)數(shù)據(jù)庫、學(xué) MySQL,到底是要學(xué)習(xí)它的哪些東西呢?

學(xué)習(xí) MySQL 的 28 個小技巧

前言

無論是運維、開發(fā)、測試,還是架構(gòu)師,數(shù)據(jù)庫技術(shù)都是一個 必備加薪神器,那么,一直說學(xué)習(xí)數(shù)據(jù)庫、學(xué) MySQL,到底是要學(xué)習(xí)它的哪些東西呢?

一、如何快速掌握 MySQL?

1.培養(yǎng)興趣

興趣是最好的老師,不論學(xué)習(xí)什么知識,興趣都可以極大地提高學(xué)習(xí)效率。不管學(xué)習(xí) MySQL5.7 還是 MySQL8.0 都不例外!

2.夯實 SQL 基礎(chǔ)

計算機領(lǐng)域的技術(shù)非常強調(diào)基礎(chǔ),剛開始學(xué)習(xí)可能還認識不到這一點。隨著技術(shù)應(yīng)用的深 入,只有有著扎實的基礎(chǔ)功底,才能在技術(shù)的道路上走得更快、更遠。對于 MySQL 的學(xué)習(xí)來說, SQL 語句 是其中最為基礎(chǔ)的部分,很多操作都是通過 SQL 語句來實現(xiàn)的。所以在學(xué)習(xí)的過程中, 讀者要多編寫 SQL 語句,對于同一個功能,使用不同的實現(xiàn)語句來完成,從而深刻理解其不同之處。

這里可以參考文章:基礎(chǔ)篇:數(shù)據(jù)庫 SQL 入門教程

3.及時學(xué)習(xí)新知識

正確、有效地利用搜索引擎,可以搜索到很多關(guān)于 MySQL 的相關(guān)知識。同時,參考別 人解決問題的思路,也可以吸取別人的經(jīng)驗,及時獲取最新的技術(shù)資料。

4.多實踐操作

數(shù)據(jù)庫系統(tǒng)具有極強的操作性,需要多動手上機操作。在實際操作的過程中才能發(fā)現(xiàn)問題, 并思考解決問題的方法和思路,只有這樣才能提高實戰(zhàn)的操作能力。

二、技巧分享

下面分享學(xué)習(xí) MySQL 的 28 個不得不知道的小技巧!

1、MySQL 中如何使用特殊字符?

諸如單引號 ',雙引號 ",反斜線 \ 等符號,這些符號在 MySQL 中不能直接輸入使用,否則會產(chǎn)生意料之外的結(jié)果。

舉例:

假設(shè) Lucifer 表中需要存入一行記錄,值為 lucifer's dog,其中的單引號 ' 號,如果不做轉(zhuǎn)義,則無法成功執(zhí)行:

  1. mysql> create table lucifer (id int,name char(100));
  2. Query OK, 0 rows affected (0.02 sec)
  3.  
  4. mysql> insert into lucifer values (1,'lucifer's dog');
  5. '>
  6. '> mysql>
  7.  
  8. ^C
  9. mysql>

在 MySQL 中,這些特殊字符稱為轉(zhuǎn)義字符,在輸入時需要以反斜線符號 \ 開頭,所以在使用單引號和雙引號時應(yīng)分別輸入 \' 或者 \",輸入反斜線時應(yīng)該輸入 \\,其他特殊字符還有回車符 \r,換行符 \n,制表符 \tab,退格符 \b 等。

  1. mysql> create table lucifer (id int,name char(100));
  2. Query OK, 0 rows affected (0.03 sec)
  3.  
  4. mysql> insert into lucifer values (1,'lucifer\'s dog');
  5. Query OK, 1 row affected (0.00 sec)
  6.  
  7. mysql> select * from lucifer;
  8. +------+---------------+
  9. | id | name |
  10. +------+---------------+
  11. | 1 | lucifer's dog |
  12. +------+---------------+
  13. 1 row in set (0.00 sec)
  14. mysql>

注意: 在向數(shù)據(jù)庫中插入這些特殊字符時,一定要進行轉(zhuǎn)義處理。

2、MySQL 中可以存儲文件嗎?

答案當(dāng)然是可以的!

MySQL 中的 BLOB 和 TEXT 字段類型可以存儲數(shù)據(jù)量較大的文件,可以使用這些數(shù)據(jù)類型 存儲圖像、聲音或者是大容量的文本內(nèi)容,例如網(wǎng)頁或者文檔。

  1. mysql> create table view(id int unsigned NOT NULL AUTO_INCREMENT, catid int,title varchar(256),picture MEDIUMBLOB, content TEXT,PRIMARY KEY (id));
  2. Query OK, 0 rows affected (0.03 sec)
  3.  
  4. mysql> show fields from view;
  5. +---------+--------------+------+-----+---------+----------------+
  6. | Field | Type | Null | Key | Default | Extra |
  7. +---------+--------------+------+-----+---------+----------------+
  8. | id | int unsigned | NO | PRI | NULL | auto_increment |
  9. | catid | int | YES | | NULL | |
  10. | title | varchar(256) | YES | | NULL | |
  11. | picture | mediumblob | YES | | NULL | |
  12. | content | text | YES | | NULL | |
  13. +---------+--------------+------+-----+---------+----------------+
  14. 5 rows in set (0.00 sec)
  15.  
  16. mysql>

雖然使用 BLOB 或者 TEXT 可 以存儲大容量的數(shù)據(jù),但是對這些字段的處理會降低數(shù)據(jù)庫的性能。

注意: 如果并非必要,可以選擇只儲存文件的路徑。

3、MySQL 中如何執(zhí)行區(qū)分大小寫的字符串比較?

MySQL 是 不區(qū)分大小寫 的,因此字符串比較函數(shù)也不區(qū)分大小寫。

  1. mysql> select 'TRUE' from dual where 'DOG' = 'dog';
  2. +------+
  3. | TRUE |
  4. +------+
  5. | TRUE |
  6. +------+
  7. 1 row in set (0.00 sec)

如果想執(zhí)行區(qū)分大小寫的比較,可以在字符串前面添加 BINARY 關(guān)鍵字。

  1. mysql> select 'TRUE' from dual where BINARY'DOG' = 'dog';
  2. Empty set (0.00 sec)
  3.  
  4. mysql>

例如默認情況下,’DOG‘=’dog‘ 返回結(jié)果為 TRUE,如果使用 BINARY 關(guān)鍵字,BINARY’DOG’=‘dog’ 結(jié)果為 FALSE,在區(qū)分大小寫的情況下,’DOG’ 與 ’dog’ 并不相同。

4、如何從日期時間值中獲取年、月、日等部分日期或時間值?

MySQL 中,日期時間值以字符串形式存儲在數(shù)據(jù)表中,因此可以使用字符串函數(shù)分別截取日期時間值的不同部分。

  1. mysql> create table lucifer(date date);
  2. Query OK, 0 rows affected (0.04 sec)
  3.  
  4. mysql> show fields from lucifer;
  5. +-------+------+------+-----+---------+-------+
  6. | Field | Type | Null | Key | Default | Extra |
  7. +-------+------+------+-----+---------+-------+
  8. | date | date | YES | | NULL | |
  9. +-------+------+------+-----+---------+-------+
  10. 1 row in set (0.00 sec)
  11.  
  12. mysql> insert into lucifer values (now());
  13. Query OK, 1 row affected, 1 warning (0.00 sec)
  14.  
  15. mysql> select * from lucifer;
  16. +------------+
  17. | date |
  18. +------------+
  19. | 2021-11-25 |
  20. +------------+
  21. 1 row in set (0.00 sec)

例如某個名稱為 date 的字段有值 2021-11-25,如果只需要獲得年值,可以輸入 LEFT(date, 4),這樣就獲得了字符串左邊開始長度為 4 的子字符串,即 YEAR 部分的值;

  1. mysql> select LEFT(date, 4) from lucifer;
  2. +---------------+
  3. | LEFT(date, 4) |
  4. +---------------+
  5. | 2021 |
  6. +---------------+
  7. 1 row in set (0.00 sec)

如果要獲取月份值,可以輸入 MID(date,6,2),字符串第 6 個字符開始,長度為 2 的子字符串正好為 date 中的月份值。同理,讀者可以根據(jù)其他日期和時間的位置,計算并獲取相應(yīng)的值。

  1. mysql> select MID(date,6,2) from lucifer;
  2. +---------------+
  3. | MID(date,6,2) |
  4. +---------------+
  5. | 11 |
  6. +---------------+
  7. 1 row in set (0.00 sec)

5、如何改變默認的字符集?

CONVERT() 函數(shù)改變指定字符串的默認字符集!

MySQL 的安裝和配置過程中,其中的一個步驟是可以選擇 MySQL 的默認字符集。但是,如果只改變字符集,沒有必要把配置過程重新執(zhí)行一遍,在這里,一個簡單的方式是 修改配置文件。

讀者可以在修改字符集時使用 SHOW VARIABLES LIKE 'character_set_%'; 或者 status 命令查看當(dāng)前字符集,以進行對比。

  1. mysql> SHOW VARIABLES LIKE 'character_set_%';
  2. +--------------------------+----------------------------+
  3. | Variable_name | Value |
  4. +--------------------------+----------------------------+
  5. | character_set_client | latin1 |
  6. | character_set_connection | latin1 |
  7. | character_set_database | utf8mb3 |
  8. | character_set_filesystem | binary |
  9. | character_set_results | latin1 |
  10. | character_set_server | utf8mb4 |
  11. | character_set_system | utf8mb3 |
  12. | character_sets_dir | /usr/share/mysql/charsets/ |
  13. +--------------------------+----------------------------+
  14. 8 rows in set (0.00 sec)
  15.  
  16. mysql> status
  17. --------------
  18. mysql Ver 8.0.26-0ubuntu0.21.04.3 for Linux on aarch64 ((Ubuntu))
  19.  
  20. Connection id: 10
  21. Current database:
  22. Current user: root@localhost
  23. SSL: Not in use
  24. Current pager: stdout
  25. Using outfile: ''
  26. Using delimiter: ;
  27. Server version: 8.0.26-0ubuntu0.21.04.3 (Ubuntu)
  28. Protocol version: 10
  29. Connection: Localhost via UNIX socket
  30. Server characterset: utf8mb4
  31. Db characterset: utf8mb4
  32. Client characterset: latin1
  33. Conn. characterset: latin1
  34. UNIX socket: /var/run/mysqld/mysqld.sock
  35. Binary data as: Hexadecimal
  36. Uptime: 36 min 55 sec
  37.  
  38. Threads: 2 Questions: 325 Slow queries: 0 Opens: 181 Flush tables: 3 Open tables: 69 Queries per second avg: 0.146
  39. --------------
  40.  
  41. mysql>

MySQL 配置文件名稱為 my.cnf,該文件在 MySQL 的安裝目錄下面。修改配置文件中的 default-character-set 和 character-set-server 參數(shù)值,將其改為想要的字符集名稱,如 gbk、gb2312、latinl 等,修改完之后重新啟動 MySQL 服務(wù),即可生效。

  1. ## 找到 my.cnf 位置
  2. root@modb:~# find /etc -iname my.cnf -print
  3. /etc/alternatives/my.cnf
  4. /etc/mysql/my.cnf
  5.  
  6. ## 修改字符集
  7. 在[client ]下面加入
  8. default-character-set=utf8
  9. 在[ mysqld ] 下面加
  10. character_set_server=utf8
  11.  
  12. ## 重啟 mysql 生效
  13. service mysql restart

此時,登錄 MySQL 后使用 SHOW VARIABLES LIKE 'character_set_%'; 或者 status 命令查看修改結(jié)果!

6、DISTINCT 可以應(yīng)用于所有的列嗎?

查詢結(jié)果中,如果需要對列進行降序排序,可以使用 DESC,這個關(guān)鍵字只能對其前面的列 進行降序排列。

  1. mysql> select * from lucifer;
  2. +------+----------+
  3. | id | name |
  4. +------+----------+
  5. | 1 | lucifer |
  6. | 2 | lucifer1 |
  7. | 3 | lucifer2 |
  8. +------+----------+
  9. 3 rows in set (0.00 sec)
  10.  
  11. mysql> select * from lucifer order by id desc;
  12. +------+----------+
  13. | id | name |
  14. +------+----------+
  15. | 3 | lucifer2 |
  16. | 2 | lucifer1 |
  17. | 1 | lucifer |
  18. +------+----------+
  19. 3 rows in set (0.00 sec)

例如,要對多列都進行降序排序,必須要在每一列的列名后面加 DESC 關(guān)鍵字。

  1. mysql> select * from lucifer order by id desc,name desc;
  2. +------+----------+
  3. | id | name |
  4. +------+----------+
  5. | 3 | lucifer2 |
  6. | 2 | lucifer1 |
  7. | 1 | lucifer |
  8. +------+----------+
  9. 3 rows in set (0.00 sec)

而 DISTINCT 不同,DISTINCT 不能部分使用。換句話說,DISTINCT 關(guān)鍵字應(yīng)用于所有列而不僅是它后面的第一個指定列。

例如,查詢 2 個字段 sex,age,如果不同記錄的這 2 個字段的組合值都不同,則所有記錄都會被查詢出來。

  1. mysql> select * from lucifer;
  2. +------+-----------+--------+------+
  3. | id | name | sex | age |
  4. +------+-----------+--------+------+
  5. | 1 | xiaoli | male | 20 |
  6. | 1 | xiaoliu | female | 21 |
  7. | 1 | xiaozhang | female | 21 |
  8. | 1 | xiaowu | female | 21 |
  9. +------+-----------+--------+------+
  10. 4 rows in set (0.00 sec)
  11.  
  12. mysql> select distinct sex,age from lucifer;
  13. +--------+------+
  14. | sex | age |
  15. +--------+------+
  16. | male | 20 |
  17. | female | 21 |
  18. +--------+------+
  19. 2 rows in set (0.00 sec)
  20.  
  21. mysql>

7、ORDER BY 可以和 LIMIT 混合使用嗎?

在使用 ORDER BY 子句時,應(yīng)保證其位于 FROM 子句之后,如果使用 LIMIT,則必須位于 ORDER BY 之后,如果子句順序不正確,MySQL 將產(chǎn)生錯誤消息。

正確用法:

  1. mysql> select * from lucifer order by age desc limit 2,4;
  2. +------+--------+--------+------+
  3. | id | name | sex | age |
  4. +------+--------+--------+------+
  5. | 1 | xiaowu | female | 21 |
  6. | 1 | xiaoli | male | 20 |
  7. +------+--------+--------+------+
  8. 2 rows in set (0.00 sec)

錯誤用法:

  1. mysql> select * from lucifer limit 2,4 order by age desc;
  2. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'order by age desc' at line 1
  3. mysql>

8、什么時候使用引號?

在查詢的時候,會看到在 WHERE 子句中使用條件,有的值加上了單引號,而有的值未加。

  1. mysql> select * from lucifer where sex = 'female';
  2. +------+-----------+--------+------+
  3. | id | name | sex | age |
  4. +------+-----------+--------+------+
  5. | 1 | xiaoliu | female | 21 |
  6. | 1 | xiaozhang | female | 21 |
  7. | 1 | xiaowu | female | 21 |
  8. +------+-----------+--------+------+
  9. 3 rows in set (0.00 sec)
  10.  
  11. mysql>

單引號用來限定字符串,如果將值與字符串類型列進行比較,則需要限定引號;而用來與數(shù)值進行比較則不需要用引號。

  1. mysql> select * from lucifer where age = 20;
  2. +------+--------+------+------+
  3. | id | name | sex | age |
  4. +------+--------+------+------+
  5. | 1 | xiaoli | male | 20 |
  6. +------+--------+------+------+
  7. 1 row in set (0.00 sec)
  8.  
  9. mysql>

9、在 WHERE子句中 AND 和 OR 必須使用圓括號嗎?

任何時候使用具有 AND 和 OR 操作符的 WHERE 子句,都應(yīng)該使用圓括號明確操作順序。

  1. mysql> select * from lucifer where (age = 20 or sex = 'female') and name != 'xiaowu';
  2. +------+-----------+--------+------+
  3. | id | name | sex | age |
  4. +------+-----------+--------+------+
  5. | 1 | xiaoli | male | 20 |
  6. | 1 | xiaoliu | female | 21 |
  7. | 1 | xiaozhang | female | 21 |
  8. +------+-----------+--------+------+
  9. mysql> 3 rows in set (0.00 sec)

如果條件較多,即使能確定計算次序,默認的計算次序也可能會使 SQL 語句不易理解,因此使 用括號明確操作符的次序,是一個好的習(xí)慣。

10、更新或者刪除表時必須指定 WHERE子 句嗎?

個人建議所有的 UPDATE 和 DELETE 語句全都在 WHERE 子句中指定條件。

  1. mysql> update lucifer set age = 22 where name = 'xiaoliu';
  2. Query OK, 1 row affected (0.01 sec)
  3. Rows matched: 1 Changed: 1 Warnings: 0
  4.  
  5. mysql> select * from lucifer where name = 'xiaoliu';
  6. +------+---------+--------+------+
  7. | id | name | sex | age |
  8. +------+---------+--------+------+
  9. | 1 | xiaoliu | female | 22 |
  10. +------+---------+--------+------+
  11. 1 row in set (0.00 sec)
  12.  
  13. mysql>

如果省略 WHERE 子句,則 UPDATE 或 DELETE 將被應(yīng)用到表中所有的行。

  1. mysql> update lucifer set age = 22;
  2. Query OK, 3 rows affected (0.01 sec)
  3. Rows matched: 4 Changed: 3 Warnings: 0
  4.  
  5. mysql> select * from lucifer;
  6. +------+-----------+--------+------+
  7. | id | name | sex | age |
  8. +------+-----------+--------+------+
  9. | 1 | xiaoli | male | 22 |
  10. | 1 | xiaoliu | female | 22 |
  11. | 1 | xiaozhang | female | 22 |
  12. | 1 | xiaowu | female | 22 |
  13. +------+-----------+--------+------+
  14. 4 rows in set (0.00 sec)
  15.  
  16. mysql>

因此,除非確實打算更新或者刪除所有記錄,否則要注意使用不帶 WHERE 子句的 UPDATE 或 DELETE 語句。

注意: 建議在對表進行更新和刪除操作之前,使用 SELECT 語句確認需要刪除的記錄,以免造成無法挽回的結(jié)果。

11、索引對數(shù)據(jù)庫性能如此重要,應(yīng)該如何使用它?

索引的優(yōu)點:

  • 通過創(chuàng)建唯一索引可以保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性。
  • 可以給所有的 MySQL 列類型設(shè)置索引。
  • 可以大大加快數(shù)據(jù)的查詢速度,這是使用索引最主要的原因。
  • 在實現(xiàn)數(shù)據(jù)的參考完整性方面可以加速表與表之間的連接。
  • 在使用分組和排序子句進行數(shù)據(jù)查詢時也可以顯著減少查詢中分組和排序的時間

缺點:

  • 創(chuàng)建和維護索引組要耗費時間,并且隨著數(shù)據(jù)量的增加所耗費的時間也會增加。
  • 索引需要占磁盤空間,除了數(shù)據(jù)表占數(shù)據(jù)空間以外,每一個索引還要占一定的物理空間。如果有大量的索引,索引文件可能比數(shù)據(jù)文件更快達到最大文件尺寸。
  • 當(dāng)對表中的數(shù)據(jù)進行增加、刪除和修改的時候,索引也要動態(tài)維護,這樣就降低了數(shù)據(jù)的維護速度。

使用索引時,需要綜合考慮索引的優(yōu)點和缺點。

為數(shù)據(jù)庫選擇正確的索引是一項復(fù)雜的任務(wù)。如果索引列較少,則需要的磁盤空間和維護開銷 都較少。如果在一個大表上創(chuàng)建了多種組合索引,索引文件也會膨脹很快。

而另一方面,索引較多 可覆蓋更多的查詢。可能需要試驗若干不同的設(shè)計,才能找到最有效的索引。可以添加、修改和刪 除索引而不影響數(shù)據(jù)庫架構(gòu)或應(yīng)用程序設(shè)計。

因此,應(yīng)嘗試多個不同的索引從而建立最優(yōu)的索引。

12、盡量使用短索引(前綴索引)

對字符串類型的字段進行索引,如果可能應(yīng)該指定一個前綴長度。

例如,如果有一個 CHAR(255) 的列,如果在前 10 個或 30 個字符內(nèi),多數(shù)值是惟一的,則不需要對整個列進行索引。

  1. mysql> select * from lucifer;
  2. +------+-----------+--------+------+
  3. | id | name | sex | age |
  4. +------+-----------+--------+------+
  5. | 1 | xiaoli | male | 22 |
  6. | 1 | xiaoliu | female | 22 |
  7. | 1 | xiaozhang | female | 22 |
  8. | 1 | xiaowu | female | 22 |
  9. +------+-----------+--------+------+
  10. 4 rows in set (0.00 sec)
  11.  
  12. mysql> create index idx_lucifer_name on lucifer (name(4));
  13. Query OK, 0 rows affected (0.03 sec)
  14. Records: 0 Duplicates: 0 Warnings: 0
  15.  
  16. mysql> show index from lucifer;
  17. +---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
  18. | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
  19. +---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
  20. | lucifer | 1 | idx_lucifer_name | 1 | name | A | 1 | 4 | NULL | YES | BTREE | | | YES | NULL |
  21. +---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
  22. 1 row in set (0.01 sec)
  23.  
  24. mysql>

短索引不僅可以提高查詢速度而且可以節(jié)省磁盤空間、減少 I/O 操作。

13、MySQL 存儲過程和函數(shù)有什么區(qū)別?

在本質(zhì)上它們都是存儲程序。

函數(shù):

  • 只能通過 return 語句返回單個值或者表對象;
  • 限制比較多,不能用臨時表,只能用表變量,還有一些函數(shù)都不可用等等;
  • 可以嵌入在 SQL 語句中使用,可以在 SELECT 語句中作為查詢語句的一個部分調(diào)用;

存儲過程:

  • 不允許執(zhí)行 return,但是可以通過 out 參數(shù)返回多個值;
  • 限制相對就比較少;
  • 一般是作為一個獨立的部分來執(zhí)行;

14、存儲過程中的內(nèi)容可以改變嗎?

不可以!

目前,MySQL 還不提供對已存在的存儲過程代碼的修改,如果必須要修改存儲過程,必須使用 DROP 語句刪除之后,再重新編寫代碼,或者創(chuàng)建一個新的存儲過程。

不得不說,這方面還是 Oracle 做的比較好。

15、存儲過程中可以調(diào)用其他存儲過程嗎?

可以!

存儲過程包含用戶定義的 SQL 語句集合,可以使用 CALL 語句調(diào)用存儲過程,當(dāng)然在存儲過程中也可以使用 CALL 語句調(diào)用其他存儲過程,但是不能使用 DROP 語句刪除其他存儲過程。

16、存儲過程的參數(shù)不要與數(shù)據(jù)表中的字段名相同。

在定義存儲過程參數(shù)列表時,應(yīng)注意把參數(shù)名與數(shù)據(jù)庫表中的字段名區(qū)別開來,否則將出 現(xiàn)無法預(yù)期的結(jié)果。

17、存儲過程的參數(shù)可以使用中文嗎?

一般情況下,可能會出現(xiàn)存儲過程中傳入中文參數(shù)的情況,例如某個存儲過程根據(jù)用戶的 名字查找該用戶的信息,傳入的參數(shù)值可能是中文。這時需要在定義存儲過程的時候,在后面加 上 character set gbk,不然調(diào)用存儲過程使用中文參數(shù)會出錯,比如定義 userInfo 存儲過程,代碼 如下:

CREATE PROCEDURE useInfo(IN u_name VARCHAR(50) character set gbk, OUT u_age INT)

18、MySQL 中視圖和表的區(qū)別以及聯(lián)系是什么?

兩者的區(qū)別:

  • 視圖是已經(jīng)編譯好的 SQL 語句,是基于 SQL 語句的結(jié)果集的可視化的表,而表不是;
  • 視圖沒有實際的物理記錄,而基本表有;
  • 表是內(nèi)容,視圖是窗口;
  • 表占用物理空間而視圖不占用物理空間,視圖只是邏輯概念的存在,表可以及時對它進行修改,但視圖只能用創(chuàng)建的語句來修改;
  • 視圖是查看數(shù)據(jù)表的一種方法,可以查詢數(shù)據(jù)表中某些字段構(gòu)成的數(shù)據(jù),只是一些SQL 語句的集合。從安全的角度來說,視圖可以防止用戶接觸數(shù)據(jù)表,因而用戶不知道表結(jié)構(gòu);
  • 表屬于全局模式中的表,是實表;視圖屬于局部模式的表,是虛表;
  • 視圖的建立和刪除只影響視圖本身,不影響對應(yīng)的基本表;

兩者的聯(lián)系:

視圖(view)是在基本表之上建立的表,它的結(jié)構(gòu)(即所定義的列)和內(nèi)容(即所有記錄) 都來自基本表,它依據(jù)基本表存在而存在。

一個視圖可以對應(yīng)一個基本表,也可以對應(yīng)多個基本表。

視圖是基本表的抽象和在邏輯意義上建立的新關(guān)系。

19、使用觸發(fā)器時須特別注意!

在使用觸發(fā)器的時候需要注意,對于相同的表,相同的事件只能創(chuàng)建一個觸發(fā)器。

  1. mysql> create trigger lucifer_tri before insert on lucifer for each row set NEW.id=NEW.id+1;
  2. Query OK, 0 rows affected (0.01 sec)
  3.  
  4. mysql>
  5. mysql>
  6. mysql> select * from lucifer;
  7. +------+-----------+--------+------+
  8. | id | name | sex | age |
  9. +------+-----------+--------+------+
  10. | 1 | xiaoli | male | 22 |
  11. | 1 | xiaoliu | female | 22 |
  12. | 1 | xiaozhang | female | 22 |
  13. | 1 | xiaowu | female | 22 |
  14. | 1 | lucifer | male | 20 |
  15. | 1 | lucifer | male | 20 |
  16. +------+-----------+--------+------+
  17. 6 rows in set (0.00 sec)
  18.  
  19. mysql> insert into lucifer values(1,'lucifer','male',20);
  20. Query OK, 1 row affected (0.00 sec)
  21.  
  22. mysql> select * from lucifer;
  23. +------+-----------+--------+------+
  24. | id | name | sex | age |
  25. +------+-----------+--------+------+
  26. | 1 | xiaoli | male | 22 |
  27. | 1 | xiaoliu | female | 22 |
  28. | 1 | xiaozhang | female | 22 |
  29. | 1 | xiaowu | female | 22 |
  30. | 1 | lucifer | male | 20 |
  31. | 1 | lucifer | male | 20 |
  32. | 2 | lucifer | male | 20 |
  33. +------+-----------+--------+------+
  34. 7 rows in set (0.00 sec)

比如對表 lucifer 創(chuàng)建了一個 BEFORE INSERT 觸發(fā)器,那么如果對表 lucifer 再次創(chuàng)建一個 BEFORE INSERT 觸發(fā)器,MySQL 將會報錯,此時,只可以在表 lucifer 上創(chuàng)建 AFTER INSERT 或者 BEFORE UPDATE 類型的觸發(fā)器。

  1. mysql> create trigger lucifer_tri before insert on lucifer for each row set NEW.id=NEW.id+1;
  2. ERROR 1359 (HY000): Trigger already exists
  3. mysql>

靈活的運用觸發(fā)器將為操作省去很多麻煩。

20、及時刪除不再需要的觸發(fā)器觸發(fā)器

定義之后,每次執(zhí)行觸發(fā)事件,都會激活觸發(fā)器并執(zhí)行觸發(fā)器中的語句。

如果需求發(fā)生變化,而觸發(fā)器沒有進行相應(yīng)的改變或者刪除,則觸發(fā)器仍然會執(zhí)行舊的語句,從而會影響新的數(shù)據(jù)的完整性。

  1. mysql> drop trigger lucifer_tri;
  2. Query OK, 0 rows affected (0.03 sec)
  3.  
  4. mysql>

因此,要將不再使用的觸發(fā)器及時刪除。

21、應(yīng)該使用哪種方法創(chuàng)建用戶?(3種方式)

創(chuàng)建用戶有 3 種方法:

  • 使用 CREATE USER 語句創(chuàng)建用戶
  • 在 mysql.user 表中添加用戶
  • 使用 GRANT 語句創(chuàng)建用戶(僅限 MySQL 8 版本以下使用)

一般情況, 最好使用 GRANT 或者 CREATE USER 語句,而不要直接將用戶信息插入 user 表,因為 user 表中存儲了全局級別的權(quán)限以及其他的賬戶信息,如果意外破壞了 user 表中的記錄,則可能會對 MySQL 服務(wù)器造成很大影響。

  1. -- 使用 CREATE USER 語句創(chuàng)建用戶
  2. mysql> create user 'lucifer'@'localhost' identified by 'lucifer';
  3. Query OK, 0 rows affected (0.01 sec)
  4.  
  5. mysql>
  6.  
  7. -- 在 mysql.user 表中添加用戶
  8. mysql> select MD5('lucifer');
  9. +----------------------------------+
  10. | MD5('lucifer') |
  11. +----------------------------------+
  12. | cae33a0264ead2ddfbc3ea113da66790 |
  13. +----------------------------------+
  14. 1 row in set (0.00 sec)
  15.  
  16. mysql>
  17. mysql> INSERT INTO mysql.user(Host, User, authentication_string, ssl_cipher, ssuex509_i09_sr, x5ubject) VALUES ('lohoscalt',uci 'lfer MD5('1',lucifer'), '', '',; '')
  18. Query OK, 1 row affected (0.01 sec)
  19.  
  20. mysql>
  21.  
  22. -- 使用 GRANT 語句創(chuàng)建用戶
  23. mysql> GRANT SELECT ON*.* TO 'lucifer2'@localhost IDENTIFIED BY 'lucifer';
  24. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY 'lucifer'' at line 1
  25. mysql>

注意: 由于測試使用的是 MySQL 8 版本,已經(jīng)不支持 GRANT 直接創(chuàng)建用戶,5.7 版本依然是支持的。

22、mysqldump 備份的文件只能在 MySQL 中使用嗎?

邏輯備份工具,適用于所有的存儲引擎,支持溫備、完全備份、部分備份、對于 InnoDB 存儲引擎支持熱備。

mysqldump 備份的文本文件實際是數(shù)據(jù)庫的一個副本,使用該文件不僅可以在 MySQL 中恢復(fù)數(shù)據(jù)庫,而且通過對該文件的簡單修改,可以使用該文件在 SQL Server 或者 Sybase 等其他數(shù)據(jù)庫中恢復(fù)數(shù)據(jù)庫。

  1. root@modb:~# mysqldump -uroot -p hr > /root/hr.db
  2. Enter password:
  3. root@modb:~#
  4. root@modb:~# ll hr.db
  5. -rw-r--r-- 1 root root 25327 Nov 26 08:52 hr.db

這在某種程度上實現(xiàn)了數(shù)據(jù)庫之間的遷移。

23、如何選擇備份工具?

根據(jù)備份的方法(是否需要數(shù)據(jù)庫離線)可以將備份分為:

  • 熱備(Hot Backup)
  • 冷備(Cold Backup)
  • 溫備(Warm Backup)

MySQL 中進行不同方式的備份還要考慮存儲引擎是否支持,如 MyISAM 不支持熱備,支持溫備和冷備。而 InnoDB 支持熱備、溫備和冷備。

一般情況下,我們需要備份的數(shù)據(jù)分為以下幾種:

  • 表數(shù)據(jù)
  • 二進制日志、InnoDB 事務(wù)日志
  • 代碼(存儲過程、存儲函數(shù)、觸發(fā)器、事件調(diào)度器)
  • 服務(wù)器配置文件

下面是幾種常用的備份工具:

  • mysqldump:邏輯備份工具,適用于所有的存儲引擎,支持溫備、完全備份、部分備份、對于 InnoDB 存儲引擎支持熱備。
  • cp、tar 等歸檔復(fù)制工具:物理備份工具,適用于所有的存儲引擎、冷備、完全備份、部分備份。
  • lvm2 snapshot:借助文件系統(tǒng)管理工具進行備份。
  • mysqlhotcopy:名不副實的一個工具,僅支持 MyISAM 存儲引擎。
  • xtrabackup:一款由 percona 提供的非常強大的 InnoDB/XtraDB 熱備工具,支持完全備份、增量備份。

直接復(fù)制數(shù)據(jù)文件是最為直接、快速的備份方法,但缺點是基本上不能實現(xiàn)增量備份。備份時必須確保沒有使用這些表。如果在復(fù)制一個表的同時服務(wù)器正在修改它,則復(fù)制無效。備份 文件時,最好關(guān)閉服務(wù)器,然后重新啟動服務(wù)器。

24、平時應(yīng)該打開哪些日志?

日志既會影響 MySQL 的性能,又會占用大量磁盤空間。因此,如果不必要,應(yīng)盡可能少地 開啟日志。

根據(jù)不同的使用環(huán)境,可以考慮開啟不同的日志。

例如,在開發(fā)環(huán)境中優(yōu)化查詢效率低的語句,可以開啟慢查詢?nèi)罩?

開啟慢查詢?nèi)罩荆?可以讓MySQL記錄下查詢超過指定時間的語句,通過定位分析性能的瓶頸,才能更好的優(yōu)化數(shù)據(jù)庫系統(tǒng)的性能。

  1. -- 檢查是否開啟慢查詢
  2. mysql> show variables like 'slow_query%';
  3. +---------------------+------------------------------+
  4. | Variable_name | Value |
  5. +---------------------+------------------------------+
  6. | slow_query_log | OFF |
  7. | slow_query_log_file | /var/lib/mysql/modb-slow.log |
  8. +---------------------+------------------------------+
  9. 2 rows in set (0.00 sec)
  10.  
  11. mysql> show variables like 'long_query_time';
  12. +-----------------+-----------+
  13. | Variable_name | Value |
  14. +-----------------+-----------+
  15. | long_query_time | 10.000000 |
  16. +-----------------+-----------+
  17. 1 row in set (0.01 sec)
  18.  
  19. -- 開啟慢查詢?nèi)罩?/span>
  20. mysql> set global slow_query_log='ON';
  21. Query OK, 0 rows affected (0.00 sec)
  22.  
  23. -- 設(shè)置查詢超過10秒就記錄
  24. mysql> set global long_query_time=10;
  25. Query OK, 0 rows affected (0.00 sec)
  26.  
  27. -- 再次檢查是否開啟
  28. mysql> show variables like 'slow_query%';
  29. mysql> +---------------------+------------------------------+
  30. | Variable_name | Value |
  31. +---------------------+------------------------------+
  32. | slow_query_log | ON |
  33. | slow_query_log_file | /var/lib/mysql/modb-slow.log |
  34. +---------------------+------------------------------+
  35. 2 rows in set (0.00 sec)

如果需要記錄用戶的所有查詢操作,可以開啟通用查詢?nèi)罩?

  1. mysql> show variables like 'general_log%';
  2. +------------------+-------------------------+
  3. | Variable_name | Value |
  4. +------------------+-------------------------+
  5. | general_log | OFF |
  6. | general_log_file | /var/lib/mysql/modb.log |
  7. +------------------+-------------------------+
  8. 2 rows in set (0.00 sec)
  9.  
  10. -- 開啟通用查詢?nèi)罩?/span>
  11. mysql> SET GLOBAL general_log=1;
  12. Query OK, 0 rows affected (0.00 sec)
  13.  
  14. mysql> show variables like 'general_log%';
  15. +------------------+-------------------------+
  16. | Variable_name | Value |
  17. +------------------+-------------------------+
  18. | general_log | ON |
  19. | general_log_file | /var/lib/mysql/modb.log |
  20. +------------------+-------------------------+
  21. 2 rows in set (0.00 sec)

如果需要記錄數(shù)據(jù)的變更,可以開啟二進制日志;錯誤日志是默認開啟的。

  1. mysql> show variables like 'log_bin%';
  2. +---------------------------------+-----------------------------+
  3. | Variable_name | Value |
  4. +---------------------------------+-----------------------------+
  5. | log_bin | ON |
  6. | log_bin_basename | /var/lib/mysql/binlog |
  7. | log_bin_index | /var/lib/mysql/binlog.index |
  8. | log_bin_trust_function_creators | OFF |
  9. | log_bin_use_v1_row_events | OFF |
  10. +---------------------------------+-----------------------------+
  11. 5 rows in set (0.00 sec)
  12.  
  13. mysql>

25、如何使用二進制日志?

二進制日志主要用來記錄數(shù)據(jù)變更。

如果需要記錄數(shù)據(jù)庫的變化,可以開啟二進制日志。基于二進制日志的特性,不僅可以用來進行數(shù)據(jù)恢復(fù),還可用于數(shù)據(jù)復(fù)制。

  1. root@modb:/var/lib/mysql# ls binlog*
  2. binlog.000001 binlog.000002 binlog.index
  3. root@modb:/var/lib/mysql# mysqlbinlog binlog.000001 | mysql -u root -p
  4. Enter password:
  5. root@modb:/var/lib/mysql#

在數(shù)據(jù)庫定期備份的 情況下,如果出現(xiàn)數(shù)據(jù)丟失,可以先用備份恢復(fù)大部分數(shù)據(jù),然后使用二進制日志恢復(fù)最近備份后變更的數(shù)據(jù)。在雙機熱備情況下,可以使用 MySQL 的二進制日志記錄數(shù)據(jù)的變更,然后將變更部分復(fù)制到備份服務(wù)器上。

26、如何使用慢查詢?nèi)罩?

慢查詢?nèi)罩局饕脕碛涗洸樵儠r間較長的日志。

在開發(fā)環(huán)境下,可以開啟慢查詢?nèi)罩緛碛涗洸樵儠r間較長的查詢語句,然后對這些語句進行優(yōu)化。

  1. root@modb:/var/lib/mysql# cat /var/lib/mysql/modb-slow.log
  2. /usr/sbin/mysqld, Version: 8.0.26-0ubuntu0.21.04.3 ((Ubuntu)). started with:
  3. Tcp port: 3306 Unix socket: /var/run/mysqld/mysqld.sock
  4. Time Id Command Argument
  5. root@modb:/var/lib/mysql#

通過配 long_query_time 的值,可以靈活地掌握不同程度的慢查詢語句。

27、是不是索引建立得越多越好?

合理的索引可以提高查詢的速度,但不是索引越多越好。

在執(zhí)行插入語句的時候,MySQL 要為新插入的記錄建立索引。所以過多的索引會導(dǎo)致插入操作變慢。原則上是只有查詢用的字段才建立索引。

使用索引時,需要綜合考慮索引的優(yōu)點和缺點。

28、如何使用查詢緩沖區(qū)?

查詢緩沖區(qū)可以提高查詢的速度,但是這種方式只適合查詢語句比較多、更新語句比較少 的情況。

默認情況下查詢緩沖區(qū)的大小為 0,也就是不可用。可以修改 queiy_cache_size 以調(diào)整查詢緩沖區(qū)大小;修改 query_cache_type 以調(diào)整查詢緩沖區(qū)的類型。

在 my.cnf 中修改 query_cache_size 和 query_cache_type 的值如下所示:

  1. [mysqld]
  2. query_cache_size= 512M
  3. query_cache_type= 1
  4. query_cache_type=1

表示開啟查詢緩沖區(qū)。

只有在查詢語句中包含 SQL_NO_CACHE 關(guān)鍵字時,才不會使用查詢緩沖區(qū)。可以使用 FLUSH QUERY CACHE 語句來刷新緩沖區(qū),清理查詢緩沖區(qū)中的碎片。

原文鏈接:https://mp.weixin.qq.com/s/3Dz_g40C6D87avlUpiBwDA

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产美女屁股直流白浆视频无遮挡 | 秋霞理论一级在线观看手机版 | 欧美ay| 驯服有夫之妇HD中字日本 | 夫妻性生活一级黄色片 | 啪啪大幂幂被c | 久久精品一区二区免费看 | 惩罚美女妲己的尤老师 | 天天综合天天色 | 万域之王动漫在线观看全集免费播放 | 性生大片免费看 | 国产51社区精品视频资源 | 午夜一级毛片看看 | 国产人成精品午夜在线观看 | 十大免费批日的软件 | 免费在线视频一区 | 第一次破学生处破 | 乌克兰黄色录像 | 桃乃木香奈作品在线 | 久久棋牌评测 | 亚洲狠狠婷婷综合久久久久网站 | 9自拍视频在线观看 | 国产高清dvd | 桃乃木香奈ipx在线播放 | 国产果冻传媒 | 亚洲一区 在线播放 | 国产精品一区三区 | 免费黄色网站视频 | 97菊爱网 | www亚洲精品| 亚洲福利在线观看 | 亚洲成a人不卡在线观看 | 国产成人8x视频一区二区 | 无码AV毛片色欲欧洲美洲 | 国产成人无精品久久久 | 亚洲六月丁香六月婷婷蜜芽 | 99精品国产美女福到在线不卡 | 天天综合天天综合 | 亚洲视频在线观看不卡 | 精品国产美女AV久久久久 | 国产成年人网站 |