-
char、varchar 的區別是什么?
- varchar是變長而char的長度是固定的。如果創建的列是固定大小的,你會得到更好的性能
-
truncate 和 delete 的區別是什么?
- delete 命令從一個表中刪除某一行,或多行,可以使用用where,truncate 命令清空表里的所有數據,再插入數據時自增 id 從 1 開始
-
什么是觸發器,MySQL 中都有哪些觸發器?
- 觸發器是指一段代碼,當觸發某個事件,自動執行這些代碼(維護數據庫的一致性的完整性)。MySQL中的觸發器有如下六種:
- Before Insert
- After Insert
- Before Update
- After Update
- Before Delete
- After Delete
-
float 和 double 的區別是什么?
- float 類型數據可以存儲之多8位十進制數,並在內存中占4字節
- double類型數據可以存儲至多18位十進制數,並在內存中占8字節
-
如何在 MySQL 中獲取當前日期?
- select curdate();
- select current_date();
- select date_format(now(), '%y%m%d');
-
如何查詢第 n 高的工資?
- select distinct(salary) from employee order by salary desc limit n-1, 1;
-
請寫出下面 MySQL 數據類型表達的意義(int(0), char(16), varchar(16), datetime, text)
-
數據類型考點:
- 整數類型:包括 tinyint、smallint、mediumint、int、bigint、分別表示1字節、2字節、3字節、4字節、8字節整數。任何整數類型都可以加上unsigned,表示數據是無符號的,即非負整數。
- 長度:整數類型可以被指定長度,例如:int(11)表示長度為11的int類型。長度在大多數場景是沒有意義的,它不會限制值的合法范圍,指揮影響顯示字符的個數,而且需要和unsigned和zerofill屬性配合使用才有意義。
- 例子:假設數據類型為int(5),屬性為unsigned zerofill,如果用戶插入的數據為12的話,那么數據庫實際存儲數據為00012.
- 實數類型:包括float、double、decimal。
- decimal可以用於存儲比bigint還大的整數,能存儲精確的小數。
- 而float和double是由取值范圍的,並支持使用標准的浮點進行近似計算。
- 計算時float和double相比decimal效率更高一些,decimal可以理解為用字符串進行處理(保證數據不會失真)
- 字符串類型:包括varchar、char、text、blob
- varchar 用於存儲可變長字符串,比定長類型更節省空間
- varchar 使用額外1個或2個字節存儲字符串長度。列長度小於255字節時,使用1字節表示,負責小於2字節表示
- varchar 存儲的內容超出設置的長度時,內容會被截斷
- char 是定長的,根據定義的字符串長度分配足夠的空間
- char 會根據需要使用空格進行填充方便比較
- char 適合存儲很短的字符串,或者所有值都接近同一個長度
- char 存儲的內容超出設置的長度時,內容同樣會被截斷
- 字符串使用策略:
- 對於經常變更的數據來說,char比varchar更好,因為char不容易產生碎片
- 對於非常短的列,char比varchar在存儲空間上更有效率
- 使用時要注意只分配需要的空間,更長的列排序時會消耗更多內存
- 盡量避免使用text/blob類型,查詢時會使用臨時表,導致嚴重的性能開銷
- 枚舉類型(ENUM):把不重復的數據存儲為一個預定義的集合
- 有時可以使用enum代替常用的字符串類型
- enum存儲非常緊湊,會把列表值壓縮到一個或兩個字節
- enum在內部存儲時,其實存的是整數
- 盡量避免使用數字作為enum枚舉的常量,因為容易混亂
- 排序是按照內部存儲的數據
- 日期和時間類型:盡量使用timestamp,空間效率高於datetime,但是如果表中有timestamp類的列,每次更新時timestamp列都會自動更新為當前時間戳
- 整數類型:包括 tinyint、smallint、mediumint、int、bigint、分別表示1字節、2字節、3字節、4字節、8字節整數。任何整數類型都可以加上unsigned,表示數據是無符號的,即非負整數。
MySQL基礎操作
MySQL的連接和關閉:mysql -u -p -h -P
-u:指定用戶名
-p:指定密碼
-h:主機
-P:端口
進入MySQL命令行后:G、c、q、s、h、d
G:打印結果垂直顯示
c:取消當前MySQL命令
q:退出MySQL連接
s:顯示服務器狀態
h:幫助信息
d:改變執行符
MySQL存儲引擎:
1、InnoDB存儲引擎
- 默認事物型引擎,最重要最廣泛的存儲引擎,性能非常優秀。
- 數據存儲在共享表空間,可以通過配置分開。也就是多個表和索引都存儲在一個表空間中,可以通過配置文件改變此配置
- 對主鍵查詢的性能高於其他類型的存儲引擎
- 內部做了很多優化,從磁盤讀取數據時會自動構建hash索引,插入數據時自動構建插入緩沖區
- 通過一些機制和工具支持真正的熱備份
- 支持崩潰后的安全回復
- 支持行級鎖
- 支持外鍵
2、MyISAM存儲引擎
- 擁有全文索引、壓縮、空間函數
- 不支持事物和行級鎖、不支持崩潰后的安全恢復
- 表存儲在兩個文件,MYD(MY date)和MYI(MY index)
- 設計簡單,某些場景下性能很好,例如獲取整個表有多少條數據,性能很高。
- 全部索引不是很常用,不如使用外部的ElasticSearch
3、其他引擎
Archive、Blackhole、CSV、Memory
使用策略:在大多數場景下建議使用InnoDB存儲引擎
MySQL鎖機制
表鎖是日常開發中的常見問題,因此也是面試中最常見的考察點,當多個查詢同一時刻進行數據修改時,就會產生並發控制的問題。共享鎖和排它鎖,就是讀鎖和寫鎖
- 共享鎖:不堵塞,多個用戶可以同時讀同一個資源,互不干擾
- 排他鎖:一個寫鎖會堵塞其他的讀鎖和寫鎖,這樣可以只允許一個用戶進行寫入,防止其他用戶讀取正在寫入的資源
鎖的粒度 - 表鎖:系統開銷最小,會鎖定整張表,MyISAM使用表鎖
- 行鎖:最大程度的支持並發處理,但是也帶來了最大的鎖開銷,InnoDB使用行鎖
MySQL事物處理
- MySQL提供事物處理的表引擎,InnoDB
- 服務器層不管理事物,由下層的引擎實現,所以同一個事物中,使用多種引擎是不靠譜的
- 需要注意,在非事物表上執行事物操作,MySQL不會發出提醒,也不會報錯
存儲過程
- 為以后的使用保存的一條或多條MySQL語句的集合,因此也可以在存儲過程中加入業務邏輯和流程
- 可以在存儲過程中創建表,更新數據,刪除數據等等
使用策略
- 可以通過把SQL語句封裝在容易使用的單元中,簡化復雜的操作
- 可以保證數據的一致性
- 可以簡化對變動的管理
觸發器
提供給程序員和數據分析員來保證數據完整性的一種方法,與表事件相關的特殊的存儲過程。
使用場景
-
可以通過數據庫中的相關表實現級聯更改
-
實時監控某張表中的某個字段的更改而需要做出相應的處理
-
例如可以生成某些業務的編號
-
注意不要濫用。否則會造成數據庫及應用程序的維護困難
-
InnoDB和MyISAM的區別
- InnoDB支持事物,MyISAM不支持
- InnoDB數據存儲在共享表空間,MyISAM數據存儲在文件中
- InnoDB支持行級鎖,MyISAM只支持表鎖
- InnoDB支持崩潰后的恢復,MyISAM不支持
- InnoDB支持外鍵,MyISAM不支持
- InnoDB不支持全文索引,MyISAM支持全文索引
-
InnoDB引擎的特性
- 插入緩沖(insert buffer)
- 二次寫(double write)
- 自適應哈希索引(ahi)
- 預讀(read ahead)
-
varchar和text的區別
- varchar可指定字符數,text不能指定,內部存儲varchar是存入的實際字符數+1個字節(n<=255)或2個字節(n>255),text是實際字符數+2個字節
- text類型不能有默認值
- varchar可直接創建索引,text創建索引要指定前多少個字符。varchar查詢速度快於text,在都創建索引的情況下,text的索引幾乎不起作用
- 查詢text需要創建臨時表
-
varchar(50)中50的涵義
最多存放50個字符,varchar(50)和(200)存儲hello所占空間一樣,但后者在排序時會消耗更多內存,因為order by col采用fixed_lengtn計算col長度(memory引擎也一樣) -
MySQL中,索引,主鍵,唯一索引,聯合索引的區別,對數據庫性能有什么影響
- 索引的基礎
- 索引類似於書籍的目錄,要想找到一本書的某個特定主題,需要先查找書的目錄,定位對應的頁面
- 存儲引擎使用類似的方式進行數據查詢,先去索引當中找到對應的值,然后根據匹配的索引找到對應的數據行
- 創建索引的語法
- 首先創建一個表:create table t1 (id int primary key,username varchar(20),password varchar(20));
- 創建單個索引的語法:create index 索引名 on 表名(字段名);
- 索引名一般是:表名_字段名
- 給id創建索引:create index ti_id on t1(id);
- 創建聯合索引的語法:create index 索引名 on 表名(字段名1,字段名2)
- 給username 和 password 創建聯合索引:create index t1_username_password on t1(username,password)
- 其中index還可以替換成unique,primary key,分別代表唯一索引和主鍵索引
- 刪除索引:drop index t1_username_password on t1
- 索引對性能的影響
- 大大減少服務器需要掃描的數據量
- 幫助服務器避免排序和臨時表
- 將隨機I/O變順序I/O
- 大大提高查詢速度
- 降低寫得速度(不良影響)
- 磁盤占用(不良影響)
- 索引的使用場景
- 對於非常小的表,大部分情況下全表掃描效率更高
- 中到大型表,索引非常有效
- 特大型的表,建立和使用索引的代價會隨之增大,可以使用分區技術來解決
- 索引的類型
索引有多種類型,是在MySQL的存儲引擎實現的- 普通索引:最基本的索引,沒有任何約束限制
- 唯一索引:和普通索引類似,但是具有唯一性約束
- 主鍵索引:特殊的唯一索引,不允許有空值
- 索引的區別
一個表只能有一個主鍵索引,但是可以有多個唯一索引- 主鍵索引一定是唯一索引,唯一索引不一定是主鍵索引
- 主鍵和與外鍵構成參照完整性約束,防止數據不一致
- 聯合索引:將多個列組合在一起創建索引,可以覆蓋多個列。(也叫復合索引,組合索引)
- 外鍵索引:只有InnoDB引擎的表才可以使用外鍵索引,保證數據的一致性、完整性和實現級聯操作
- 全文索引:MySQL自帶的全部索引只能用於MyISAM,並且只能對英文進行全文檢索(基本不用)
- MySQL索引的創建原則
- 最適合創建索引的列是出現在where或on字句中的列,或連接子句的列而不是出現在select關鍵字后的列
- 索引列的基數越大,數據區分度越高,索引的效果越好
- 對於字符串進行索引,應該制定一個前綴長度,可以節省大量的索引空間
- 根據情況創建聯合索引,聯合索引可以提高查詢效率
- 避免創建過多的所有,所有會額外占用磁盤空間,降低寫操作效率
- 主鍵盡可能選擇較短的數據類型,可以有效減少索引的磁盤占用提高查詢效率
- 索引的基礎