最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

快速學習MySQL基礎知識

 更新時間:2020年07月15日 15:52:43   作者:以終為始  
這篇文章主要介紹了MySQL基礎知識的相關資料,文中講解非常細致,幫助大家更好的理解和學習,感興趣的朋友可以了解下

這篇文章主要梳理了 SQL 的基礎用法,會涉及到以下方面內容:

  • SQL大小寫的規(guī)范
  • 數(shù)據庫的類型以及適用場景
  • SELECT 的執(zhí)行過程
  • WHERE 使用規(guī)范
  • MySQL 中常見函數(shù)
  • 子查詢分類
  • 如何選擇合適的 EXISTS 和 IN 子查詢

了解 SQL

SQL 是我們用來最長和數(shù)據打交道的方式之一,如果按照功能劃分可分為如下 4 個部分:

  • DDL,數(shù)據定義語言。定義數(shù)據庫對象,數(shù)據表,數(shù)據列。也就是,對數(shù)據庫和表結構進行增刪改操作。
  • DML,數(shù)據操作語言。對數(shù)據表的增刪改。
  • DCL,數(shù)據控制語言。定義訪問權限和安全級別。
  • DQL,數(shù)據查詢語言。用來查詢數(shù)據。

平時在編寫 SQL 時,可能發(fā)現(xiàn)許多 SQL 大小寫不統(tǒng)一,雖然不會影響 SQL 的執(zhí)行結果,但保持統(tǒng)一的書寫規(guī)范,是提高效率的關鍵,通常遵循如下的原則:

  • 表名,表別名,字段名,字段別名等用小寫。
  • SQL 保留字,函數(shù)名,綁定變量等用大寫。
  • 數(shù)據表,字段名采用下劃線命名。

目前排名較前的 DBMS:

  • 關系型數(shù)據庫:建立在關系模型上的數(shù)據庫,在建表時,通常先設計 ER 圖表示之間的關系。
  • 鍵值型數(shù)據庫:以 key-value 的形式存儲數(shù)據,優(yōu)點是查找速度快,缺點是無法向關系型數(shù)據庫一樣使用如 WHERE 等的過濾條件。常見場景是作為內容緩存。
  • 文檔型數(shù)據庫,在保存時以文檔作為處理信息的基本單位。
  • 搜索引擎:針對全文檢索而設計。核心原理是 “倒排索引”。
  • 列式數(shù)據庫:相對于如 MySQL 等行式存儲的數(shù)據庫,是以列將數(shù)據存在數(shù)據庫中,由于列具有相同的數(shù)據類型,所以可以更好的壓縮,從而減低系統(tǒng)的 I/O,適用于分布式文件系統(tǒng),但功能相對有限。
  • 圖形數(shù)據庫,利用圖的數(shù)據結構存儲實體之間的關系。比如社交網絡中人與人的關系,數(shù)據模型為節(jié)點和邊來實現(xiàn)。

認識 SELECT

SELECT 一般是在學習 SQL 接觸的第一個關鍵字,基礎的內容就是不提了,這里整理常用的規(guī)范:

起別名

SELECT name AS n FROM student

查詢常數(shù), 增加一列固定的常數(shù)列:

SELECT '學生信息' as student_info, name FROM student

去重重復行

SELECT DISTINCT age FROM student

需要注意的是 DISTINCT 是對后面的所有列進行去重, 下面這種情況就會對 age 和 name 的組合進行去重。

SELECT DISTINCT age,name FROM student

排序數(shù)據,ASC 代表升序,DESC 代表降序

如先按照 name 排序,name 相等的情況下按照 age 排序。

SELECT DISTINCT age FROM student ORDERY BY name,age DESC

限制返回的數(shù)量

SELECT DISTINCT age FROM student ORDERY BY name DESC LIMIT 5

SELECT 的執(zhí)行順序

了解了 SELECT 的執(zhí)行順序,才能更好地寫出更有效率的 SQL。

對于 SELECT 順序有兩個原則:

  • 關鍵字的順序不能顛倒:
    SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...
  • SELECT 會按照如下順序執(zhí)行:
    FROM > WHERE > GROUP BY > HAVING > SELECT的字段 > DISTINCT > ORDER BY > LIMIT
