1. 程式人生 > >[別被脫庫系列]1 資料庫的初戀

[別被脫庫系列]1 資料庫的初戀

>此資料庫系列,是學習工作中的總結,具體章節系列如下圖所示。如果您需要掃盲資料庫,突擊資料庫的面試,那就盤他,盤他!所謂初戀,初次見面,下凡資料庫基礎。請多多關照! ![童鞋別被脫褲系列](https://user-gold-cdn.xitu.io/2020/3/15/170dee4b75683c33?w=886&h=374&f=png&s=22931) [toc] ## 1 瞭解sql----長生不老,異常穩定 檢視近幾年的TIOBE發現了,一直在前十,可見是個老且管用的東西。 ![來自網路](https://user-gold-cdn.xitu.io/2020/3/15/170deab068ae7ac1?w=921&h=437&f=png&s=102829) 瞭解幾個術語: - DDL(Data Definition Language),定義資料庫物件。 - DML:(DATA Manipulation Language),用來操作和資料庫相關記錄。 - DCL:(Data Cnotrol Language)定義訪問許可權和安全級別。 - DQL(Data Query Language)。查詢記錄。 sql大小寫規範 - 表名、表別名、欄位名、欄位別名等可以小寫 - SQL保留字,函式名,繫結變數大寫 >SELECT name,age FROM student WHERE id="1"; ## 2 為啥要儲存資料 > 我們大部分的系統都會考慮到資料的儲存,那麼如何更有效地儲存好資料,做好資料備份。當我們擁有了資料,可以進行資料探勘,大資料分析,輿情預測,自然語言處理等等一系列的操作,可見儲存資料是多麼的重要。這一篇文章對資料庫基礎知識的掃盲,下一節將是資料儲存,資料備份等。另外我需要知道硬碟的處理速度比cpu,記憶體,網絡卡都會慢。 ## 3 DBMS是什麼 - DB、DBS和DBMS區別 | | 全稱 | 功能 | | ---- | -------------------------- | ----------------------------------------------- | | DBMS | DataBase Management System | 可對多個數據庫進行管理 | | DB | DataBase | 儲存樹的集合,理解為多個數據表 | | DBS | DataBase system | 老大哥。包含了資料庫管理系統和資料庫管理人員DBA | ## 4 當前主流的DBMS有哪些 > ## 5 sql與Nosql Nosql的timestamp: ![](https://user-gold-cdn.xitu.io/2020/3/15/170deb6e05297e3f?w=359&h=453&f=png&s=45413) 1970:Nosql=we have no sql 1980:Nosql=know sql 2000:Nosql=No SQL 2005:Nosql=not only sql 2013:Nosql=No,SQL 鍵值資料庫 > 通過key-value方式儲存,key為唯一表示,優點,查詢快,缺點是無法像關係型資料庫一樣使用條件過濾,這樣可能導致遍歷所有的鍵,消耗大量的計算。所以經常用來作為快取,比如redis。 文件資料庫 >管理文件,一個文件相當於一條記錄,MongoDB。 搜尋引擎 >雖然關係型資料庫常常通過索引的方式提高檢索效率(不一定),但是對於全文檢索卻比較低。搜尋引擎的優勢比如Elasticsearch、Splunk和Solr採用全文搜尋,核心原理為倒排索引 列式資料庫 >相對於行式資料庫,將資料按照列儲存,這樣可以大量降低系統的IO(因為相鄰的資料型別一樣,方便壓縮,自然就會降低IO),適合分散式檔案系統,比如 圖資料庫 >典型的就是網路中的人與人的關係,節點和邊關係。 ## 6 Oracle中的sql如何執行的 ![查詢執行流程](https://user-gold-cdn.xitu.io/2020/3/15/170deda570beff12?w=707&h=265&f=png&s=17810) - 語法檢查:檢查SQL拼寫是否正確。 - 語義檢查:檢查SQL訪問物件是否存在。 - 許可權檢查:檢查使用者是否有訪問許可權。 - 共享池檢查:包含了庫快取、資料字典緩衝區等。主要用來緩衝執行計劃或者表、檢視等物件。 - 優化器:進行硬解析,決定建立解析樹和生成執行計劃應該怎麼做 - 執行器:有了優化器,那麼在執行器思考如何被執行 ## 7 mysql中sql如何執行的 ![查詢執行流程](https://user-gold-cdn.xitu.io/2020/3/15/170dec0271e313f4?w=678&h=381&f=png&s=34972) - 查詢快取 >首先注意,mysql8.0之後已經放棄了這個功能(因為如果資料更新,快取會情況,如果為動態資料經常更新,這樣反而增加SQL查詢時間)。快取通常的理解是一箇中間層,如果在中間層存在查詢語句就直接返回,如果沒有則給解析器處理。 - 解析層 >主要進行語法分析和語義分析。 - 優化器 >確定SQL語句的執行路徑。是根據全表檢索還是根據索引。 - 執行器 >進行許可權檢查。 那麼mysql和oracle兩者執行情況有啥不一樣呢 >MySql具有多種儲存引擎且可以自定義儲存引擎,那麼有哪些儲存引擎,優點缺點是啥? | | 描述 | | --------------- | ------------------------------------------------------------ | | InnoDB | Mysql5.5以後預設儲存引擎,支援事務,行級鎖,外來鍵約束 | | MyISAM | Mysql5.5以前為預設儲存引擎,不支援事務和外來鍵,最大特點速度快,佔資源少 | | Memory儲存引擎 | 使用系統記憶體為儲存介質,更快的響應速度。 | | NDB儲存引擎 | 用於Mysql Cluster分散式叢集環境 | | Archive儲存引擎 | 壓縮機制的特點便於檔案的歸檔,常用來做倉庫 | ## 8 如何檢視一條sql的資源使用情況 - prifiling是否開啟 >mysql> select @@profiling;如果為0代表關閉,設定為1表示開啟。 - 執行sql查詢語句 >mysql> select *from student; - 檢視當前所有profiles >show profiles;檢視當前會話的profiles - 檢視執行時間show profile ## 9 DDL - 建立資料庫 >#建立公眾號原創作者資料庫 > >CREATE DATABASE WeChat_Official_Account_Author; - 建立表結構(注意語句最後;結束,最後一個欄位定義結束沒有逗號) >#建立表 作者名(author_id,author_name且id為遞增) > >CREATE TABLE authors_name(author_id int(15) NOT NULL AUTO_INCREMENT), > >author_name varchar(255) NOT NULL); - 新增欄位 >ALTER TABLE authors_name ADD(age int(12)); - 修改欄位名 >ALTER TABLE authors_name RENAME_COLUME age to author_age; - 刪除欄位 >ALTER TABLE author_names DROP COLUME author_age; ## 10 資料庫的常見約束 >不成規矩,不成方圓 - 主鍵約束 >唯一標識一條記錄,不重複且不能為空(UNIQUE+NOT NULL)。主鍵可以使是一個欄位或者多個欄位的組合,一個數據表主鍵只能有一個 - 外來鍵約束 >外來鍵確保表與表之間引用的完整性。外來鍵可以重複也可以為空。 - 唯一性約束 >欄位在表中可以使唯一的。 - NOT NULL約束 >表明欄位不應為空,必須有取值。 - CHECK約束 >檢查特定欄位取值範圍的有效性 ## 11 常見查詢語句 - 查詢姓名列 >#查詢單列 > >SELECT author_name FROM authors_name; > >#查詢所有列 > >SELECT * FROM authors_name; - 去除重複行 >SELECT DISTICT age FROM authors_name; - 查詢排序 >#ASC 遞增排序,DESC遞減排序 > >SELECT author_name FROM authors_names ORDER BY age DESC; - 約束返回結果的個數 >#返回5條資料 LIMIT需要放在最後 > >SELECT author_name FROM authors_names ORDER BY age DESC LIMIT 5; - SELECT語句中關鍵字順序 >關鍵字的順序:SELECT.....FROM...WHERE...GROUP BY - SELECT語句的執行順序 >FROM>WHERE>GROUP BY HAVING>SELECT - 那麼一句sql的執行原理是什麼?請看下圖。 ## 12 sql運算子 - 比較運算子(不同的DBMS支援的運算子可能不同) ![比較運算子](https://user-gold-cdn.xitu.io/2020/3/15/170dee22626ef6b6?w=545&h=353&f=jpeg&s=29595) - 邏輯運算子 ![邏輯運算子](https://user-gold-cdn.xitu.io/2020/3/15/170dee149faeafbb?w=482&h=234&f=jpeg&s=15738) >當WHERE字句中同時出現OR和AND的時候,AND執行優先順序會更高。一般來說()優先順序最高,其次是AND,然後是OR。 - 萬用字元過濾 >萬用字元是對文字型別進行模糊哈訊,但是通常是全表掃描,所以效率很低。只有當LIKE後面沒有萬用字元,並對欄位進行索引的時候不會進行全表掃描。匹配一部分特殊字元。"LIKE"操作符。 - 萬用字元匹配之任意字串出現的任意次數(%) - 萬用字元匹配之耽擱字元(_) ## 13 常見sql函式 >提供函式,類似介面,更方便快速的得出想要的結果。 | | 描述 | 例子 | | -------------------- | ------------------------------------------------------------ | ------------------------------------------------------ | | ABS() | 取絕對值 | SELECT ABS(-5)---5 | | MOD() | 取餘 | SELECT MOD(101,3)---2 | | ROUND() | 四捨五入為指定的小數位數,如果兩個引數,分別為欄位名稱和小數位數 | SELECT ROUND(38.29,1)--38.3 | | LENGTH() | 計算欄位長度。一個漢字三個字元。 | SELECT LENGTH('小藍')--6 | | UPPER() | 字元轉大寫 | SELECT LOWER('qwe')--QWE | | LOWER() | 字元轉小寫 | SELECT LOWER('QWE')--qwe | | REPLACE() | 替換函式 | SELECT REPLACE('QWE123D','QWE',789)--789123D | | SUBSTRING() | 擷取字串 | SELECT SUBSTRING('QWE123',1,3)-- | | CHAR_LENGTH() | 計算機欄位的長度,漢字,數字都算一個字元 | SELECT CHAR_LENGTH('小藍')--2 | | CONCAT() | 連線字串 | SELECT CONCAT('XIAOLAN',789)---XIAOLAN789 | | DATA() | 返回時間的日期 | SELECT DATA('2020-03-13 11:30:20')--2020-03-13 | | YEAR()/MONTH()/DAY() | 返回時間的年份/月份/天數 | SELECT YEAR(NOW())--2020 | | HOUR() | 返回時間的小時 | SELECT hour('12:13:14')--12 | | MINUTE() | 返回時間的分鐘 | SELECT MINUTE('12:13:14')--13 | | SECOND() | 返回時間的秒部 | SELECT SECOND('12:13:14')--14 | | CURRENT_DATE() | 系統當前日期 | SELECT CURRENT_DATE('2020-03-13 11:30:20')--2020-03-13 | | CURRENT_TIME() | 系統當前時間,沒有具體日期 | SELECT CURRENT_TIME('2020-03-13 11:30:20')--11:30:20 | | CURRENT_TIMESTAMP() | 日期+時間 | SELECT CURRENT_TIMESTAMP--2020-03-13 11:30:20 | ## 14 聚集函式 | | 描述 | 例子 | | ------- | ----------------------------- | ---------------------------------------------- | | COUNT() | 總行數,不管某個欄位是否為NULL | SELECT COUNT(*) FROM authors_name WHERE age>25 | | MAX() | 最大值 | SELECT MAX(Age) FROM authors_name | | MIN() | 最小值 | SELECT MIN(Age) FROM authors_name | | SUM() | 求和 | SELECT SUM(Age) FROM authors_name | | AVG() | 平均值 | SELECT AVG(Age) FROM authors_name | - 資料分組 >使用GROUP BY字句進行資料分組。 - HAVING過濾分組和WHERE的區別 >WHERE 是用於資料行,而 HAVING 則作用於分組。如果分組完以後需要排序,就在其後增加ORDER BY完成 ## 17 檢視 - 什麼是檢視 >檢視可以理解為一箇中間表(結果集),咋們叫虛擬表,它主要把我們經常查詢的結果存放於中,從而提升使用的效率。本身不具有資料。如下圖所示。 - 為什麼使用檢視 :baby_bottle:重用SQL語句 :baby_bottle:使用表的一部分而不是整個表 :baby_bottle:更改資料格式和表示。 :baby_bottle:通過授予表的特定訪問許可權來保護資料,。。 - 如何使用檢視 :v: - 使用檢視過濾不想想要的資料 - 更新檢視 ## 18 事務處理 >要麼完全執行,要麼不執行。 - A(Atomicity)原子性。不可分割,進行資料處理的基本單位。 - C(Consistency)。在進行事務操作以後,會從一致的狀態變為另一種一致的狀態。即使事務回滾也不能被破壞。 - I(Isolation)隔離性。事務的獨立性。一個事務在提交之前,對其他的事務不可見。 - D(Durability)。通過事務日誌保證。即使系統崩潰,通過資料庫日誌的更新讓系統恢復到最後一次成功的更新狀態。 ## 19 事務隔離 >我們知道當在高併發的情況下,這個時候需要較高的吞吐量,那麼採取方式之一就是將原來的序列操作變化為並行。這個時候可以通過降低資料庫的隔離標準,來換取事務的併發能力。 講述相關內容之前,我們先定義一個表如下。 | ID | Age | Name | | ---- | ---- | ---- | | 1 | 18 | 小藍 | | 2 | 19 | 小林 | | 3 | 20 | 小旋 | - 髒讀 小藍今天想去看看資料庫內容,並想把朋友小地增加到資料庫中,於是操作如下: ```sql SQL> BEGINT: SQL> INSERT INTO authors value(4,20,"小地"); ``` 此時小藍還沒有提交這個事務,小林去訪問了這個表(小林去年買了個表,哈哈哈嗝),於是 ```sql SQL>SELECT * FROM authors; ``` 然後得到這個結果: | ID | Age | Name | | ---- | ---- | ---- | | 1 | 18 | 小藍 | | 2 | 19 | 小林 | | 3 | 22 | 小旋 | | 4 | 20 | 小地 | 結論:小藍還沒有提交事務,小林訪問卻看到了增加的小地,這就是髒讀。 - 不可重複讀 小藍聽說小地也在表裡,然後想看看是為何人如此牛掰,幾歲了? ```sql SQL> SELECT Age FROM authors where Name="小地" ``` 結果如下: | Age | | ---- | | 20 | 我的天,這麼年輕?小藍試圖用個事務去修改其年齡 ``` SQL>BEGIN; SQL>UPDATE authors SET Age = 25 where Name='小地' ``` 此時小藍去查詢下修改是否成功 ```sql SQL>SELECT Age FROM authors where Name='小地' ``` 結果如下: | Age | | ---- | | 25 | 牛掰,修改成功?那麼問題來了,小藍雖然修改了,但是並沒有提交呀,這就是不可重複讀,兩次查詢出現了不同的結果。 - 幻讀 今天小旋過來想看看,表裡都有哪些小夥伴。 ```sql SQL> SELECT *FROM authors; ``` 結果如下: | ID | Age | Name | | ---- | ---- | ---- | | 1 | 18 | 小藍 | | 2 | 19 | 小林 | | 3 | 22 | 小旋 | | 4 | 20 | 小地 | 這個時候小林遇到個小妹妹,發現其文采還不錯,開啟個事務將其放入表中。 ```sql SQL> BEGIN; SQL> INSERT INTO authors values(5,'21','小魏') ``` 小林記性太好了,於是還想看看到底有哪些人, ```sql SQL> SELECT * FROM authors; ``` 結果如下 | ID | Age | Name | | ---- | ---- | ---- | | 1 | 18 | 小藍 | | 2 | 19 | 小林 | | 3 | 22 | 小旋 | | 4 | 20 | 小地 | | 5 | 21 | 小魏 | 啊!小林驚呆了,怎麼多了個妹妹!!!這就是幻讀! - 隔離級別 | | 髒讀 | 不可重複讀 | 幻讀 | | -------- | ---- | ---------- | ---- | | 讀未提交 | 允許 | 允許 | 允許 | | 讀已提交 | 禁止 | 允許 | 允許 | | 可重複讀 | 禁止 | 禁止 | 允許 | | 可序列化 | 禁止 | 禁止 | 禁止 | 總結下: 讀未提交: >允許髒讀,也就是可能讀取到其他會話中未提交事務修改的資料 讀已提交 >只能讀取到已經提交的資料。Oracle等多數資料庫預設都是該級別 (不重複讀) 可重複讀 >可重複讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB預設級別。在SQL標準中,該隔離級別消除了不可重複讀,但是還存在幻讀 序列讀: >全序列化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞. ## 20 python如何操作oracle ![簡單操作](https://user-gold-cdn.xitu.io/2020/3/16/170e235e86460b1f?w=2048&h=842&f=png&s=218039) - 插入資料 ![插入資料](https://user-gold-cdn.xitu.io/2020/3/16/170e236442d80ecd?w=2048&h=1562&f=png&s=392784) - 查詢資料 ![查詢資料](https://user-gold-cdn.xitu.io/2020/3/16/170e236a4180f343?w=1424&h=1562&f=png&s=322619) ## 21 初探調優 為什麼調優,無非就是希望響應更快,吞吐量更大,使用者體驗更好。 >那麼怎麼獲得反饋 - 使用者 >他們是直接體驗者,來的直接。 - 日誌匯聚分析,伺服器監控,資料庫內部監控 >通過效能工具進行檢視,想起一張圖送給大家。 這裡是效能指標圖 >一般從哪幾個方面著手資料庫調優,總之沒有最好,只有更合適。 - 前期DBMS的調研,選擇合適業務的DBMS >比如需要有事務處理能力,可以選擇mysql的InnoDB。如果採用如果考慮大幅度的降低系統IO,那麼可以考慮Nosql中的列式資料庫,之前說過列式儲存方便使用壓縮,但是不適合頻繁的增刪改。 - 選擇合適的快取比如redis >將經常使用的資料放入快取中(記憶體),提升查詢效率。 - 庫級別的優化 >主從架構優化讀寫策略,具體方法請關注系列篇第二節。 >好了,上面的基礎部分學習應該差不多了,那麼資料庫相關的優化,主從架構,讀寫分離,資料庫的分片等都是怎麼樣的呢?盡請期待後續學習分享,一起成長! 參考資料 《mysql必知必會》 《mysql45講》 https://blog.csdn.net/gengkui9897/article/details/89294936 《高效能