初級程式設計師的SQL拾遺(增刪改查)

LYX6666發表於2022-04-26

前言

雖然平時開發中經常接觸MySQL,但大多數的資料庫操作都是通過ORM實現的(SpringDataJPA),自己並沒有從底層接觸SQL。
再加上筆者非專業的身份,對於原生的SQL語句幾乎完全不瞭解。
本文是寫給自己的,關於原生SQL的一篇筆記。
學習應該掌握邊界,由於這部分不是程式設計核心,所以不需要背程式碼,只需要能理解會貼上修改即可。

小Tip:

初學者如何除錯SQL程式碼呢?可以用Navicat或PHPMyAdmin視覺化練習。
先用圖形介面建幾張表,再練習用SQL語句運算元據表即可。
這樣就避免了前期就用純命令列難度過高。

一、增刪改查(CRUD)

在REST規範中寫到:查詢使用GET、增加使用POST、修改使用UPDATE、刪除使用DELETE。增刪改查是最常見的搬磚了,那麼它們的SQL程式碼是什麼呢?

我們先以單表為例(也就是無外來鍵情況)。

單表操作的命令具有很強的規律。包括以下要素:

  • 指令
  • 欄位
  • 目標表
  • 引數
  • 分號

指令告訴SQL要執行什麼操作,是增加?還是修改?還是刪除?
欄位告訴SQL要操作哪幾個列,比如查出所有學生的姓名和年齡。
目標表告訴SQL要操作哪張表,比如刪除班級表某個班級?

查——SELECT

寫法是:

SELECT 欄位1,欄位2,... FORM 表名 WHERE 條件;

示例:

// 從學生表查詢ID為1的姓名和年齡
SELECT name, age FORM student where id=1;

(輔助記憶:)
此時的指令為SELECT
目標表使用FORM 表名來確定
引數主要是增加篩選的條件,準確查到想要的資料

分頁查——LIMIT引數(對於MySQL)

寫法是:

SELECT 欄位1,欄位2,... FORM 表名 WHERE 條件 LIMIT 條數;

示例:

// 從學生表查詢10條性別是女的學生的所有欄位
SELECT * FORM student where sex=1 LIMIT 10;

(輔助記憶:)
LIMIT不屬於原生SQL的語法,對於不同的發行版有著不同的實現。
其中MySQL使用的是LIMIT語句,作用是隻取出十條。
這種查詢方法常用於Web的分頁查詢。

增加——INSERT

寫法:

INSERT INTO 表名 (欄位1,欄位2,...) VALUES (值1,值2,...);

示例:

// 向學生表插入姓名為張三、性別為女、年齡20歲的學生
INSERT INTO student (name, sex, age) VALUES (zhangsan, 1, 20);

(輔助記憶:)
對於增加操作,指令就變成了INSERT。
增加操作不僅要給出欄位還要給出值,所以需要VALUES。
此時作用表的字首有一些變化,想象一下:
執行查詢時,資料從資料庫到使用者,所以用FORM;
但插入時,資料從使用者到資料庫,所以是INTO。
而由於插入會直接插到最後一條資料,所以沒有WHERE引數。

修改——UPDATE

寫法:

UPDATE 表名 SET 欄位1=值1,欄位2=值2,欄位3=值3,... WHERE 條件;

示例:

// 在學生表中找到id為1的學生,然後更新姓名=張三、年齡=20、性別=男
UPDATE student SET name=zhangsan,age=20,sex=0,... WHERE id=1;

(輔助記憶:)
此時的指令為UPDATE。
由於需要修改欄位,需要使用SET
修改只針對一條或幾條資料,必須使用WHERE條件進行限制,否則會修改整張表的資料!

刪除——DELETE

DETELE FORM 表名 WHERE 條件;

(輔助記憶:)
刪除的指令為DELETE
由於資料從表中被拿出來,所以是FROM
刪除只針對一條或幾條資料,必須使用WHERE條件進行限制,否則會刪除整張表的資料!