SELECT DISTINCT student_id, name, count(*) as num #順序5
FROM student JOIN class ON student.class_id = class.class_id #順序1
WHERE age > 18 #順序2
GROUP BY student.class_id #順序3
HAVING num > 2 #順序4
ORDER BY num DESC #順序6
LIMIT 2 #順序7

在逐一分析下這個過程前,我們需要知道在上面的每一個步驟中都會產生一個虛擬表,然后將這個虛擬表作為下一個步驟中作為輸入,但這一過程對我們來說是不可見的:

  1. 從 FROM 語句開始,對 student 和 class 表進行 CROSS JOIN 笛卡爾積運算,得到虛擬表 vt 1-1;
  2. 通過 ON 篩選,在 vt1-1 的基礎上進行過濾然后得到表 vt 1-2;
  3. 添加外部行。如使用左連接,右連接和全連接時,就會涉及到外部行,會在 vt1-2 的基礎上增加外部行,得到 vt1-3。
  4. 如果超過兩張表,就會重復上面的步驟。
  5. 在拿到最終的 vt1 的表數(shù)據后,會執(zhí)行 WHERE 后面的過濾階段,得到表 vt2.
  6. 接著到 GROUP 階段,進行分組得到 vt3.
  7. 接著到 HAVING 階段,對分組的數(shù)據進行過濾,得到 vt4.
  8. 后面進入 SELECT 階段,提取需要的字段,得到 vt5-1,接著通過 DISTINCT 階段,過濾到重復的行,得到 vt5-2.
  9. 然后對指定的字段進行排序,進入 ORDER BY 階段,得到 vt6.
  10. 最后在 LIMIT 階段,取出指定的行,對應 vt7,也就是最后的結果。

如果涉及到函數(shù)的計算比如 sum() 等,會在 GROUP BY分組后,HAVING 分組前,進行聚集函數(shù)的計算。

涉及到表達式計算,如 age * 10 等,會在 HAVING 階段后,SELECT 階段前進行計算。

  • 通過這里,就可以總結出提高 SQL 效率的第一個方法:

使用 SELECT 時指定明確的列來代替 SELECT * . 從而減少網絡的傳輸量。

使用 WHERE 進行過濾

使用 WHERE 篩選時,常有通過比較運算符,邏輯運算符,通配符三種方式。

對于比較運算符,常用的運算符如下表。

對于邏輯運算符來說,可以將多個比較運行符連接起來,進行多條件的篩選,常用的運算符如下:

需要注意的是,當 AND 和 OR 同時出現(xiàn)時,AND 的優(yōu)先級更高會先被執(zhí)行。當如果存在 () 的話,則括號的優(yōu)先級最高。

使用通配符過濾:

like:(%)代表零個或多個字符,(_)只代表一個字符

函數(shù)

和編程語言中的定義的函數(shù)一樣,SQL 同樣定義了一些函數(shù)方便使用,比如求和,平均值,長度等。

常見的函數(shù)主要分為如下四類,分類的原則是根據定義列時的數(shù)據類型:

  • 算術函數(shù):

  • 字符串函數(shù)

需要注意的是,在使用字符串比較日期時,要使用 DATE 函數(shù)比較。

  • 日期函數(shù)

  • 轉換函數(shù):

CAST 函數(shù)在轉換數(shù)據類型時,不會四舍五入,如果原數(shù)值是小數(shù),在轉換到整數(shù)時會報錯。

在轉換時可以使用 DECIMAL(a,b) 函數(shù)來規(guī)定小數(shù)的精度,比如 DECIMAL(8,2) 表示精度為 8 位 - 小數(shù)加整數(shù)最多 8 位。小數(shù)后面最多為 2 位。

然后通過 SELECT CAST(123.123 AS DECIMAL(8,2)) 來轉換。

聚集函數(shù)

通常情況下,我們會使用聚集函數(shù)來匯總表的數(shù)據,輸入為一組數(shù)據,輸出為單個值。

常用的聚集函數(shù)有 5 個:

其中 COUNT 函數(shù)需要額外注意,具體的內容可以參考這篇。

如何進行分組

在統(tǒng)計結果時,往往需要對數(shù)據按照一定條件進行分組,對應就是 GROUP BY 語句。

