《原神攻略》折箭覓蹤第一天活動攻略
SQL -- MySQL
-
基本型別
- 字元型,數值型,日期型
- 字元型(VARCHARVS,CHAR,TEXT,TINYTEXT ...)
- VARCHARVS是可變長度字串,長度超過255會變成TEXT
- CHAR是固定字串,最大長度為255
- 數值型(INT,BIGINT,FLOAT,DOUBLE...)
- 日期型(DATE,TIME...)
-
常見函式
- 字元函式
- concat : 連線
- substr :擷取子串
- upper / lower : 變 大寫 / 小寫
- replace : 替換
- length : 長度
- trim :去除首位空格
- instr :獲取子串第一次出現的位置
- 數學函式
- round :四捨五入取較大
- ceil :四捨五入向上取整
- floor :四捨五入向下取整
- mod :取模
- truncate :截斷
- rand :獲取0~1的隨機數
- 日期函式
- now :返回當前日期+時間
- year/month/day :年/月/日
- date_format :將日期轉換成字串
- curdate / curtime :返回當前日期 / 時間
- str_to_date :字元轉換日期(指定格式)
- hour / minute / second :時 / 分 / 秒
- datediff :返回兩個日期相差的天數
- monthname :以英文形式返回月份
- 其它函式
- version :返回當前伺服器的資料庫版本
- database :當前開啟的資料庫
- user :當前使用者
- md5 :返回該字元通過md5加密後的形式
- 字元函式
-
一些常用的SQL語句
- SELECT - 從資料庫中提取資料
- UPDATE - 更新資料庫中的資料
- DELETE - 從資料庫中刪除資料
- INSERT INTO - 向資料庫中插入新資料
- CREATE DATABASE - 建立新資料庫
- ALTER DATABASE - 修改資料庫
- CREATE TABLE - 建立新表
- ALTER TABLE - 變更(改變)資料庫表
- DROP TABLE - 刪除表
- CREATE INDEX - 建立索引(搜尋鍵)
- DROP INDEX - 刪除索引
-
SELECT
-
select 查詢列表
-
form 表1
-
連線型別 join 表2
-
on 連線條件
-
where 篩選條件
-
group by 分組列表
-
having 分組後篩選
-
order by 排序列表
-
limit 偏移,條目數
解析過程 :
-
-
約束
- 型別:
- not null:非空
- unique:唯一
- default:預設
- check:檢查(mysql不支援)
- primary key:主鍵
- foreign key:外來鍵
- 語法
- 新增:alter table 表名 add 約束型別 欄位名
- 刪除:alter table 表名 drop 約束型別 欄位名
- 主鍵和唯一的區別
- 異:一個表最多隻能有一個主鍵,唯一可以多個;主鍵不能為null,唯一可以
- 同:都具有唯一性;都支援組合鍵(不推薦)
- 外來鍵
- 用於限制兩表的關係,從表引用主表的主鍵的某個欄位,型別需一樣,名稱無要求;
- 主表被引用的列要求是一個key(一般就是主鍵);
- 保護資料:插入資料,先插入主表;刪除資料,先刪除從表(級聯刪除,級聯置空);
- 型別:
-
自增長列(auto_increment_increment,auto_increment_offset)
- 特點:
- 預設從1開始,步長為1(修改起始值:手動插入值;修改步長:set auto_increment_increment = 值)
- 一個表最多隻能有一個自增長列
- 自增長列只能支援數值型(整數,浮點數)
- 自增長列必須為一個key(MySQL)
- 語法:
- create table 表(欄位名 欄位型別 約束 auto_increment)
- alter table 表 modify column 欄位名 欄位型別 約束 auto_increment
- alter table 表 modify column 欄位名 欄位型別 約束
- 特點:
-
變數
-
流程結構
- 順序結構
- 分支結構
- if case
- 迴圈結構
- while
- loop
- repeat
-
儲存過程和函式
-
儲存過程 :
-
作用 : 提高程式碼複用性,簡化操作
-
建立語法:
create procedure 儲存過程名(引數列表) begin 儲存過程體(一組合法的sql語句) end
- 引數列表:引數模式 引數名 引數型別
- 引數模式:IN 輸入; OUT 作為返回值; INOUT 即是輸入也是返回值
- 儲存過程中的每條SQL語句的幾位都需要加分號(delimiter可以設定結束標記)
-
呼叫 : CALL 儲存過程名
-
檢視 : SHOW CREATE PROCEDURE 儲存過程名
-
刪除 : DROP PROCEDURE 儲存過程名
-
-
函式 :
-
建立 :
create function 函式名(引數列表 -> 引數名, 引數型別) returns 返回型別 begin 函式體(return 值) end
-
呼叫 : select 函式名(引數列表)
-
檢視 : show create function 函式名
-
刪除 : drop function 函式名
-
-
儲存過程與函式的區別 :
- 儲存過程:可以有0個或多個返回值,適合做批量插入,更新
- 函式:有且僅有一個返回值,適合做處理資料後返回一個結果
-
-
檢視(虛擬表)
-
優點:
- 重用sql語句
- 簡化複雜的sql操作,不必找到查詢細節
- 保護資料,提高安全性
-
建立檢視:
create view 檢視名 as 查詢語句
-
修改:
create or replace view 檢視名(存在則修改,否則則建立) as 查詢語句 #或者 alter view 檢視名 as 查詢語句
-
刪除:drop view 檢視名1,檢視名2...
-
檢視:show create view 檢視名 / desc 檢視名
-
注意點:
- 檢視一般用於查詢,不用於修改
- 以下情況不允許修改:
- 包含分組函式:group by,distinct,having,union
- join
- 常量檢視
- where後的子查詢用到了from中的表
- 用到了不可更新的檢視
-
檢視與表的關係:
關鍵字 是否佔用物理空間 使用 檢視 view 佔用較小,只儲存sql邏輯 一般用於查詢 表 table 儲存實際資料 增刪改查
-
-
事務:
- 特性:(ACID)
- 原子性:一個事務不可再分割,要麼都執行,要麼都不執行
- 一致性:一個事務執行會使資料從一個一致的狀態切換到另一個狀態
- 隔離性:一個事務的執行不受其它事務的干擾
- 永續性:一個事務一旦提交,則會永久的改變資料庫數
- 事務的建立:
- 隱式事務:事務沒有明顯的開啟和關閉的標記
- 如:insert,update,delete語句
- 原因:事務的自動提交功能預設為開啟狀態(show variables like 'autocommit'; -> Value : ON)
- 關閉方法:set autocommit = 0 -> Value : OFF
- 顯式事務:有明顯的開啟和結束標記
- 開啟事務
- (set autcommit = 0)
- start transaction; (可選)
- 編寫sql語句
- (select,insert,update,delete) 可以有多個語句
- 結束事務
- commit:提交事務 -- 全部正常執行
- rollback:回滾事務 -- 出現異常(delete能回滾,而truncate不能)
- savepoint a :設定儲存點a
- rollback to a :回滾到儲存點a
- 開啟事務
- 隱式事務:事務沒有明顯的開啟和關閉的標記
- 特性:(ACID)
-
資料庫的隔離級別:
-
對於同時執行多個事務,當這些事務訪問資料庫中相同的資料時,如果沒有采用必要的隔離機制,就會導致各種併發問題
-
併發問題:
- 髒讀:對於兩個事務T1,T2;T1讀取了已經被T2更新但還沒提交的欄位,之後若T2回滾,T1讀到的資料內容就是臨時且無效的
- 不可重複讀:對於兩個事務T1,T2;T1讀取了一個欄位,然後T2更新了該欄位,之後,T1再次讀取同一個欄位,值就不同了
- 幻讀:對於兩個事務T1,T2;T1從一個表讀取了一個欄位,然後T2在該表中插入(或刪除)了一些新的行,之後,T1再次讀取同一個表就會多出(少)幾行
-
隔離級別:
隔離級別 說明 解決的併發問題 讀未提交(Read uncommitted) 允許事務讀取未被其他事務提交的變更 都有可能發生 讀已提交(Read committed) 只允許事務讀取已經被其他事務提交的變更 可以避免髒讀 可重複讀(Repeatable read) 在這個事務期間,禁止其它事務對此欄位進行更新 可以避免髒讀和不可重複讀 序列化(Serializable ) 在這個事務期間,禁止其它事務對該表的操作 可以解決以上三種問題 -
MySQL預設隔離級別:可重複讀 -- REPEATABLE-READ(查詢方法:select @@tx_isolation;)
-
MySQL支援以上四種隔離級別,Oracle支援:讀已提交(預設) 和 序列化
-
設定隔離級別:
set tx_isolation='隔離級別'; #read-uncommitted, read-committed, repeatable-read, serializable set transaction isolation level '級別' #當前資料庫 set global transaction isolation level '級別' #全域性
-
-
MySQL架構
-
MySQL的架構使得它可以在不同的場景下應用併發揮良好的作用,外掛的儲存引擎架構將查詢處理和其它的系統任務以及資料的儲存提取分離(可以根據業務的需求和實際選擇合適的儲存引擎)
-
MyISAM 和 InnoDB
MyISAM InnoDB(預設) 主外來鍵 不支援 支援 事務 不支援 支援 行表鎖 表鎖,即使操作一條記錄也會鎖住整個表,不適合高併發 行鎖,操作時只鎖一行,不對其它行有影響,適合高併發 快取 只快取索引,不快取真實資料 不僅快取索引,也快取真實資料,對記憶體要求較高(記憶體大小對效能有直接關係) 表空間 小 大 關注點 效能 事務 預設安裝 Y Y
-
-
JOINS:
-
MySQL索引:
-
索引是什麼:
- 索引是一種資料結構 -> 排好序的快速查詢資料結構
- 由於索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以檔案的格式儲存在磁碟上
- 一般是指B樹(多路搜尋樹)結構組織的索引;其中聚集索引,次要索引,複合索引,字首索引,唯一索引預設都是使用B+樹索引,統稱索引(除了B+樹外,還有雜湊索引等等)
-
優勢:
- 提高資料檢索的效率,降低資料庫的IO成本
- 通過索引列對資料進行排序,降低資料排序的成本,降低CPU消耗
-
劣勢:
- 實際索引也是一張表,該表儲存了主鍵和索引欄位,並指向實體表(佔用空間)
- 提高查詢速度的同時,會降低更新表的速度(不僅要儲存資料,也需要修改索引)
- 索引只是提高效率的一個因素,有大量資料量表時,需要不斷建立最優索引
-
索引分類:
- 單值索引:一個索引只包含單個列,一個表可以有多個單列索引(最好不要超過5個)
- 唯一索引:索引列的值必須唯一,但允許空值
- 複合索引:即一個索引包含多個列
-
語法:
-
建立:
create [unique] index 索引名 on 表名(列名/欄位) alter 表名 add [unique] index [索引名] on (列名/欄位)
-
刪除:
drop index [索引名] on 表名
-
檢視:
show index from 表名
-
ALTER;
-
-
索引失效情況:
- 全值匹配最愛
- 最佳左字首法則(索引必須依次使用,從左到右(MySQL會自動優化順序),中間索引不能斷,否則後面的索引會失效)
- 不在索引列上做任何操作(計算,函式,(自動或手動)型別轉換)
- 儲存引擎不能使用使用中範圍右邊的列(中間索引不能斷)
- 儘量使用覆蓋所有(即所有列與查詢列一致,加少select *)
- MySQL在使用不等於(!= 或 <>)時,會導致索引失效
- is null,is not null 也無法使用索引
- like 以萬用字元開頭("%aa...")會導致索引失效,而("aa%")不會;如果一定要使用("%aa...")建議使用覆蓋索引(即查詢列與索引列對應)
- 字串不加單引號會導致索引失效(會發生自動隱式型別轉換)
- 少用or,用它來連線時會導致索引失效
-
索引結構:
- BTree 索引:真實的資料存在葉子節點,非葉子節點不儲存真實的資料,只儲存指引搜尋方向的資料項
- Hash 索引
- full-text 全文索引
- R-Tree 索引
-
索引的適用情況:
- 主鍵自動建立唯一索引
- 頻繁作為查詢條件的欄位應該建立索引
- 查詢中與其它表關聯的欄位,外來鍵關係建立索引
- 查詢中排序的欄位,排序欄位若通過索引去訪問將大大提高排序速度
- 查詢中統計或分組欄位
- 高併發下偏向於建立聯合索引
-
不適合建立索引的情況:
- 表記錄較少
- 經常增刪改的表
- 資料重複且分佈均勻的欄位(比如:性別)
-
SQL效能分析:
-
語法:Explain + SQL語句
-
包含的資訊
id select_type table partitions type possible_keys key key_len ref rows filtered Extra -
id:select查詢的序列號,表示查詢中執行select子句或操作表的順序
- 三種情況:
- id 相同:表示順序由上至下
- id 不同:如果是子查詢,id的序號會遞增,id值越大,優先順序越高,越先被執行
- 同時存在相同的id和不同的id:
- 三種情況:
-
select_type:查詢的型別,主要用於區別普通查詢,聯合查詢,指查詢等複雜查詢(6種類型)
- SIMPLE:簡單的select查詢,不包含子查詢和UNION
- PRIMARY:查詢中若包含任何複雜的子部分,最外層將用此標記
- SUBQUERY:在select 或 where 列表中包含了子查詢
- DERIVED:在From列表中包含的子查詢被標記為DERIVED(衍生),MySQL會遞迴執行這些子查詢,並將結果放於臨時表中
- UNION:若第二個select出現在UNION之後,則被標記為UNION。若UNION包含在FROM子查詢中,外層select將被標記為DERIVED
- UNION RESULT:從UNION表獲取結果的select
-
table:表名
-
type:訪問型別排列(從好到差:system > const > eq_ref > ref > range > index > ALL)
- system:表中只有一條記錄(等於系統表)
- const:表示通過一次索引就找到了,用於比較Primary key 或 union
- eq_ref:唯一性索引掃描,對於每個索引列,表中只有一條記錄與之匹配,1對1
- ref:非唯一索引掃描,返回匹配某個單獨值的所有列,1對n ---> 佳
- range:只檢索給定的範圍的行,使用一個索引來選擇行(如 > , < , between in)---> 至少
- index:Full Index Scan 遍歷索引樹
- ALL:全表掃描
-
possible_keys,key:判斷索引的使用情況
- possible_keys(理論上):顯示可能應用在這張表中的索引,一個或多個(實際不一定使用到)
- key(實際上):實際使用的索引,如果為null,則沒有使用索引(索引失效),若使用了覆蓋索引,則該索引僅出現在key列表中
-
key_len:表索引中使用的位元組數,在不損失精度的情況下,長度越短越好(最大可能的長度,並非實際使用的長度)
-
ref:顯示索引的哪一列被使用了,如果可能話,是一個常數
-
rows:根據表統計的資訊及索引選用的情況,大致估算出找到所需的記錄所需要讀取的行數
-
Extra:包含不適合在其它列顯示但十分重要的資訊
- Using filesort:說明MySQL會使用外部的索引排序,而不是按表內的索引順序進行讀取(多了排序)儘量不出現,降低效率
- Using temporary:使用臨時表儲存中間結果(傷效能),常見於order by 和 group by;儘量避免
- Using Index:表示使用了覆蓋索引(所需的資料在索引中就能得到,不必再讀取資料檔案,查詢的列被索引覆蓋),效能不錯,避免了訪問表的資料行,如果同時出現Using where則代表索引被用來執行鍵值的查詢,如果沒有則代表索引用來讀取資料而非查詢操作
- Using where:
- Using join Buffer:
- impossible where:
- select tables optimized away:
- distinct:
-
-
- 資料庫鎖機制:
- 分類:
- 讀鎖(共享鎖):針對同一份資料,多個讀操作互不影響
- 寫鎖(排它鎖):當前寫操作未完成前,會阻斷其它的寫鎖和讀鎖
- MySQL的三種鎖:
- 表鎖(偏讀):
- 特點:偏向於MyISAM儲存引擎,開銷小,加鎖快,無死鎖;但鎖的粒度大,發生鎖衝突的概率最高,併發度低
- 兩種表級鎖:
- 表共享讀鎖:阻塞所有的寫操作,但不影響讀操作
- 表獨佔寫鎖:阻塞其它程序的讀和寫操作
- 行鎖(偏寫):
- 特點:偏向於InnoDB儲存引擎,開銷大,加鎖慢,會可能出現死鎖,但鎖的粒度小,發生鎖的衝突概率小,併發度高
- InnoDB 與 MyISAM 最大不同:1.支援事務 ,2.採用行級鎖
- 若索引失效,行鎖會升級為表鎖
- 行級鎖:
- 共享鎖
- 排它鎖
- 表級鎖:
- 意向共享鎖
- 意向排他鎖
- 間隙鎖:
- 通過範圍查詢的話,它會鎖定整個範圍內所有的索引鍵值,即使這個鍵值並不存在
- 作用:
- 防止幻讀,以滿足相關隔離級別的要求。
- 為了資料恢復和複製的需要。
- 缺點:
- 間隙鎖有一個比較致命的弱點,就是當鎖定一個範圍鍵值之後,即使某些不存在的鍵值也會被無辜的鎖定,而造成在鎖定的時候無法插入鎖定鍵值範圍內的任何資料。在某些場景下這可能會對效能造成很大的危害
- 當Query無法利用索引的時候, Innodb會放棄使用行級別鎖定而改用表級別的鎖定,造成併發效能的降低;
- 當Quuery使用的索引並不包含所有過濾條件的時候,資料檢索使用到的索引鍵所指向的資料可能有部分並不屬於該Query的結果集的行列,但是也會被鎖定,因為間隙鎖鎖定的是一個範圍,而不是具體的索引鍵;
- 當Query在使用索引定位資料的時候,如果使用的索引鍵一樣但訪問的資料行不同的時候(索引只是過濾條件的一部分),一樣會被鎖定
- 優化:InnoDB行級鎖鎖的是索引
- 儘可能讓所有的資料檢索都通過索引的方式完成,避免無索引行鎖升級為表鎖
- 合理設計索引,儘量縮小鎖的範圍
- 儘可能較少檢索條件,避免間隙鎖
- 儘量控制事務的大小,減少鎖定資源和時間長度
- 儘可能低級別事務隔離
- 死鎖:
- 發現死鎖: 在InnoDB的事務管理和鎖定機制中,有專門檢測死鎖的機制,會在系統中產生死鎖之後的很短時間內就檢測到該死鎖的存在
- 解決方法:
- 回滾較小的那個事務(判斷大小:事務各自插入、更新或者刪除的資料量)
- 在REPEATABLE-READ隔離級別下,如果兩個執行緒同時對相同條件記錄用SELECT…FOR UPDATE加排他鎖,在沒有符合該條件記錄情況下,兩個執行緒都會加鎖成功。程式發現記錄尚不存在,就試圖插入一條新記錄,如果兩個執行緒都這麼做,就會出現死鎖。這種情況下,將隔離級別改成READ COMMITTED,就可避免問題。
- 避免的方法:
- 如果不同程式會併發存取多個表,儘量約定以相同的順序訪問表,可以大大降低死鎖機會。
- 在同一個事務中,儘可能做到一次鎖定所需要的所有資源,減少死鎖產生概率;
- 對於非常容易產生死鎖的業務部分,可以嘗試使用升級鎖定顆粒度,通過表級鎖定來減少死鎖產生的概率;
- 頁鎖:介於表鎖和行鎖之間,會出現死鎖,併發度一般,較少使用
- 表鎖(偏讀):
- 分類: