此錯誤是執行到分析器階段報出的,由於 MySQL 會在分析器階段檢查 SQL 語句的正確性。面試
MySQL 查詢緩存功能是在鏈接器以後發生的,它的優勢是效率高,若是已經有緩存則會直接返回結果。 查詢緩存的缺點是失效太頻繁致使緩存命中率比較低,任何更新表操做都會清空查詢緩存,所以致使查詢緩存很是容易失效。正則表達式
MySQL 查詢緩存默認是開啓的,配置 querycachetype 參數爲 DEMAND(按需使用)關閉查詢緩存,MySQL 8.0 以後直接刪除了查詢緩存的功能。redis
MySQL 的經常使用引擎有 InnoDB、MyISAM、Memory 等,從 MySQL 5.5.5 版本開始 InnoDB 就成爲了默認的存儲引擎。sql
能夠針對不一樣的表設置不一樣的引擎。在 create table 語句中使用 engine=引擎名(好比Memory)來設置此表的存儲引擎。完整代碼以下:數據庫
create table student( id int primary key auto_increment, username varchar(120), age int ) ENGINE=Memory
InnoDB 和 MyISAM 最大的區別是 InnoDB 支持事務,而 MyISAM 不支持事務,它們主要區別以下:緩存
1)插入緩衝(insert buffer):對於非彙集索引的插入和更新,不是每一次直接插入索引頁中,而是首先判斷插入的非彙集索引頁是否在緩衝池中,若是在,則直接插入,不然,先放入一個插入緩衝區中。好似欺騙數據庫這個非彙集的索引已經插入到葉子節點了,而後再以必定的頻率執行插入緩衝和非彙集索引頁子節點的合併操做,這時一般能將多個插入合併到一個操做中,這就大大提升了對非彙集索引執行插入和修改操做的性能。安全
2)兩次寫(double write):兩次寫給 InnoDB 帶來的是可靠性,主要用來解決部分寫失敗(partial page write)。doublewrite 有兩部分組成,一部分是內存中的 doublewrite buffer ,大小爲 2M,另一部分就是物理磁盤上的共享表空間中連續的 128 個頁,即兩個區,大小一樣爲 2M。當緩衝池的做業刷新時,並不直接寫硬盤,而是經過 memcpy 函數將髒頁先拷貝到內存中的 doublewrite buffer,以後經過 doublewrite buffer 再分兩次寫,每次寫入 1M 到共享表空間的物理磁盤上,而後立刻調用 fsync 函數,同步磁盤。以下圖所示服務器
3)自適應哈希索引(adaptive hash index):因爲 InnoDB 不支持 hash 索引,但在某些狀況下 hash 索引的效率很高,因而出現了 adaptive hash index 功能, InnoDB 存儲引擎會監控對錶上索引的查找,若是觀察到創建 hash 索引能夠提升性能的時候,則自動創建 hash 索引。併發
若是這張表的引擎是 MyISAM,那麼 ID=4,若是是 InnoDB 那麼 ID=2(MySQL 8 以前的版本)。函數
如下狀況會致使 MySQL 自增主鍵不能連續:
自增主鍵能不能被持久化,說的是 MySQL 重啓以後 InnoDB 能不能恢復重啓以前的自增列,InnoDB 在 8.0 以前是沒有持久化能力的,但 MySQL 8.0 以後就把自增主鍵保存到 redo log(一種日誌類型,下文會詳細講)中,當 MySQL 重啓以後就會從 redo log 日誌中恢復。
共享表空間:指的是數據庫的全部的表數據,索引文件所有放在一個文件中,默認這個共享表空間的文件路徑在 data 目錄下。 獨立表空間:每個表都將會生成以獨立的文件方式來進行存儲。 共享表空間和獨立表空間最大的區別是若是把表放再共享表空間,即便表刪除了空間也不會刪除,因此表依然很大,而獨立表空間若是刪除表就會清除空間。
獨立表空間是由參數 innodbfileper_table 控制的,把它設置成 ON 就是獨立表空間了,從 MySQL 5.6.6 版本以後,這個值就默認是 ON 了。
使用重建表的方式能夠收縮表空間,重建表有如下三種方式:
表結構定義佔有的存儲空間比較小,在 MySQL 8 以前,表結構的定義信息存在以 .frm 爲後綴的文件裏,在 MySQL 8 以後,則容許把表結構的定義信息存在系統數據表之中。
覆蓋索引是指,索引上的信息足夠知足查詢請求,不須要再回到主鍵上去取數據。
能夠回表查詢,若是把主鍵刪掉了,那麼 InnoDB 會本身生成一個長度爲 6 字節的 rowid 做爲主鍵。
多是由於 update 語句執行完成後,InnoDB 只保證寫完了 redo log、內存,可能還沒來得及將數據寫到磁盤。
髒讀是一個事務在處理過程當中讀取了另一個事務未提交的數據;幻讀是指同一個事務內屢次查詢返回的結果集不同(好比增長了或者減小了行記錄)。
由於行鎖只能鎖定存在的行,針對新插入的操做沒有限定,因此就有可能產生幻讀。 幻讀帶來的問題以下:
使用間隙鎖的方式來避免出現幻讀。間隙鎖,是專門用於解決幻讀這種問題的鎖,它鎖的了行與行之間的間隙,可以阻塞新插入的操做 間隙鎖的引入也帶來了一些新的問題,好比:下降併發度,可能致使死鎖。
在 MySQL 的命令行中使用 show processlist;
查看全部鏈接,其中 Command 列顯示爲 Sleep 的表示空閒鏈接,以下圖所示:
MySQL 的字符串類型和取值以下:
類型 | 取值範圍 |
---|---|
CHAR(N) | 0~255 |
VARCHAR(N) | 0~65536 |
TINYBLOB | 0~255 |
BLOB | 0~65535 |
MEDUIMBLOB | 0~167772150 |
LONGBLOB | 0~4294967295 |
TINYTEXT | 0~255 |
TEXT | 0~65535 |
MEDIUMTEXT | 0~167772150 |
LONGTEXT | 0~4294967295 |
VARBINARY(N) | 0~N個字節的變長字節字符集 |
BINARY(N) | 0~N個字節的定長字節字符集 |
VARCHAR 和 CHAR 最大區別就是,VARCHAR 的長度是可變的,而 CHAR 是固定長度,CHAR 的取值範圍爲1-255,所以 VARCHAR 可能會形成存儲碎片。因爲它們的特性決定了 CHAR 比較適合長度較短的字段和固定長度的字段,如身份證號、手機號等,反之則適合使用 VARCHAR。
MySQL 存儲金額應該使用 decimal
,由於若是存儲其餘數據類型,好比float
有致使小數點後數據丟失的風險。
去除前三條數據以後查詢兩條信息。
now() 返回當前時間包含日期和時分秒,current_date() 只返回當前時間,以下圖所示:
使用 distinct 去重,使用 count 統計總條數,具體實現腳本以下:
select count(distinct f) from t
lastinsertid() 用於查詢最後一次自增表的編號,它的特色是查詢時不須要不須要指定表名,使用 select last_insert_id()
便可查詢,由於不須要指定表名因此它始終以最後一條自增編號爲主,能夠被其它表的自增編號覆蓋。好比 A 表的最大編號是 10,lastinsertid() 查詢出來的值爲 10,這時 B 表插入了一條數據,它的最大編號爲 3,這個時候使用 lastinsertid() 查詢的值就是 3。
刪除數據有兩種方式:delete 和 truncate,它們的區別以下:
delete 和 truncate 的使用腳本以下:
delete from t where username='redis'; truncate table t;
MySQL 中支持兩種模糊查詢:regexp 和 like,like 是對任意多字符匹配或任意單字符進行模糊匹配,而 regexp 則支持正則表達式的匹配方式,提供比 like 更多的匹配方式。 regexp 和 like 的使用示例以下: select * from person where uname like '%SQL%';> select from person where uname regexp '.SQL*.';
MySQL 支持枚舉,它的實現方式以下:
create table t( sex enum('boy','grid') default 'unknown' );
枚舉的做用是預約義結果值,當插入數據不在枚舉值範圍內,則插入失敗,提示錯誤 Data truncated for column 'xxx' at row n
。
count(column) 和 count() 最大區別是統計結果可能不一致,count(column) 統計不會統計列值爲 null 的數據,而 count() 則會統計全部信息,因此最終的統計結果可能會不一樣。
A. count 的查詢性能在各類存儲引擎下的性能都是同樣的。 B. count 在 MyISAM 比 InnoDB 的性能要低。 C. count 在 InnoDB 中是一行一行讀取,而後累計計數的。 D. count 在 InnoDB 中存儲了總條數,查詢的時候直接取出。
答:C
由於 InnoDB 使用了事務實現,而事務的設計使用了多版本併發控制,即便是在同一時間進行查詢,獲得的結果也可能不相同,因此 InnoDB 不能把結果直接保存下來,由於這樣是不許確的。
不能,由於 show table status 是經過採樣統計估算出來的,官方文檔說偏差可能在 40% 左右,因此 show table status 中的錶行數不能直接使用。
A. select count(*) from t where time>1000 and time<4500 B. show table status where name='t' C. select count(id) from t where time>1000 and time<4500 D. select count(name) from t where time>1000 and time<4500
答:B 題目解析:由於 show table status 的錶行數是估算出來,而其餘的查詢由於添加了 where 條件,即便是 MyISAM 引擎也不能直接使用已經存儲的總條數,因此 show table status 的查詢性能最高。
MyISAM 效率最高,由於 MyISAM 內部維護了一個計數器,直接返回總條數,而 InnoDB 要逐行統計。
MySQL 有對 count() 進行優化,以 InnoDB 爲例,在 InnoDB 中主鍵索引數的葉子節點是主鍵值,而普通索引的葉子節點則是主鍵值,因此普通索引數比主鍵索引數要小不少,而對於 count 查詢來講,每一個索引樹的查詢結果都是同樣的,因此 MySQL 會選擇最小的那顆樹來遍歷,以此來優化 count() 的查詢。
count(字段)<count(主鍵 id)<count(1)≈count(*) 題目解析:
因此最後得出的結果是:count(字段)<count(主鍵 id)<count(1)≈count(*)。
視圖是一種虛擬的表,具備和物理表相同的功能,能夠對視圖進行增、改、查操做。視圖一般是一個表或者多個表的行或列的子集。 視圖建立腳本以下:
create view vname as select column_names from table_name where condition
MySQL 中的「視圖」概念有兩個,它們分別是:
能夠用 Flashback 工具經過閃回把數據恢復回來。
Flashback 恢復數據的原理是是修改 binlog 的內容,拿回原庫重放,從而實現數據找回。