比如統(tǒng)計每個班級的學生人數(shù):

SELECT class_id, COUNT(*) as student_count FROM student \
GROUP BY class_id; 

GROUP BY 后也可接多個列名,進行分組,比如按照班級和性別分組:

SELECT class_id, sex, COUNT(*) as student_count FROM \
student GROUP BY class_id, sex; 

HAVING 過濾和 WHERE 的區(qū)別

和 WHERE 一樣,可以對分組后的數(shù)據進行篩選。區(qū)別在于 WHERE 適用于數(shù)據行,HAVING 用于分組。

而且 WHERE 支持的操作,HAVING 也同樣支持。

比如可以篩選大于2人的班級:

SELECT class_id, COUNT(*) as student_count FROM student \ 
GROUP BY class_id \ 
HAVING student_count > 20; 

子查詢

在一些更為復雜的情況中,往往會進行嵌套的查詢,比如在獲取結果后,該結果作為輸入,去獲取另外一組結果。

在 SQL 中,查詢可以分為關聯(lián)子查詢和非關聯(lián)子查詢。

假設有如下的表結構:

-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(20) NOT NULL DEFAULT '',
 `age` int(3) NOT NULL,
 `sex` varchar(10) NOT NULL DEFAULT '',
 `class_id` int(11) NOT NULL COMMENT '班級ID',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of Student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '胡一', 13, '男', '1');
INSERT INTO `student` VALUES ('3', '王阿', 11, '女', '1');
INSERT INTO `student` VALUES ('5', '王琦', 12, '男', '1');
INSERT INTO `student` VALUES ('7', '劉偉', 11, '女', '1');
INSERT INTO `student` VALUES ('7', '王意識', 11, '女', '2');

-- ----------------------------
DROP TABLE IF EXISTS `student_activities`;
CREATE TABLE `student_activities` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(20) NOT NULL DEFAULT '',
 `stu_id` int(11) NOT NULL COMMENT '班級ID',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
INSERT INTO `student_activities` VALUES ('1', '博物館', 1);
INSERT INTO `student_activities` VALUES ('3, '春游', 3);

非關聯(lián)子查詢

子查詢從數(shù)據表中查詢了數(shù)據結果,如果這個數(shù)據結果只執(zhí)行一次,然后這個數(shù)據結果作為主查詢的條件接著執(zhí)行。

這里想要查詢和胡一相同班級的同學名稱:

SELECT name FROM student WHERE class_id = \
(SELECT class_id FROM student WHERE name='胡一')

這里先查到胡一的班級,只有一次查詢,再根據該班級查找學生就是非關聯(lián)子查詢。

關聯(lián)子查詢

如果子查詢需要執(zhí)行多次,即采用循環(huán)的方式,先從外部查詢開始,每次都傳入子查詢進行查詢,然后再將結果反饋給外部

再舉個例子, 比如查詢比每個班級中比平均年齡大的學生姓名信息:

SELECT name FROM student as s1 WHERE age > 
	(SELECT AVG(age) FROM student as s2 where s1.class_id = s2.class_id) 

這里根據每名同學的班級信息,查找出對應班級的平均年齡,然后做判斷。子查詢每次執(zhí)行時,都需要根據外部的查詢然后進行計算。這樣的子查詢就是關聯(lián)子查詢。

EXISTS 子查詢

在關聯(lián)子查詢中,常會和 EXISTS 一起使用。用來判斷條件是否滿足,滿足的話為 True,不滿足為 False。

比如查詢參加過學?;顒拥膶W生名稱:

SELECT NAME FROM student as s where \
	EXISTS(SELECT stu_id FROM student_activities as sa where sa.stu_id=s.id)

同樣 NOT EXISTS 就是不存在的意思,滿足為 FALSE , 不滿足為 True.

比如查詢沒有參加過學?;顒拥膶W生名稱:

SELECT NAME FROM student as s where \
	NOT EXISTS(SELECT stu_id FROM student_activities as sa where sa.stu_id=s.id)

集合比較子查詢

可以在子查詢中,使用集合操作符,來比較結果。

還是上面查詢參加學?;顒拥膶W生名字的子查詢, 同樣可以使用 IN:

SELECT name FROM student WHERE id IN (SELECT stu_id FROM student_activities)

EXISTS 和 IN 的區(qū)別

既然 EXISTS 和 IN 都能實現(xiàn)相同的功能,那么他們之間的區(qū)別是什么?

現(xiàn)在假設我們有表 A 和 表 B,其中 A,B 都有字段 cc,并對 cc 建立了 b+ 索引,其中 A 表 n 條記錄,B 表 m 條索引。

將其模式抽象為:

SELECT * FROM A WHERE cc IN (SELECT cc FROM B)

SELECT * FROM A WHERE EXIST (SELECT cc FROM B WHERE B.cc=A.cc)

對于 EXISTS 來說,會先對外表進行逐條循環(huán),每次拿到外表的結果后,帶入子查詢的內表中,去判斷該值是否存在。

偽代碼類似于下面:

for i in A
    for j in B
        if j.cc == i.cc:
         return result

首先先看外表 A,每一條都需要遍歷到,所以需要 n 次。內表 B,在查詢時由于使用索引進而查詢效率變成 log(m) B+ 的樹高,而不是 m。

進而總效率:n * log(m)

所以對于 A 表的數(shù)量明顯小于 B 時,推薦使用 EXISTS 查詢。

再看 IN ,會先對內表 B 進行查詢,然后用外表 A 進行判斷,偽代碼如下:

for i in B
    for j in A
        if j.cc == i.cc:
         return result

由于需要首先將內表所有數(shù)據查出,所以需要的次數(shù)就是 m. 再看外表 A ,由于使用了 cc 索引,可將 n 簡化至 log(n), 也就是 m * log(n).

所以對于 A 表的數(shù)據明顯大于 B 表時,推薦使用 IN 查詢。

總結一下對于 IN 和 EXISTS時,采用小表驅動大表的原則。

這里再擴展下 NOT EXISTS 和 NOT IN 的區(qū)別:

SELECT * FROM A WHERE cc NOT IN (SELECT cc FROM B) 

SELECT * FROM A WHERE NOT EXIST (SELECT cc FROM B WHERE B.cc=A.cc)

對于 NOT EXITS 來說,和 EXISTS 一樣,對于內表可以使用 cc 的索引。適用于 A 表小于 B 表的情況。

但對于 NOT IN 來說,和 IN 就有區(qū)別了,由于 cc 設置了索引 cc IN (1, 2, 3) 可以轉換成 WHERE cc=1 OR cc=2 OR cc=3 , 是可以正常走 cc 索引的。但對于 NOT IN 也就是轉化為 cc!=1 OR cc!=2 OR cc!=3 這時由于是不等號查詢,是無法走索引的,進而全表掃描。

也就是說,在設置索引的情況下 NOT EXISTS 比 NOT IN 的效率高。

但對于沒有索引的情況,IN 和 OR 是不同的:

一、操作不同
1、in:in是把父查詢表和子查詢表作hash連接。
2、or:or是對父查詢表作loop循環(huán),每次loop循環(huán)再對子查詢表進行查詢。

二、適用場景不同
1、in:in適合用于子查詢表數(shù)據比父查詢表數(shù)據多的情況。
2、or:or適合用于子查詢表數(shù)據比父查詢表數(shù)據少的情況。

三、效率不同
1、in:在沒有索引的情況下,隨著in后面的數(shù)據量越多,in的執(zhí)行效率不會有太大的下降。
2、or:在沒有索引的情況下,隨著or后面的數(shù)據量越多,or的執(zhí)行效率會有明顯的下降。

總結

這篇文章中主要歸納了一些 SQL 的基礎知識:

在使用 SELECT 查詢時,通過顯式指定列名,來減少 IO 的傳輸,從而提高效率。

并且需要注意 SELECT 的查詢過程會從 FROM 后開始到 LIMIT 結束,理解了整體的流程,可以讓我們更好的組織 SQL.

之后詳細介紹了 WHERE 進行過濾的操作符和常用的函數(shù),這里要注意在比較時間時要使用 DATE 函數(shù),以及如何對數(shù)據進行分組和過濾。

最后著重介紹了子查詢,IN 和 EXISTS 的適用場景。

以上就是快速學習MySQL基礎知識的詳細內容,更多關于MySQL基礎知識的資料請關注腳本之家其它相關文章!

相關文章

  • mysql的啟動過程詳解

    mysql的啟動過程詳解

    這篇文章主要介紹了mysql的啟動過程詳解,本文用生動風趣的文風講解了mysql的啟動過程,絕對讓你難忘哦,需要的朋友可以參考下
    2014-08-08
  • .Net Core導入千萬級數(shù)據至Mysql的步驟

    .Net Core導入千萬級數(shù)據至Mysql的步驟

    最近在工作中,涉及到一個數(shù)據遷移功能,從一個txt文本文件導入到MySQL功能。數(shù)據遷移,在互聯(lián)網企業(yè)可以說經常碰到,而且涉及到千萬級、億級的數(shù)據量是很常見的。今天我們就來談談MySQL怎么高性能插入千萬級的數(shù)據。
    2021-05-05
  • MySQL分區(qū)之HASH分區(qū)詳解

    MySQL分區(qū)之HASH分區(qū)詳解

    hash分區(qū)的目的是將數(shù)據按照某列進行hash計算后更加均勻的分散到各個分區(qū),下面這篇文章主要給大家介紹了關于MySQL分區(qū)之HASH分區(qū)的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • MySQL設置global變量和session變量的兩種方法詳解

    MySQL設置global變量和session變量的兩種方法詳解

    這篇文章主要介紹了MySQL設置global變量和session變量的兩種方法,每種方法給大家介紹的非常詳細 ,需要的朋友可以參考下
    2018-10-10
  • MySql中把一個表的數(shù)據插入到另一個表中的實現(xiàn)代碼

    MySql中把一個表的數(shù)據插入到另一個表中的實現(xiàn)代碼

    本篇文章是對MySql中把一個表的數(shù)據插入到另一個表中的實現(xiàn)代碼進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • windows下mysql中binlog日志分析和數(shù)據恢復問題

    windows下mysql中binlog日志分析和數(shù)據恢復問題

    這篇文章主要介紹了windows下mysql中binlog日志分析和數(shù)據恢復問題,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • MySQL5.7主從復制詳細配置教程

    MySQL5.7主從復制詳細配置教程

    這篇文章主要介紹了MySQL5.7主從復制詳細配置教程的相關資料,需要的朋友可以參考下
    2022-11-11
  • MySQL查詢數(shù)據庫中某個庫、表、索引等所占空間的大小

    MySQL查詢數(shù)據庫中某個庫、表、索引等所占空間的大小

    MySQL是一個非常流行的關系型數(shù)據庫管理系統(tǒng),它的查詢操作是非常強大和靈活的。查詢的效率不僅取決于表的大小,而且還取決于索引的大小,本文主要介紹了MySQL查詢數(shù)據庫中某個庫、表、索引等所占空間的大小,感興趣的可以了解一下
    2024-01-01
  • MySQL 編碼utf8 與 utf8mb4 utf8mb4_unicode_ci 與 utf8mb4_general_ci

    MySQL 編碼utf8 與 utf8mb4 utf8mb4_unicode_ci 與 utf8mb4_general_

    這篇文章主要介紹了MySQL 編碼utf8 與 utf8mb4 utf8mb4_unicode_ci 與 utf8mb4_general_ci的相關知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • Mysql5.7服務無法啟動的圖文解決教程

    Mysql5.7服務無法啟動的圖文解決教程

    這篇文章主要介紹了Mysql5.7服務無法啟動問題,解決辦法非常簡單,需要的的朋友參考下
    2017-02-02

最新評論

阳朔县| 金川县| 衡阳县| 方城县| 金坛市| 元朗区| 鄂州市| 宁强县| 平泉县| 松江区| 永泰县| 新绛县| 洛宁县| 江永县| 宜章县| 保靖县| 崇州市| 九龙县| 犍为县| 宜州市| 桑日县| 福贡县| 双桥区| 军事| 靖州| 满城县| 绍兴县| 泰州市| 新闻| 安塞县| 阿拉尔市| 新巴尔虎左旗| 皋兰县| 道真| 南溪县| SHOW| 深水埗区| 南丹县| 虹口区| 甘泉县| 泰州市|