CREATE、ALTER、DROP、TRUNCATE、COMMENT、RENAMEmysql
SELECT、INSERT、UPDATE、DELETE、MERGE、CALL、EXPLAIN PLAN、LOCK TABLEweb
內鏈接是一種一一映射關係,就是兩張表都有的才能顯示出來 redis
SELECT A.PK AS A_PK,A.Value AS A_Value,B.PK AS B_PK,B.Value AS B_Value
FROM table_a A
INNER JOIN table_b B
ON A.PK = B.PK;
複製代碼
左鏈接是左邊表的全部數據都有顯示出來,右邊的表數據只顯示共同有的那部分,沒有對應的部分只能補空顯示,所謂的左邊表其實就是指放在left join的左邊的表 sql
SELECT A.PK AS A_PK,A.Value AS A_Value,B.PK AS B_PK,B.Value AS B_Value
FROM table_a A
LEFT JOIN table_b B
ON A.PK = B.PK;
複製代碼
右鏈接正好是和左鏈接相反的,這裏的右邊也是相對right join來講的,在這個右邊的表就是右表 數據庫
SELECT A.PK AS A_PK,A.Value AS A_Value,B.PK AS B_PK,B.Value AS B_Value
FROM table_a A
RIGHT JOIN table_b B
ON A.PK = B.PK;
複製代碼
查詢出左表和右表全部數據,可是去除兩表的重複數據 後端
由於mysql不支持全鏈接,只能用如下代碼實現效果,含義是左鏈接+右鏈接+去重=全鏈接:SELECT A.PK AS A_PK,A.Value AS A_Value,B.PK AS B_PK,B.Value AS B_Value
FROM table_a A
LEFT JOIN table_b B
ON A.PK = B.PK
UNION
SELECT A.PK AS A_PK,A.Value AS A_Value,B.PK AS B_PK,B.Value AS B_Value
FROM table_a A
RIGHT JOIN table_b B
ON A.PK = B.PK;
複製代碼
沒有 WHERE 子句的交叉聯接將產生聯接所涉及的表的笛卡爾積。第一個表的行數乘以第二個表的行數等於笛卡爾積結果集的大小。 用法:A CROSS JOIN B (不要ON)緩存
關係數據庫中的關係是要知足必定要求的,知足不一樣程度要求的爲不一樣範式。bash
詳細內容參考:知乎——解釋一下關係數據庫的第一第二第三範式?_劉慰服務器
索引是一種數據結構 。數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現一般使用B樹及其變種B+樹。
B樹能夠在內部節點同時存儲鍵和值,所以,把頻繁訪問的數據放在靠近根節點的地方將會大大提升熱點數據的查詢效率。這種特性使得B樹在特定數據重複屢次查詢的場景中更加高效。
因爲B+樹的內部節點只存放鍵,不存放值,所以,一次讀取,能夠在內存頁中獲取更多的鍵,有利於更快地縮小查找範圍。 B+樹的葉節點由一條鏈相連,所以,當須要進行一次全數據遍歷的時候,B+樹只須要使用O(logN)時間找到最小的一個節點,而後經過鏈進行O(N)的順序遍歷便可。而B樹則須要對樹的每一層進行遍歷,這會須要更多的內存置換次數,所以也就須要花費更多的時間
事務是一個不可分割的數據庫操做序列,也是數據庫併發控制的基本單位,其執行的結果必須使數據庫從一種一致性狀態變到另外一種一致性狀態。
數據庫若是支持事務的操做,那麼就具有如下四個特性:
數據庫事務的隔離級別有4個,由低到高依次爲Read uncommitted、Read committed、Repeatable read、Serializable,這四個級別能夠逐個解決髒讀、不可重複讀、幻讀這幾類問題。
髒讀 | 不可重複讀 | 幻讀 | |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed--Sql Server , Oracle | × | √ | √ |
Repeatable read--MySQL | × | √ | |
Serializable | × | × | × |
公司發工資了,領導把5000元打到singo的帳號上,可是該事務並未提交,而singo正好去查看帳戶,發現工資已經到帳,是5000元整,很是高興。但是不幸的是,領導發現發給singo的工資金額不對,是2000元,因而迅速回滾了事務,修改金額後,將事務提交,最後singo實際的工資只有2000元,singo空歡喜一場。
出現上述狀況,即咱們所說的髒讀,兩個併發的事務,「事務A:領導給singo發工資」、「事務B:singo查詢工資帳戶」,事務B讀取了事務A還沒有提交的數據。
當隔離級別設置爲Read uncommitted時,就可能出現髒讀,如何避免髒讀,請看下一個隔離級別。
singo拿着工資卡去消費,系統讀取到卡里確實有2000元,而此時她的老婆也正好在網上轉帳,把singo工資卡的2000元轉到另外一帳戶,並在singo以前提交了事務,當singo扣款時,系統檢查到singo的工資卡已經沒有錢,扣款失敗,singo十分納悶,明明卡里有錢,爲什麼......
出現上述狀況,即咱們所說的不可重複讀,兩個併發的事務,「事務A:singo消費」、「事務B:singo的老婆網上轉帳」,事務A事先讀取了數據,事務B緊接了更新了數據,並提交了事務,而事務A再次讀取該數據時,數據已經發生了改變。
當隔離級別設置爲Read committed時,避免了髒讀,可是可能會形成不可重複讀。
大多數數據庫的默認級別就是Read committed,好比Sql Server , Oracle。如何解決不可重複讀這一問題,請看下一個隔離級別。
當隔離級別設置爲Repeatable read時,能夠避免不可重複讀。當singo拿着工資卡去消費時,一旦系統開始讀取工資卡信息(即事務開始),singo的老婆就不可能對該記錄進行修改,也就是singo的老婆不能在此時轉帳。
雖然Repeatable read避免了不可重複讀,但還有可能出現幻讀。
singo的老婆工做在銀行部門,她時常經過銀行內部系統查看singo的信用卡消費記錄。有一天,她正在查詢到singo當月信用卡的總消費金額(select sum(amount) from transaction where month = 本月)爲80元,而singo此時正好在外面胡吃海塞後在收銀臺買單,消費1000元,即新增了一條1000元的消費記錄(insert transaction ... ),並提交了事務,隨後singo的老婆將singo當月信用卡消費的明細打印到A4紙上,卻發現消費總額爲1080元,singo的老婆很詫異,覺得出現了幻覺,幻讀就這樣產生了。
注:MySQL的默認隔離級別就是Repeatable read。
Serializable是最高的事務隔離級別,同時代價也花費最高,性能很低,通常不多使用,在該級別下,事務順序執行,不只能夠避免髒讀、不可重複讀,還避免了幻像讀。
在該隔離級別,全部事務均可以看到其餘未提交事務的執行結果。本隔離級別不多用於實際應用,由於它的性能也不比其餘級別好多少。讀取未提交的數據,也被稱之爲髒讀(Dirty Read)。
這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它知足了隔離的簡單定義:一個事務只能看見已經提交事務所作的改變。這種隔離級別 也支持所謂的不可重複讀(Nonrepeatable Read),由於同一事務的其餘實例在該實例處理其間可能會有新的commit,因此同一select可能返回不一樣結果。
這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在併發讀取數據時,會看到一樣的數據行。不過理論上,這會致使另外一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一範圍的數據行時,另外一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的數據行時,會發現有新的「幻影」 行。InnoDB和Falcon存儲引擎經過多版本併發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
這是最高的隔離級別,它經過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每一個讀的數據行上加上共享鎖。在這個級別,可能致使大量的超時現象和鎖競爭。
在Read Uncommitted級別下,讀操做不加S鎖; 在Read Committed級別下,讀操做須要加S鎖,可是在語句執行完之後釋放S鎖; 在Repeatable Read級別下,讀操做須要加S鎖,可是在事務提交以前並不釋放S鎖,也就是必須等待事務執行完畢之後才釋放S鎖。 在Serialize級別下,會在Repeatable Read級別的基礎上,添加一個範圍鎖。保證一個事務內的兩次查詢結果徹底同樣,而不會出現第一次查詢結果是第二次查詢結果的子集。
存儲過程是一個預編譯的SQL語句,優勢是容許模塊化的設計,就是說只須要建立一次,之後在該程序中就能夠調用屢次。若是某次操做須要執行屢次SQL,使用存儲過程比單純SQL語句執行要快。
1)存儲過程是預編譯過的,執行效率高。 2)存儲過程的代碼直接存放於數據庫中,經過存儲過程名直接調用,減小網絡通信。 3)安全性搞,執行存儲過程須要有必定權限的用戶。 4)存儲過程能夠重複使用,減小數據庫開發人員的工做量。
1)調試麻煩,可是用 PL/SQL Developer 調試很方便!彌補這個缺點。 2)移植問題,數據庫端代碼固然是與數據庫相關的。可是若是是作工程型項目,基本不存在移植問題。 3)從新編譯問題,由於後端代碼是運行前編譯的,若是帶有引用關係的對象發生改變時,受影響的存儲過程、包將須要從新編譯(不過也能夠設置成運行時刻自動編譯)。 4)若是在一個程序系統中大量的使用存儲過程,到程序交付使用的時候隨着用戶需求的增長會致使數據結構的變化,接着就是系統的相關問題了,最後若是用戶想維護該系統能夠說是很難很難、並且代價是空前的,維護起來更麻煩。
視圖是從一個或幾個基本表(或視圖)導出的表。它與基本表不一樣,是一個虛表。數據庫中只存放視圖的定義,而不存放視圖對應的數據,這些數據仍存放在原來的基本表中。因此一旦基本表中的數據發生變化,從視圖中查詢出的數據也就隨之改變了。從這個意義上講,視圖就像一個窗口,透過它能夠看到數據庫中本身感興趣的數據及其變化。 視圖一經定義,就能夠和基本表同樣被查詢、被刪除。也能夠在一個視圖上再定義新的視圖,但對視圖的更新(增、刪、改)操做則有必定的限制。
遊標是系統爲用戶開設的一個數據緩衝區,存放SQL語句的執行結果,每一個遊標區都有一個名字。用戶能夠經過遊標逐一獲取記錄並賦給主變量,交由主語言進一步處理。
觸發器是用戶定義在關係表上的一類由事件驅動的特殊過程。一旦定義,觸發器將被保存在數據庫服務器中。任何用戶對錶的增、刪、改操做均由服務器自動激活相應的觸發器,在關係數據庫管理系統核心層進行集中的完整性控制。觸發器相似於約束,可是比約束更加靈活,能夠實施更爲複雜的檢查和操做,具備更精細和更強大的數據控制能力。
三者都表示刪除,可是三者有一些差異:
Delete | Truncate | Drop | |
---|---|---|---|
類型 | 屬於DML | 屬於DDL | 屬於DDL |
回滾 | 可回滾 | 不可回滾 | 不可回滾 |
刪除內容 | 表結構還在,刪除表的所有或者一部分數據行 | 表結構還在,刪除表中的全部數據 | 從數據庫中刪除表,全部的數據行,索引和權限也會被刪除 |
刪除速度 | 刪除速度慢,須要逐行刪除 | 刪除速度快 | 刪除速度快 |
所以,在再也不須要一張表的時候,用drop;在想刪除部分數據行時候,用delete;在保留表而刪除全部數據的時候用truncate。
將主數據庫中的DDL和DML操做經過二進制日誌(BINLOG)傳輸到從數據庫上,而後將這些日誌從新執行(重作);從而使得從數據庫的數據與主數據庫保持一致。
MySQL默認的存儲引擎是MyISAM,其餘經常使用的就是InnoDB了。
方式一: 修改配置文件my.ini 將mysql.ini另存爲my.ini,在[mysqld]後面添加default-storage-engine=InnoDB,重啓服務,數據庫默認的引擎修改成InnoDB 方式二:在建表的時候指定
create table mytbl(
id int primary key,
name varchar(50)
)type=MyISAM;
複製代碼
方式三:建表後更改
alter table table_name type = InnoDB;
複製代碼
MyISAM | InnoDB | |
---|---|---|
存儲結構 | 每張表被存放在三個文件:frm-表格定義、MYD(MYData)-數據文件、MYI(MYIndex)-索引文件 | 全部的表都保存在同一個數據文件中(也多是多個文件,或者是獨立的表空間文件),InnoDB表的大小隻受限於操做系統文件的大小,通常爲2GB |
存儲空間 | MyISAM可被壓縮,存儲空間較小 | InnoDB的表須要更多的內存和存儲,它會在主內存中創建其專用的緩衝池用於高速緩衝數據和索引 |
可移植性、備份及恢復 | 因爲MyISAM的數據是以文件的形式存儲,因此在跨平臺的數據轉移中會很方便。在備份和恢復時可單獨針對某個表進行操做 | 免費的方案能夠是拷貝數據文件、備份 binlog,或者用 mysqldump,在數據量達到幾十G的時候就相對痛苦了 |
事務安全 | 不支持 每次查詢具備原子性 | 支持 具備事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表 |
AUTO_INCREMENT | MyISAM表能夠和其餘字段一塊兒創建聯合索引 | InnoDB中必須包含只有該字段的索引 |
SELECT | MyISAM更優 | |
INSERT | InnoDB更優 | |
UPDATE | InnoDB更優 | |
DELETE | InnoDB更優 它不會從新創建表,而是一行一行的刪除 | |
COUNT without WHERE | MyISAM更優。由於MyISAM保存了表的具體行數 | InnoDB沒有保存表的具體行數,須要逐行掃描統計,就很慢了 |
COUNT with WHERE | 同樣 | 同樣,InnoDB也會鎖表 |
鎖 | 只支持表鎖 | 支持表鎖、行鎖 行鎖大幅度提升了多用戶併發操做的新能。可是InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的 |
外鍵 | 不支持 | 支持 |
FULLTEXT全文索引 | 支持 | 不支持 能夠經過使用Sphinx從InnoDB中得到全文索引,會慢一點 |
總的來講,MyISAM和InnoDB各有優劣,各有各的使用環境。
可是InnoDB的設計目標是處理大容量數據庫系統,它的CPU利用率是其它基於磁盤的關係數據庫引擎所不能比的。
我以爲使用InnoDB能夠應對更爲複雜的狀況,特別是對併發的處理要比MyISAM高效。同時結合memcache也能夠緩存SELECT來減小SELECT查詢,從而提升總體性能。
LIMIT 子句能夠被用於強制 SELECT 語句返回指定的記錄數。LIMIT 接受一個或兩個數字參數。參數必須是一個整數常量。若是給定兩個參數,第一個參數指定第一個返回記錄行的偏移量,第二個參數指定返回記錄行的最大數目。初始記錄行的偏移量是 0(而不是 1)
mysql> SELECT * FROM table LIMIT 5,10; // 檢索記錄行 6-15
複製代碼
爲了檢索從某一個偏移量到記錄集的結束全部的記錄行,能夠指定第二個參數爲 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 檢索記錄行 96-last.
複製代碼
若是隻給定一個參數,它表示返回最大的記錄行數目:
mysql> SELECT * FROM table LIMIT 5; //檢索前 5 個記錄行
複製代碼
換句話說,LIMIT n 等價於 LIMIT 0,n。
查詢從第1000000以後的30條記錄:
SQL代碼1:平均用時6.6秒 SELECT * FROM `cdb_posts` ORDER BY pid LIMIT 1000000 , 30
SQL代碼2:平均用時0.6秒 SELECT * FROM `cdb_posts` WHERE pid >= (SELECT pid FROM
`cdb_posts` ORDER BY pid LIMIT 1000000 , 1) LIMIT 30
複製代碼
由於要取出全部字段內容,第一種須要跨越大量數據塊並取出,而第二種基本經過直接根據索引字段定位後,才取出相應內容,效率天然大大提高。對limit的優化,不是直接使用limit,而是首先獲取到offset的id,而後直接使用limit size來獲取數據。
獲取最新資訊,請關注微信公衆號:南強說晚安
秋招求職徵文正在火熱進行中👉秋招求職時,寫文就有好禮相送 | 掘金技術徵文 - 掘金