二、WHERE引數

WHERE在SQL定義了查詢條件,但有以下幾個注意的地方:

WHERE搭配的操作符

常規操作符

  • = 欄位等於值
  • > 欄位大於值
  • < 欄位小於值
  • >= 欄位大於等於值
  • <= 欄位小於等於值

特殊操作符

  • LIKE 模糊查詢(欄位包含值)
  • IN 屬於(欄位的值屬於給定的集合)
  • BETWEEN 區間(欄位的值屬於給定的區間)

模糊查詢指的是,被查詢的欄位不需要嚴格等於某字串,只需要包含字串即可。
例如,使用LIKE '%zhang%'作為條件,'zhangsan'包括了'zhang',就會被查出來。
模糊查詢又分為三種:

  • 字首匹配 開頭必須相同:zhangsan%
  • 中綴匹配 中間相同即可:%zhangsan%
  • 字尾匹配 結尾必須相同:%zhangsan

WHERE的邏輯運算

在程式語言中一定會用到邏輯用語(與、或、非),而SQL中也有與、或。

邏輯運算子連線兩個條件。
與運算使用AND,表示兩個條件都滿足才有效。
或運算使用OR,表示任一個條件滿足則有效。
實際使用場景可以多個邏輯符連續使用,並用括號定義優先順序。

寫法:

SELECT 欄位 FROM 表名 WHERE 條件1 AND/OR 條件2;

舉例:

// 在學生表取出年齡大於18歲的女生的所有欄位
SELECT * FROM student WHERE sex=1 AND age > 18;

三、多表查詢(連線/JOIN)

軟體開發中常見的實體關係包括:

  • 一對一(0…1 : 0…1)
  • 一對多/多對一(0…1 : 0…n)
  • 多對多(0…n : 0…n)

其中,一對一、一對多、多對一使用外來鍵關聯,而多對多使用中間表關聯。

對於外來鍵關聯的三種情況,在查詢時,往往需要通過table1把與之關聯的table2一併查出來。

這時候可以使用JOIN,把兩張表拼成一張表。

關聯表就像兩個集合,分別是表一和表二,
他們的交集就是兩張表中有外來鍵關聯的那部分記錄。

Pasted image 20220424213339.png

班級有多個學生,每個學生屬於一個班級。所以學生和班級是多對一。
如果想在查詢學生的時候,一併顯示他們所在班級的資訊:

SELECT student.id, student.name, klass.name, klass.count  
FROM Students  
INNER JOIN Klass  
ON Klass.id=Student.klass_id;

儘管菜鳥教程已經講的很清楚了,我們這裡可以再精簡一些:

  • 我們把使用FORM欄位的表定義為左表
  • 把使用JOIN欄位的表定義為右表

同樣對於四種連線也可以概況:

  • INNER JOIN 一般連線:只查外來鍵關聯的資料,也就是取交集
  • LEFT JOIN 左連線:左表全查,右表隨緣,空資料置NULL,也就是取集合A
  • RIGHT JOIN 右連線:右表全查,左表隨緣,空資料置NULL,也就是取集合B
  • FULL JOIN 全連線:左右表都全查,兩側空資料都置NULL,也就是取並集。

四、總結

藉助程式語言強大的ORM(實體關係對映),增刪改查的操作幾乎不再需要手寫SQL來完成,但我們不能對ORM形成依賴而忘記了原生SQL怎麼寫。

這也是一門必修課,至少能看懂增刪改查的基本寫法,才能在一些特殊需求中知道如何變通,也能在JPA出問題時通過檢視生成的SQL語句來順利的Debug。

文章中提到的內容基本覆蓋日常增刪改查的需要,而對於如何定義主鍵、外來鍵,如何建表、刪表,如何新增、編輯欄位,這些非高頻操作,以後再說。

參考資料:

菜鳥教程: https://www.runoob.com/sql/sq...

相關文章