硬核學習 MySQL 之入門篇

這篇博客將結合MySQL命令和圖形界面工具SQLyog來介紹 MySQL 的基本語法,案例將以學生數據庫爲代表,逐一介紹和分析 MySQL 數據的增刪改查操作,如果仔細看完並認真理解,基本上已經可以進行數據庫開發和操作了。在學習之前,如果對 MySQL 的安裝、啓動和登錄不熟悉的話,可以先閱讀我的另一篇博客 手把手教你安裝和配置 MySQL 數據庫

數據庫相關術語:

學習數據庫之前,我們需要先介紹和梳理一下數據庫相關的一些專業術語,不然,有可能後面看着看着就不知道我在說什麼了😏

數據庫(database):真正存放數據的地方或者容器,裏面由一張張不同數據類型的數據表組成

DBMS(數據庫管理系統,Database Manage System):操作和管理數據庫的軟件,我們是不能夠直接操作數據庫的,所有的操作都是通過DBMS來操作。沒錯!MySQL就是其中一種DBMS,所以,千萬別說MySQL是數據庫了,它是管理和操作數據庫的軟件而已。

數據表(table):某種特定類型數據的結構化列表,比如包含學生各種信息的學生數據表,包含教師各種信息的教師數據表,這些表組合起來共同構成一個學校信息數據庫。所以,數據表示數據庫的子單元

注意:在同一個數據庫中,表的名字是唯一,不可相同重複,但不同數據庫之間可以有相同的表名字

模式(schema):關於數據庫和表的佈局及特性的信息

列(column):表中的一個字段(filed),數據表由列組成,所有表都是由一個或多個列組成的,而每一列存放着相同數據類型的數據

提示:列和字段是同一個概念,當別人說起字段的時候你要想到列是的意思,從專業的角度來說,我們在談及數據表的列時應該使用字段術語,因爲字段更符合標準,比如 anme字段、ID字段等,而不是 name列、ID列。所以後面的內容將統一爲使用字段來表達列的意思。

行(row):數據表中的一條記錄,表中的數據都是按行來存儲的,可以把表想象成一張網格,每一列代表一個字段,每一行代表一條數據

主鍵(primary key):能夠唯一區分表中每個行的字段,沒錯,主鍵就是一個字段,而且這個字段的值不能夠重複,必須唯一區分

重點:任意一個字段都可以作爲主鍵,只要它滿足任意兩行的值不同就可以了,當然,主鍵也可以有多個字段組成,使用多個字段作爲主鍵的標準是:多個字段組合的值必須是唯一的


數據庫操作命令

接下來,我將會從數據庫的增、刪、改、查這四個方面來介紹數據的操作命令

一、數據庫的<增>

☕️ 查看數據庫

增加數據庫之前,我們先查看一下我們的數據庫有哪些,查看數據的命令爲:

SHOW DATABASES;
提示:MySQL語句以分號( ; )分割,而以分號( ; )或者\g結束,只有使用分號或者\g後按下回車纔會執行命令。MySQL 不區分大小寫,一般的原則是所有 SQL 關鍵字使用大寫,而數據庫名、表和字段使用小寫,這樣有助於閱讀和調試;
由於我的MySQL是新安裝的(使用的是MySQL8.0),所以會默認包含下面幾個自帶的數據庫

在這裏插入圖片描述
這裏先簡單介紹一下這幾個數據庫的作用:

  • information_schema:是一個信息數據庫,它保存着關於MySQL服務器所維護的所有其他數據庫的信息(如:數據庫名、數據庫的表、表欄的數據類型與訪問權限等)
  • mysql:MySQL的核心數據庫,類似於sql server中的master表,主要負責存儲數據庫的用戶、權限設置、關鍵字等mysql自己需要使用的控制和管理信息。mysql下有一張user表,裏面包含了所有用戶的信息,包括用戶名和密碼,所以我們可以直接在user表中修改用戶的密碼
  • performance_schema:主要用於收集數據庫服務器性能參數
  • sys:sys庫所有的數據源來自 performance_schema。目標是把performance_schema的複雜度降低,讓DBA能更好的閱讀這個庫裏的內容。讓DBA更快的瞭解DB的運行情況

有興趣進一步瞭解這四個數據庫的話,可以去官網查看一下幫助文檔,這裏就不多介紹了。

☕️ 創建數據庫

創建數據庫的語句爲:

CREATE DATABASE school;

創建好後,我們需要選擇或者打開這個數據庫:

USE school;

這樣我們就進入到了 school 這個數據庫了,USE database 這個命令不僅是打開進入數據庫的命令,而且還是切換數據庫的命令,比如,在 school 數據庫中,直接使用 USE mysql;命令就會切換到 mysql 數據庫中。

☕️ 創建數據表

新創建的數據庫只是一個空的數據庫,裏面沒有任何一張數據表,接下來我們添加一張學生數據表:

在這裏插入圖片描述
下面我們仔細分析一下創建表的語法,表的創建使用的是關鍵字 CREATE TABLE,後面緊跟表的名稱,然後把表中所有字段寫在括號( )中,括號後面的 ENGINE=INNODB 表示指定表的存儲引擎類型,然後以分號表示 SQL 語句的結束。整條語句的重點應該就是括號中的字段寫法以及括號後面的存儲引擎,下面我們逐一分析這兩個重點:

❄️ 字段寫法

括號中的字段給出的方式爲:字段名 + 字段數據類型 + 字段的約束,多條字段使用逗號分隔,最後一個可以不用逗號

字段名:字段名不能是 MySQL 的內置關鍵字和預留單詞,如果想知道那些是關鍵字的話,可以參考官方文檔給出的關鍵字:Keywords and Reserved Words。最尷尬的是連 name 這樣的單詞也是預留關鍵字,但我的表就只想用 name 怎麼辦?當然可以,我們可以使用頓號 ` 來去關鍵字操作,比如: `name` 就表示 name 解析爲標識符而不是關鍵字了,或者像我的例子一樣,使用一個前綴來避免和關鍵字重複。

字段數據類型:表示該字段所能存放數據類型,填寫的類型必須是 MySQL 所支持的數據類型,MySQL 所支持的數據類型放在了文章的最後面,點擊這裏查看 MySQL數據類型,類型後面的括號數字表示類型的長度,比如 CHAR(10) 表示存儲的字符串長度爲10

數值長度:MySQL 支持數值型後面"指定長度",比如 INT(4) 表示檢索的結果中顯示該字段的數值時只顯示4個字符,也就是說這個長度僅僅指的是顯示的長度,並不會影響數值原來存儲範圍。而浮點型後面的括號 FLOAT(7,4) 則表示浮點型的顯示精度,第一個數7表示顯示的總長度爲7,第二個數4表示小數點後面顯示4個數字。如果沒有指定顯示長度,INT 默認爲 INT(10),FLOAT/DOUBLE 默認爲 (10, 0)

字段的約束:是對字段值的一種而外說明,比如 :

  • NULL:表明字段值可以爲 NULL(空)
  • NOT NULL:表示字段值不能爲空
  • AUTO_INCREMENT:表示每次執行 INSERT 數據插入時,自動對該字段增量
  • DEFAULT:給定一個默認值,如果插入數據時沒有給出該字段的值,則使用 DEFAULT 後面的值
  • ZEROFILL:必須緊跟在數值類型(INT、FLOAT)之後,表示該字段的實際數值顯示長度小於指定的數值長度時,使用0來填充

PRIMARY KEY (stu_id):表示指定作爲主鍵的字段,可以指定多個字段作爲主鍵

創建表成功後,我們使用表結構查看命令來看一下表的內部結構:

DESCRIBE students;
可以看到表內部所有字段及各屬性情況

在這裏插入圖片描述
❄️ 存儲引擎

創建表最後的 ENGINE=INNODB 表示指定表的數據操作引擎爲 INNODB,數據庫引擎是專門用來管理和處理數據操作的執行者,我們查詢和更改操作都是數據庫引擎實現的,而不同的數據庫引擎具有不同的功能和特點,所以創建表時需要指定引擎,如果沒有指定引擎,那麼 MySQL 就會使用默認引擎(可能是MyISAM),下面列舉了幾個常用的數據庫引擎:

  • InnoDB:可靠的事務處理引擎,但不支持全文本搜索
  • MyISAM:性能極高的引擎,但不支持事務處理,可支持全文本搜索
  • MEMORY:功能等同於 MyISAM,但由於數據存儲在內存中,速度更快(適合用於臨時表)
提示:MySQL語句中是忽略空格的,所以一條長SQL語句可以使用換行和每行使用 tab 縮進來使語句變得更容易閱讀和編輯。在創建表的時候,指定的表名必須不存在,否則會出錯,爲了避免這種情況發生,可以在創建表的語句中添加判斷條件關鍵字:IF NOT EXISTS,比如:CREATE TABLE IF NOT EXISTS students

❄️ SQL語句註釋

在創建表的語句中我們還看到每個字段行後面有一個使用 # 號開頭的說明,沒錯,那就是 MySQL 語句的註釋,單行註釋使用 # 號開頭直到行末尾,多行註釋使用 /* */,和 c/c++的註釋類似


數據庫的<刪>

☕️ 刪除數據庫

數據庫的刪除命令爲:

DROP DATABASE school;

如果刪除的數據庫不存在則會報錯,所以刪除之前應該判斷一下是否存在:

DROP DATABASE IF EXISTS school;

☕️ 刪除表

數據表的刪除命令爲:

DROP TABLE students;

同樣如果刪除的表不存在也會報錯,所以相應地在刪除之前應該判斷一下是否存在:

DROP TABLE IF EXISTS students;
警告:刪除數據庫和數據表時一定要謹慎!因爲刪除是沒有確認提示,也不能撤銷的,執行之後就是永久刪除了。所以千萬別眼紅或者手滑刪錯庫了,別到時真的就成了從入門到刪庫跑路了


數據庫的<改>

這裏我們着重講解和介紹數據表的更改操作,這裏改的概念是對錶的結構和數據進行更改,比如插入表數據、刪除表數據或着增加刪除字段。

📝 重命名數據表

重命名數據表的命令爲:

RENAME TABLE oldtable TO newtable;

📝 添加新字段

使用命令 ALTER TABLE ADD 給表添加一列或者一個字段,比如在學生表中添加 stu_math 數學成績字段:

ALTER TABLE students
ADD stu_math FLOAT NULL;

ADD 後面緊跟的內容和創建表時添加的字段形式一樣,都是:字段名 + 字段數據類型 + 字段的約束

📝 刪除字段

使用命令 ALTER TABLE DROP COLUMN 給表刪除一列或者一個字段,ALTER TABLE 指定要更改的表名,DROP COLUMN 指定要刪除的字段名(該字段必須存在,否則會報錯),比如在學生表中刪除剛纔添加的 stu_math 數學成績字段:

ALTER TABLE students
DROP COLUMN stu_math;

📝 插入行數據

使用命令 INSERT INTO VALUES 來 插入一條完整的行數據,INSERT INTO 後面緊跟要插入的表名,VALUES 提供插入的數據,比如:

INSERT INTO students
VALUES(1, "小明", "男", "3年級", "123456");

VALUES 後面的數據對應着每個字段的值,以這種方式插入的數據,必須對每個字段都提供一個值,並且根據字段在表中出現的順序依次填充,如果不想提供某個字段的值,應該使用 NULL 值(如果對應字段允許 NULL 的話)填充。

上面的方法插入數據時不安全的,因爲它要高度依賴表中字段定義的次序,如果表結構發生變動導致列的次序發生改變,那這種SQL語句就會出錯。所以我們要使用一種更安全的方式插入數據:

INSERT INTO students(stu_id, stu_name, stu_sex, stu_class, stu_phone)
VALUES(2, "小英", "女", "2年級", "456789");

這種插入方式和前面的方式,功能上完全相同,不同的是,表名後面明確給出了字段名,插入數據 VALUES 中的數據,第一個值對應第一個指定的字段名,依次類推,這樣就只需要指定字段和值對應匹配就可以了,不需要管表中字段的定義次序。(實際工作當中,我們應該使用這種安全的數據插入方式!

指定字段的插入方式還有另一種功能,回憶之前創建表時所說 字段約束,有些字段允許 NULL,有些字段雖然不允許空(NOT NULL)但提供了默認值,這些字段都可以在插入一行數據時不用提供該字段值,下面列出了可以省略字段值的條件:

  • 字段允許爲 NULL(空)
  • 字段不允許空(NOT NULL),但提供了默認值 DEFAULT
  • 字段指定了 AUTO_INCREMENT,不管允不允許 NULL

所以下面的插入語句也是完全可以的:

INSERT INTO students(stu_name, stu_class)
VALUES("小花", "2年級");
得到的數據表如下:

在這裏插入圖片描述

重點講解 AUTO_INCREMENT:以整形爲例,MySQL會記錄該字段的上一個值,如果上一個值沒有的話就默認爲1,後面如果不提供該字段的值時會根據前面的值加1。可以手動指定該字段的值,只要它是唯一的即可,並且該值將會替代自動生成的值,後續的增量會從該值開始。(我們可以使用 SELECT LAST_INSERT_ID(); 語句查看最後一個 AUTO_INCREMENT 值

插入多行數據:一次性插入多行數據時,只需要每組 VALUES 值使用括號括起來,並且使用逗號分隔開來:

INSERT INTO students(stu_name, stu_sex, stu_class)
VALUES("小張", "男", "2年級"),("小云", "女", "2年級");

📝 選擇插入數據

INSERT INTO 還有另一種形式,就是可以將 SELECT 檢索語句(後面會詳細介紹)得到的結果插入到另一個表中,也就是所謂的 INSERT SELECT 語句,比如:

INSERT INTO students2(stu_id, stu_name)
SELECT stu_id, stu_name FROM students;

這裏並不要求 students2 的列名要和 students 的列名一樣,MySQL 並不關心列的名字,因爲 SELECT 的第一列將會填充到插入表的第一列中,以此類推。這個操作實際上是把 students 的每一行數據插入到 students2 之中。

注意:INSERT INTO 後面表的字段名需要使用括號括起來,而 SELECT 後面的字段名是不用括號括起來的,唯一相同的是,每個字段都以逗號隔開。
提高插入性能:在有很多索引需要更新的時候,INSERT 操作可能會很耗時,並且會降低等待處理的 SELECT 語句的性能。如果檢索操作比較重要的時候,可以通過在 INSERT INTO 中間添加關鍵字 LOW_PRIORITY 來指示MySQL降低 INSERT 語句的優先級,比如:INSERT LOW_PRIORITY INTO

📝 刪除行數據

行的刪除使用 DELETE 命令,而刪除又分爲特定行的刪除,這些特定的行使用 WHERE 來指定刪除那些行(WHERE 語句後面將會詳細介紹),以及刪除全部行數據。比如我們刪除 stu_id 等於 1 的行:

DELETE FROM students
WHERE stu_id = 1;

刪除全部數據有兩種方法,第一種就是上面的刪除方法,但不指定特定行:

DELETE FROM students;

DELETE 只是刪除行數據,不會刪除表!下面我們介紹另一種更快刪除方法:

TRUNCATE TABLE students;

TRUNCATE TABLE 刪除快的原因是:TRUNCATE 命令並不是逐行刪除表中的數據,而是刪除原來的表然後重新創建一個表。

📝 複製表

表的複製分爲三種:

1、只複製表的結構

CREATE TABLE students2 LIKE students;

2、只複製表的數據

INSERT INTO students2 SELECT * FROM students

3、同時複製表和數據

CREATE TABLE students2 SELECT * FROM students;

📝 修改表數據

表數據的修改使用的是 UPDATE 關鍵字,更新有很多子操作,比如使用 SET 來設置字段的值:

UPDATE students SET stu_sex = ""
WHERE stu_id = 5;

UPDATE 選擇要修改的表名,SET 設置 stu_sex 字段的值,WHERE 指定修改的字段位於那一行,如果沒有 WHERE 來限定修改的行,則會修改該所有行的該字段值,相當於修改整列值,如果加上修改的值爲 NULL 就相當於刪除整列值了:

UPDATE students SET stu_sex = NULL;

所以修改值時要小心,儘量使用限定行的 UPDATE 語句。如果要修改多個字段的值,只需加在 SET 後面即可,使用分號隔開,最後一列不用逗號:

UPDATE students
SET stu_sex = "", stu_phone = "123456"
WHERE stu_id = 5;
IGNORE 關鍵字:使用 UPDTAE 更新多行的時候,如果其中的一行或者多行出錯時,整個 UPDATE 都會被取消(發生錯誤之前更新的所有行都會恢復到原來的值),如果想要即使發生錯誤也繼續進行更新可以使用 IGNORE 關鍵字,比如:UPDATE IGNORE students

數據庫的<查>

終於進入數據庫最重要同時也是最複雜的環節了,因爲數據庫最核心的技術就是查詢技術,只有在茫茫數據庫中找出正確的數據,才能進行其他關鍵操作,比如:修改和刪除數據。如果數據查找出錯,那將是最糟糕的事情,試想一下,本來想修改A用戶的數據卻錯改了B用戶的數據以及本想刪除一個用戶的數據卻把全部用戶的數據都刪除了,內心基本上就是有種刪庫跑路的節奏呀!😂,好了,不扯了,下面開始進入查詢命令吧。

☁️ SELECT 語句

SELECT 和 FROM 關鍵字組成語句,是專門用來檢索列的語句,所以接在 SELECT 後面的就是需要檢索的字段名,而 FROM 後面的就是需要檢索的表,比如從學生表中檢索學生姓名這一列的值:

SELECT stu_name FROM students;

結果如下:
在這裏插入圖片描述
爲什麼名字變成了英文了?不要在意細節,只是後面的講解會越來越複雜,所以爲了簡潔起見,特地把表的結構改了一下!好了,廢話不多說了,介紹了單列檢索下面介紹多列檢索:只需要把所要檢索的字段名添加在 SELECT 後面並使用逗號隔開即可:

SELECT stu_id, stu_name, stu_math FROM students;

結果如下:
在這裏插入圖片描述
如果想要檢索所有列,直接使用通配符( * )來代替字段名就可以了:

SELECT * FROM students;

從上面的檢索結果可以發現,stu_math 字段的結果有重複數字的,如果想要檢索的結果中不重複(即值唯一)的話,可以在 SELECT 後面添加關鍵字 DISTINCT 來指示MySQL返回的結果唯一:

SELECT DISTINCT stu_math FROM students;

檢索得到的結果將不會重複:
在這裏插入圖片描述

注意:關鍵字 DISTINCT 作用於它前面的所有字段,比如: SELECT DISTINCT stu_math, stu_art FROM students; 關鍵字 DISTINCT 會作用於 stu_math 和 stu_art 兩個字段,即:DISTINCT 會比較這兩個字段的值,這兩個字段的值都一樣纔會被過濾,只要有一個值不相同都會被檢索出來,這是需要牢記的。

☁️ 限制檢索結果

如果沒有設置限制的話,SELECT 會返回檢索的所有結果,如果想限制返回的個數,需要使用關鍵字 LIMIT,比如:限制只返回檢索結果中的前3條:

SELECT stu_id, stu_name FROM students LIMIT 3;

輸出結果爲:
在這裏插入圖片描述
當然,我們還可以指定開始檢索的行數:

SELECT stu_name FROM students LIMIT 2,3;

這樣我們得到的結果就是從第2行開始的3條記錄,注意:檢索的結果行數是從0開始數起的,所以2表示第3表結果
在這裏插入圖片描述
爲了區分這兩個數字的含義,MySQL 還支持另一種更加清晰的寫法:

SELECT stu_name FROM students LIMIT 3 OFFSET 2;

LIMIT 3 表示只檢索3行,OFFSET 表示從第2行開始檢索

重要提示:LIMIT 只帶一個數字時,返回的起始位置爲第一行開始;檢索的結果是從0開始算起的,所以 LIMIT 1,1 返回的是第二行結果;指定的結果數大於實際檢索的數量時,返回全部結果數;

☁️ 使用完全限定名

所謂完全限定名,就是限定檢索的字段屬於哪張表,和限定檢索的表屬於哪個數據庫,比如限定檢索字段:

SELECT students.stu_name FROM students;

同時限定字段和表:

SELECT students.stu_name FROM school.students;

☁️ 檢索排序

檢索出的數據一般是以它在底層表中出現的順序顯示的,可以是數據添加到表中時的順序,但如果數據後來被更新或者刪除就會受到MySQL重用回收存儲空間的影響。在介紹排序命令時,我們先了解一下一個概念:

子句(Clause):SQL 語句由子句構成,有些是必須的,有些是可選的。一個子句由關鍵字和提供的數據組成,比如我們的 SELECT 語句中的 FROM 語句就是一個子句。

數據的排序使用的是 ORDER BY 子句,比如下面的檢索結果按照姓名排序:

SELECT stu_name, stu_math FROM students
ORDER BY stu_name;

得到的結果按照姓名排序:
在這裏插入圖片描述
由於指定的排序字段 stu_name 是字符類型,所以 MySQL 會對結果按照字母順序來排序:先比較第一個字符,如果第一個字符相同則比較第二個字符,一次類推下去。如果指定的字段爲數字類型,則直接比較數值大小即可。當然,ORDER BY 子句還可以指定多個排序字段:

SELECT stu_id, stu_math, stu_name FROM students
ORDER BY stu_math, stu_name;

在這裏插入圖片描述
從結果可以看出,多個排序字段的情況下,首先按照第一個字段 stu_math 進行排序,如果該字段的值相同情況下,則按照第二個字段 stu_name 進行排序。相應的,如果第一個排序字段的值是唯一的,則不會對第二個排序字段進行排序。

☁️ 指定排序方向

默認的排序結果爲升序排序(從小到達)其對應的關鍵字爲 ASC(ascending),如果想要進行降序排序(從大到小),則必須使用 DESC(descending) 關鍵字,用法是 DESC 關鍵字緊跟需要降序排序的字段後面,比如按照數學成績降序排序:

SELECT stu_id, stu_math, stu_name FROM students
ORDER BY stu_math DESC;

在這裏插入圖片描述
可以看到整個排序結果是按照數學成績從大到小降序進行排序的。多個字段排序也是一樣,比如:按照數學成績進行降序排序,如果數學成績相同則按照學生姓名進行升序排序:

SELECT stu_id, stu_math, stu_name FROM students
ORDER BY stu_math DESC, stu_name ASC;

在這裏插入圖片描述

提示:由於默認排序是升序排序,所以使不使用關鍵字 ASC 效果都一樣;關鍵字 DESC 和 ASC 只作用於一個字段,即它所緊跟的前面的那個字段,如果想要多個排序字段都使用降序的話,每個字段都要指定 DESC 關鍵字。

ORDER BY 與 LIMIT 結合找出最值,比如使用降序找出最高的數學成績:

SELECT stu_math FROM students
ORDER BY stu_math DESC
LIMIT 1;
重點:子句的出現順序爲:如果有 ORDER BY 子句,則應該保證它位於 FROM 子句之後,如果使用了 LIMIT,則它必須位於 ORDER BY 之後。如果子句的次序不對將會產生錯誤信息。

☁️ WHERE 語句

檢索數據的時候,我們往往需要制定搜索條件(search criteria),搜索條件也稱爲過濾條件(filter condition)。在 SELECT 語句中,通過使用 WHERE 子句指定的搜索條件來過濾數據,比如檢索 stu_id 爲2的整條學生數據:

SELECT * FROM students WHERE stu_id = 2;

這樣就得到了一條學生ID爲2的數據:
在這裏插入圖片描述

提示:當同時使用 WHERE 和 ORDER BY 語句的時候,應該讓 ORDER BY 位於 WHERE 之後,否則將會出錯。

☁️ WHERE 語句操作符

WHERE 語句使用操作符來對數據進行過濾,比如前面看到的 WHERE stu_id = 2 使用的就是相等操作符(沒錯!MySQL使用的是 = 來表示相等,而不是編程語言所使用的 ==),下面列出了 WHERE 語句支持的條件操作符:

=等於
!=不等於
<>等價於 !=
<小於
<=小於等於
>大於
>=小於等於
BETWEEN AND在指定的兩個值之間
注意:由於MySQL在執行匹配的時候是不區分大小寫的,所以,如果使用 WHERE stu_name = 'Jack' 來進行檢索時,'Jack','JACK' 之類的都會匹配出來。

☁️ 範圍值檢索

如果想要對某個範圍區間進行檢索,可以使用 BETWEEN AND 操作符,即提供開始值和結束值,例如檢索 stu_id 在 2 和 4 之間的學生數據:

SELECT * FROM students
WHERE stu_id BETWEEN 2 AND 4;

這樣就檢索出學生ID爲2到4之間的數據:
在這裏插入圖片描述
☁️ 空值判斷

SELECT 語句有一個特殊的 WHERE 子句,可用來檢索值爲 NULL 的結果數據,這個子句就是 IS NULL 子句,比如檢索英語成績爲空的數據:

SELECT * FROM students
WHERE stu_eng IS NULL;

檢索得到所有 stu_eng 值爲空的數據:
在這裏插入圖片描述

注意:值爲空(NULL),表示意思是沒有值,和整數0、空字符串"",之間的含義是不同的,0和空字符串是有值的數據,而 NULL 指的是沒有值的意思。

☁️ 邏輯操作符

在 WHERE 語句中可以使用邏輯操作符(logical operator)來組合多條過濾條件,下面將逐一介紹這些組合邏輯操作符:

AND 操作符

AND 是用在WHERE子句中的關鍵字,用來指示檢索需要滿足所有給定的條件進行,可以組合使用多個 AND 來給定多個條件,並且每個條件都必須滿足。比如檢索數學成績大於80分並且英語成績大於85分的所有行數據:

SELECT * FROM students
WHERE stu_math >= 80 AND stu_eng >= 85;

OR 操作符

OR 操作符與 AND 操作符不同,它指示 MySQL 檢索匹配其中任意一個條件即可,比如檢索數學成績大於60或者英語成績大於70的所有行數據:

SELECT * FROM students
WHERE stu_math >= 60 OR stu_eng >= 70;
計算次序:在混合使用 AND 和 OR 操作符的時候,MySQL 會優先計算 AND 操作符然後再計算 OR 操作符,比如:WHERE stu_math > 60 OR stu_eng > 70 AND stu_art < 90,會被解釋爲 WHERE (stu_math > 60) OR (stu_eng > 70 AND stu_art < 90),所以這一點是需要注意。爲了避免出現這種不明確的含義,可以明確地給出括號來進行分組,這樣就可以消除歧義。

IN 操作符

IN 操作符用來指定條件範圍,範圍值使用逗號分隔並用圓括號括起來,表示括號中的每個值都可以匹配。比如檢索數學成績爲80或者90的所有行數據:

SELECT * FROM students
WHERE stu_math IN (80, 90);

IN 操作符的效果相當於 OR 操作符,上面的條件也可以寫成:WHERE stu_math = 80 OR stu_math = 90,那爲什麼要使用 IN 操作符呢?因爲使用 IN 操作符有以下幾個優點:

  • 在使用多個長選項組合時,IN 操作符的語句比較清晰直觀
  • 使用 IN 操作符可以更容易管理計算次序(因爲使用的操作符更少)
  • IN 操作符比OR操作符執行速度更快
  • IN 最大的優點是可以包含其他 SELECT 語句,使得能夠更動態建立 WHERE 語句

NOT 操作符

NOT 操作符的主要功能是否定跟在它後面的條件關鍵字,最常用的是 NOT 與 IN 組合使用來排除條件,比如排除數學成績爲80或90的數據:

SELECT * FROM students
WHERE stu_math NOT IN (80, 90);
MySQL 的 NOT 操作符支持對 IN、BETWEEN 和 EXISTS 字句取反

☁️ 通配符

我們先來了解一下兩個專業術語:

  • 通配符(wildcard):用來匹配值的一部分特殊字符
  • 搜索模式(search pattern):有字面值、通配符或者兩者組合構成的搜索條件

MySQL 中使用 LIKE 操作符來指示後面跟的搜索模式爲統配符匹配,MySQL 支持的統配符有:百分號(%)通配符和下劃線(_)通配符,統配符的搜索模式所作用的對象是值的類型爲字符型的字段

百分號通配符

百分號 % 表示匹配任何字符出現任意次數(匹配的字符數可以是0個、1個或多個),比如:檢索學生姓名中所有以 Jac 開頭的行數據:

SELECT * FROM students
WHERE stu_name LIKE "Jac%";

檢索模式爲:“Jac%”,Jac 表示詞的開頭爲 Jac,% 告訴 MySQL 接受 Jac 之後的任意字符,不管它出現有多少字符,所以這個模式可以檢索出姓名爲 Jack、Jacimy 等所有以 Jac 開頭的結果。

注意:MySQL 的統配符匹配模式默認是不區分大小寫的,但可以通過配置來支持區分大小寫,統配符可以放在任意位置,並且可以多個統配符同時使用,如果放在兩端:"%head%"表示任何任何位置包含文本 head 的值,如果放在中間:"h%d"表示匹配所有以 h 開頭 d 結尾的值。("%" 可以匹配任何東西但不匹配 NULL 值)

下劃線通配符

下劃線 (_) 通配符的用途和 % 的用途一樣,只是,下劃線要求匹配1個並且必須匹配1個字符,不能多也不能少。比如:

SELECT * FROM students
WHERE stu_name LIKE "_ack";

這個匹配模式匹配的結果爲 Jack、Lack 之類的,ack 之前的字符必須有一個且只能是一個。

統配符的使用技巧

  • 不要過度使用通配符,如果其他操作符可以達到相同目的的話,應該使用其他操作符
  • 儘量不要把通配符放在搜索模式的開頭,因爲這會讓搜索速度變慢
  • 想要搜索更加準確,應該仔細注意通配符的放置位置

☁️ 正則表達式

如果不瞭解正則表達式的話可以參考我的另一篇博客:一篇文章教你學會【正則表達式】,看懂我的這篇正則表達式之後,後面的 MySQL 正則表達式匹配就很簡單了,只需要使用關鍵字 REGEXP 後面跟正則表達式字符串即可,語法和 LIKE 操作符一樣。比如搜索名字中連續出現2個 a 或者連續出現3個 b 的值:

SELECT * FROM students
WHERE stu_name REGEXP "(a{2})|(b{3})";

有些搜索條件既可以使用 LIKE 操作符,也可以使用正則表達式,但相比於 LIKE 操作符,正則表示式搜索能力更強大更靈活1

注意:多數正則表達式使用的是單個反斜槓來轉義特殊字符,比如 \. 表示轉義元字符 ( . ), 但在 MySQL 中使用兩個反斜槓來轉義:\\. \\* \\n (MySQL 自己解釋一個,正則表達式庫解釋一個)


MySQL 所支持的數據類型


字符串數據類型
CHAR 1~255個字符的定長串,它的長度必須在創建時指定,否則MySQL假定爲CHAR(1)
ENUM 接受最多64K個串組成的一個預定義集合的某個串
TEXT 最大長度爲64K的變長文本
LONGTEXT 與TEXT相同,但最大長度爲4GB
MEDIUMTEXT 與TEXT相同,但最大長度爲16K
TINYTEXT 與TEXT相同,但最大長度爲255字節
SET 接受最多64個串組成的一個預定義集合的零個火多個串
VARCHAR 長度可變,最多不超過255字節,如果創建時指定爲VARCHAR(n),則可存儲0到n個字符的變長串(n<=255)

數值數據類型
BIT 位字段,1~64位
INT(或INTEGER) 整數型,4字節共32位,有符號範圍爲-2147483648~2147483648,無符號範圍爲0~4294967295
TYNYINT 整數型,1字節8位,有符號範圍爲-127~128,無符號範圍爲0~255
SMALLINT 整數型,2字節16位, 有符號復位爲-32768~32768,無符號範圍爲0~65536
MEDIUMINT 整數型,3字節24位,有符號範圍爲-8388608~8388608, 無符號範圍爲0~16777216
BIGINT 整數型,8字節64位,有符號範圍爲-9223372036854775808~9223372036854775808,無符號範圍爲0~18446744073709551615
BOOLEAN(或BOOL) 布爾型,值爲0或1,用於開/關(on/off)標誌
FLOAT 單精度浮點值
DOUBLE 雙精度浮點值
DECIMAL 精度可變的浮點值
REAL 4字節的浮點值
除了 BIT 和 BOOLEAN 之外,都可以有符號或者無符號,指定爲無符號類型時可以使用 UNSIGNED關鍵字

日期和時間數據類型
DATE 表示1000-10-01~9999-12-31的日期,格式爲 YYYY-MM-DD
TIME 格式爲 HH:MM:SS
YEAR 用2爲數字表示時,範圍爲70(1970年)~69(2069年);用4位數字表示時,範圍是 1901年~1255年
DATETIME DATE 和 TIME 的結合
TIMESTAMP 功能和 DATETIME 相同,但範圍較小

二進制數據類型
BLOB Blob最長長度爲64KB
TINYBLOB Blob最長長度爲255字節
MEDIUMBLOB Blob最長長度爲16MB
LONGBLOB Blob最長長度爲4GB
二進制數據類型可以存儲任何數據,包括圖像、多媒體、字符文檔等
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章