做爲數據庫知識點,無論是什麼語言確定都會問到,當問到MySql必定要硬起來,給你們準備了50道MySql相關的面試題,先搞明白這些,後面的我繼續準備。只要你關注我,我就會持續更新。mysql
數據庫是「按照數據結構來組織、存儲和管理數據的倉庫」。是一個長期存儲在計算機內的、有組織的、可共享的、統一管理的大量數據的集合。面試
好比看建表的語法:sql
mysql> ? create table
Name: 'CREATE TABLE'
Description:
Syntax:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
(create_definition,…)
[table_options]
[partition_options]
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,…)]
[table_options]
[partition_options]
[IGNORE | REPLACE]
[AS] query_expression
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
複製代碼
MyISAM、 InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、 ARCHIVE、CSV、BLACKHOLE、FEDERATED。shell
Tips:InnoDB和BDB提供事務安全表,其餘存儲引擎都是非事務安全表。數據庫
1.Myisam是Mysql的默認存儲引擎,當create建立新表時,未指定新表的存儲引擎時,默認使用Myisam。express
每一個MyISAM 在磁盤上存儲成三個文件。文件名都和表名相同,擴展名分別是 .frm (存儲表定義) 、.MYD (MYData,存儲數據)、.MYI (MYIndex,存儲索引)。緩存
數據文件和索引文件能夠放置在不一樣的目錄,平均分佈io,得到更快的速度。安全
2.InnoDB 存儲引擎提供了具備提交、回滾和崩潰恢復能力的事務安全。可是對比 Myisam 的存儲引擎,InnoDB 寫的處理效率差一些而且會佔用更多的磁盤空間以保留數據和索引。bash
能夠, ENGINE=xxx 設置引擎。服務器
代碼示例:
create table person(
id int primary key auto_increment,
username varchar(32)
) ENGINE=InnoDB
複製代碼
選擇標準: 根據應用特色選擇合適的存儲引擎,對於複雜的應用系統能夠根據實際狀況選擇 多種存儲引擎進行組合. 下面是經常使用存儲引擎的適用環境:
MyISAM: 默認的 MySQL 插件式存儲引擎, 它是在 Web、 數據倉儲和其餘應用環境下最常使用的存儲引擎之一。
InnoDB:用於事務處理應用程序,具備衆多特性,包括 ACID 事務支持。
Memory: 將 全部數據保存在RAM 中, 在 須要快速查找引用和其餘相似數據的環境下,可 提供極快的訪問。
Merge:容許 MySQL DBA 或開發人員將一系列等同的 MyISAM 表以邏輯方式組合在一塊兒,並做爲 1 個對象引用它們。對於諸如數據倉儲等 VLDB 環境十分適合。
前提: 使用適合存儲引擎。
選擇原則: 根據選定的存儲引擎,肯定如何選擇合適的數據類型下面的選擇方法按存儲引擎分類 :
MyISAM 數據存儲引擎和數據列
MyISAM數據表,最好使用固定長度的數據列代替可變長度的數據列。
MEMORY存儲引擎和數據列
MEMORY數據表目前都使用固定長度的數據行存儲,所以不管使用CHAR或VARCHAR列都沒有關係。二者都是做爲CHAR類型處理的。
InnoDB 存儲引擎和數據列
建議使用 VARCHAR類型
對於InnoDB數據表,內部的行存儲格式沒有區分固定長度和可變長度列(全部數據行 都使用指向數據列值的頭指針) ,所以在本質上,使用固定長度的CHAR列不必定比使 用可變長度VARCHAR列簡單。 於是, 主要的性能因素是數據行使用的存儲總量。 因爲 CHAR 平均佔用的空間多於VARCHAR,所以使用VARCHAR來最小化須要處理的數據行的存儲總 量和磁盤I/O是比較好的。
保存和檢索的方式不一樣。它們的最大長度和是否尾部空格被保留等方面也不一樣。在存儲或檢索過程當中不進行大小寫轉換。
mysql服務器能夠支持多種字符集 (能夠用show character set命令查看全部mysql支持 的字符集) ,在同一臺服務器、同一個數據庫、甚至同一個表的不一樣字段均可以指定使用不 同的字符集。
mysql的字符集包括字符集(CHARACTER)和校對規則(COLLATION)兩個概念。
建議在可以徹底知足應用的前提下,儘可能使用小的字符集。由於更小的字符集意味着可以節省空間、 減小網絡傳輸字節數,同時因爲存儲空間的較小間接的提升了系統的性能。
有不少字符集能夠保存漢字,好比 utf八、gb23十二、gbk、latin1 等等,可是經常使用的是 gb2312 和 gbk。由於 gb2312 字庫比 gbk 字庫小,有些偏僻字(例如:洺)不能保存,所以 在選擇字符集的時候必定要權衡這些偏僻字在應用出現的概率以及形成的影響, 不能作出肯 定答覆的話最好選用 gbk。
在關係數據庫中,索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的一種存儲結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單。索引的做用至關於圖書的目錄,能夠根據目錄中的頁碼快速找到所需的內容。
搜索的索引列,不 必定是所要選擇的列。最適合索引的列是出如今WHERE子句中的列,或鏈接子句中指定的列,而不是出如今SELECT 關鍵字後的選擇列表中的列。
使用唯一索引。考慮某列中值的分佈。 對於唯一值的列,索引的效果最好,而具備多個 重複值的列,其索引效果最差。
使用短索引。若是對串列進行索引,應該指定一個前綴長度,只要有可能就應該這作樣。 例如,若是有一個 CHAR(200) 列,若是在前 10 個或 20 個字符內,多數值是唯一的, 那麼就不要對整個列進行索引。
利用最左前綴。在建立 一個 n 列的索引時,實際是建立了 MySQL 可利用的 n 個索引。 多列索引可起幾個索引的做用,由於可利用索引中最左邊的列集來匹配行。 這樣的列集 稱爲最左前綴。 (這與索引一個列的前綴不一樣,索引一個列的前綴是利用該的n前個字 符做爲索引值 )
不要過分索引。每一個額外的索引都要佔用額外的磁盤空間,並下降寫操做的性能,這一點咱們前面已經介紹 過。在修改表的內容時,索引必須進行更新,有時可能須要重構, 所以, 索引越多,所花的時間越長。
若是有一個索引不多利用或從不使用,那麼會沒必要要地減緩表的修改速度。 此外,MySQL 在生成一個執行計劃時,要考慮各個索引,這也要費時間。
建立多餘的索引給查詢優化帶來了更多的工做。索引太多,也可能會使 MySQL選擇不到所要使用的 最好索引。 只保持所需的索引有利於查詢優化。 若是想給已索引的表增長索引, 應 該考慮所要增長的索引是不是現有多列索引的最左索引。
考慮在列上進行的比較類型。 索引可用於「 <」、「 < = 」、「 = 」、「 > =」、「 > 」和 BETWEEN 運算。在模式具備一個直接量前綴時,索引也用於 LIKE 運算。若是隻將某個列用於其餘類型的運算時(如 STRCMP( )) ,對其進行索引沒有價值。
一、彙集索引(clustered index)
二、非彙集索引(non-clustered index)
hash索引底層就是hash表,進行查詢時,調用一次hash函數就能夠獲取到相應的鍵值,以後進行回表查詢得到實際數據.
B+樹底層實現原理是多路平衡查找樹,對於每一次的查詢都是從根節點出發,查詢到葉子節點方能夠得到所查鍵值,而後查詢判斷是否須要回表查詢.
區別:
hash索引
1:hash索引進行等值查詢更快(通常狀況下)可是卻沒法進行範圍查詢.由於在hash索引中通過hash函數創建索引以後,索引的順序與原順序沒法保持一致,不能支持範圍查詢.
2:hash索引不支持模糊查詢以及多列索引的最左前綴匹配,由於hash函數的不可預測,eg:AAAA和AAAAB的索引沒有相關性.
3:hash索引任什麼時候候都避免不了回表查詢數據.
4:hash索引雖然在等值上查詢叫快,可是不穩定,性能不可預測,當某個鍵值存在大量重複的時候,發生hash碰撞,此時查詢效率可能極差.
5:hash索引不支持使用索引進行排序,由於hash函數的不可預測.
B+樹
1:B+樹的全部節點皆遵循(左節點小於父節點,右節點大於父節點,多叉樹也相似)天然支持範圍查詢.
2:在符合某些條件(聚簇索引,覆蓋索引等)的時候能夠只經過索引完成查詢.不須要回表查詢.
3:查詢效率比較穩定,對於查詢都是從根節點到葉子節點,且樹的高度較低.
結論
大多數狀況下,直接選擇B+樹索引能夠得到穩定且較好的查詢速度,而不須要使用Hash索引. 連接:blog.csdn.net/qq_44590469…
不必定,這涉及到查詢語句所要求的字段是否所有命中了索引,若是所有命中了索引,那麼就沒必要再進行回表查詢.
舉個簡單的例子,假設咱們在員工表的年齡上創建了索引,那麼當進行select age from employee where age < 20
的查詢時,在索引的葉子節點上,已經包含了age信息,不會再次進行回表查詢.
select * from table_name order by id desc limit 1;
複製代碼
緣由:用戶傳入的參數中注入符合sql的語法,從而破壞原有sql結構語意,達到攻擊效果。
NULL值是沒有值,,它不是空串。若是指定''(兩個單引號,其間沒有字符),這在NOT NULL列中是容許的。空串是一個有效的值,它不是無值。
判斷NULL須要用 IS NULL 或者 IS NOT NULL。
能夠用來維護數據庫的完整性,它保證成批的MySQL操做要麼徹底執行,要麼徹底不執行。
事務是必須知足4個條件(ACID):
可重複讀(REPEATABLE-READ)
查看:
mysql> select @@global.tx_isolation;
+———————————+
| @@global.tx_isolation |
+———————————+
| REPEATABLE-READ |
+———————————+
1 row in set, 1 warning (0.01 sec)
複製代碼
數據庫的鎖是爲了支持對共享資源進行併發訪問,提供數據的完整性和一致性,這樣才能保證在高併發的狀況下,訪問數據庫的時候,數據不會出現問題。
是指兩個或兩個以上進程執行過程當中,因競爭共享資源形成的相互等待現象。
設置超時時間。超時後自動釋放。
發起死鎖檢測,主動回滾其中一條事務,讓其餘事務繼續執行。
建立用戶:
CREATE USER 'username'@'host' IDENTIFIED BY 'password';
複製代碼
受權:
GRANT privileges ON databasename.tablename TO 'username'@'host';
複製代碼
desc table_name;
mysql> desc zipkin_spans;
+———————+———————+———+——+————+———+
| Field | Type | Null | Key | Default | Extra |
+———————+———————+———+——+————+———+
| trace_id_high | bigint(20) | NO | PRI | 0 | |
| trace_id | bigint(20) | NO | PRI | NULL | |
| id | bigint(20) | NO | PRI | NULL | |
| name | varchar(255) | NO | MUL | NULL | |
| parent_id | bigint(20) | YES | | NULL | |
| debug | bit(1) | YES | | NULL | |
| start_ts | bigint(20) | YES | MUL | NULL | |
| duration | bigint(20) | YES | | NULL | |
+———————+———————+———+——+————+———+
8 rows in set (0.01 sec)
複製代碼
1.delete : 僅刪除表數據,支持條件過濾,支持回滾。記錄日誌。所以比較慢。
delete from table_name;
複製代碼
2.truncate: 僅刪除全部數據,不支持條件過濾,不支持回滾。不記錄日誌,效率高於delete。
truncate table table_name;
複製代碼
3.drop:刪除表數據同時刪除表結構。將表所佔的空間都釋放掉。刪除效率最高。
drop table table_name;
複製代碼
Xxx% 走索引, %xxx不走索引。
在普通索引查到主鍵索引後,再去主鍵索引定位記錄。等於說非主鍵索引須要多走一個索引樹。
索引覆蓋被查詢的字段。
若是一個索引包含(或覆蓋)全部須要查詢的字段的值,稱爲‘覆蓋索引’。
優勢
簡單化,數據所見即所得
安全性,用戶只能查詢或修改他們所能見到獲得的數據
邏輯獨立性,能夠屏蔽真實表結構變化帶來的影響
缺點
性能相對較差,簡單的查詢也會變得稍顯複雜
修改不方便,特變是複雜的聚合視圖基本沒法修改
本質區別,主鍵是一種約束,惟一索引是一種索引。
主鍵不能有空值(非空+惟一),惟一索引能夠爲空。
主鍵能夠是其餘表的外鍵,惟一索引不能夠。
一個表只能有一個主鍵,惟一索引 能夠多個。
均可以創建聯合主鍵或聯合惟一索引。
主鍵-》聚簇索引,惟一索引->非聚簇索引。
SELECT * FROM table_name ORDER BY rand() LIMIT 1;
複製代碼
show index from table_name;
複製代碼
MVCC 全稱是多版本併發控制系統,InnoDB 的 MVCC 是經過在每行記錄後面保存兩個隱藏的列來實現,這兩個列一個保存了行的建立時間,一個保存行的過時時間(刪除時間)。固然存儲的並非真實的時間而是系統版本號(system version number)。每開始一個新的事務,系統版本號都會自動新增,事務開始時刻的系統版本號會做爲事務的版本號,用來查詢到每行記錄的版本號進行比較。
客戶端鏈接數據庫,驗證身份。
獲取當前用戶權限。
當你查詢時,會先去緩存看看,若是有返回。
若是沒有,分析器對sql作詞法分析。
優化器對sql進行「它認爲比較好的優化」。
執行器負責具體執行sql語句。
最後把數據返回給客戶端。
explain sql;
1、 id
SQL查詢中的序列號。
id列數字越大越先執行,若是說數字同樣大,那麼就從上往下依次執行。
2、select_type
3、table
顯示這一行的數據是關於哪張表的。不必定是實際存在的表名。 能夠爲以下的值:
4、type
這是最重要的字段之一,顯示查詢使用了何種類型。從最好到最差的鏈接類型依次爲:
system,const,eq_ref,ref,fulltext,ref_or_null,index_merge,unique_subquery,index_subquery,range,index,ALL
一、system
表中只有一行數據或者是空表,這是const類型的一個特例。且只能用於myisam和memory表。若是是Innodb引擎表,type列在這個狀況一般都是all或者index
二、const
最多隻有一行記錄匹配。當聯合主鍵或惟一索引的全部字段跟常量值比較時,join類型爲const。其餘數據庫也叫作惟一索引掃描
三、eq_ref
多表join時,對於來自前面表的每一行,在當前表中只能找到一行。這多是除了system和const以外最好的類型。當主鍵或惟一非NULL索引的全部字段都被用做join聯接時會使用此類型。
eq_ref可用於使用'='操做符做比較的索引列。比較的值能夠是常量,也能夠是使用在此表以前讀取的表的列的表達式。
相對於下面的ref區別就是它使用的惟一索引,即主鍵或惟一索引,而ref使用的是非惟一索引或者普通索引。 eq_ref只能找到一行,而ref能找到多行。
四、ref
對於來自前面表的每一行,在此表的索引中能夠匹配到多行。若聯接只用到索引的最左前綴或索引不是主鍵或惟一索引時,使用ref類型(也就是說,此聯接可以匹配多行記錄)。
ref可用於使用'='或'<=>'操做符做比較的索引列。
五、 fulltext
使用全文索引的時候是這個類型。要注意,全文索引的優先級很高,若全文索引和普通索引同時存在時,mysql無論代價,優先選擇使用全文索引
六、ref_or_null
跟ref類型相似,只是增長了null值的比較。實際用的很少。
七、index_merge
表示查詢使用了兩個以上的索引,最後取交集或者並集,常見and ,or的條件使用了不一樣的索引,官方排序這個在ref_or_null以後,可是實際上因爲要讀取多個索引,性能可能大部分時間都不如range
八、unique_subquery
用於where中的in形式子查詢,子查詢返回不重複值惟一值,能夠徹底替換子查詢,效率更高。 該類型替換了下面形式的IN子查詢的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr)
九、index_subquery
該聯接類型相似於unique_subquery。適用於非惟一索引,能夠返回重複值。
十、range
索引範圍查詢,常見於使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN()或者like等運算符的查詢中。
十一、index
索引全表掃描,把索引從頭至尾掃一遍。這裏包含兩種狀況: 一種是查詢使用了覆蓋索引,那麼它只須要掃描索引就能夠得到數據,這個效率要比全表掃描要快,由於索引一般比數據表小,並且還能避免二次查詢。在extra中顯示Using index,反之,若是在索引上進行全表掃描,沒有Using index的提示。
十二、all
全表掃描,性能最差。
5、possible_keys
查詢可能使用到的索引都會在這裏列出來。
6、Key
key列顯示MySQL實際使用的鍵(索引)
要想強制MySQL使用或忽視possible_keys列中的索引,可使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
select_type爲index_merge時,這裏可能出現兩個以上的索引,其餘的select_type這裏只會出現一個。
7、key_len
表示索引中使用的字節數。
key_len只計算where條件用到的索引長度,而排序和分組就算用到了索引,也不會計算到key_len中。
不損失精確性的狀況下,長度越短越好 。
8、ref
表示上述表的鏈接匹配條件,即哪些列或常量被用於查找索引列上的值。
9、rows
rows 也是一個重要的字段。 這是mysql估算的須要掃描的行數(不是精確值)。
10、Extra
該列包含MySQL解決查詢的詳細信息,有如下幾種狀況:
連接:www.jianshu.com/p/8fab76bbf…
16
主鍵是數據庫確保數據行在整張表惟一性的保障,即便業務上本張表沒有主鍵,也建議添加一個自增加的ID列做爲主鍵.設定了主鍵以後,在後續的刪改查的時候可能更加快速以及確保操做數據範圍安全.
MySQL官網這樣介紹:
NULL columns require additional space in the rowto record whether their values are NULL. For MyISAM tables, each NULL columntakes one bit extra, rounded up to the nearest byte.
null值會佔用更多的字節,且會在程序中形成不少與預期不符的狀況.
varchar的10表明了申請的空間長度,也是能夠存儲的數據的最大長度,而int的10只是表明了展現的長度,不足10位以0填充.也就是說,int(1)和int(10)所能存儲的數字大小以及佔用的空間都是相同的,只是在展現時按照長度展現。
視圖(View)是一種虛擬存在的表,對於使用視圖的用戶來講基本上是透明的。視圖並 不在數據庫中實際存在,行和列數據來自定義視圖的查詢中使用的表,而且是在使用視圖時 動態生成的。
視圖相對於普通的表的優點主要包括如下幾項。
簡單:使用視圖的用戶徹底不須要關心後面對應的表的結構、關聯條件和篩選條件,
對用戶來講已是過濾好的複合條件的結果集。
安全:使用視圖的用戶只能訪問他們被容許查詢的結果集,對錶的權限管理並不能
限制到某個行某個列,可是經過視圖就能夠簡單的實現。
數據獨立:一旦視圖的結構肯定了,能夠屏蔽表結構變化對用戶的影響,源表增長
列對視圖沒有影響;源表修改列名,則能夠經過修改視圖來解決,不會形成對訪問 者的影響。
MyISAM :把一個表的總行數存在了磁盤上,執行 count(*) 的時候會直接返回這個數,效率很高。
InnoDB : 比較麻煩,它執行 count(*) 的時候,須要把數據一行一行地從引擎裏面讀出來,而後累積計數。
參考:
新人博主求三連,同時關注個人公衆號【Java小咖秀】回覆面試便可白嫖一份《Java全級別工程獅面試題.pdf》 持續更新,堅持✊✊✊