mysql 常見面試題

Mysql 基礎

一、 基礎知識

1. 什麼是數據庫?、、

數據庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫

2. 什麼是關係型數據庫,主鍵,外鍵,索引分別是什麼?

關係型數據庫是由多張能互相聯接的二維行列表格組成的數據庫

主關鍵字(primary key)是表中的一個或多個字段,它的值用於唯一地標識表中的某一條記錄

外鍵表示了兩個關係之間的相關聯繫。以另一個關係的外鍵作主關鍵字的表被稱爲主表,具有此外鍵的表被稱

爲主表的從表。外鍵又稱作外關鍵字

在關係數據庫中,索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的一種存儲結構,它是某

個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單

3. 表的連接查詢方式有哪些,有什麼區別?

交叉連接即笛卡兒乘積,是指兩個關係中所有元組的任意組合

使用內連接時,如果兩個表的相關字段滿足連接條件,就從這兩個表中提取數據並組合成新的記錄

自連接是一種特殊的內連接,它是指相互連接的表在物理上爲同一張表,但可以在邏輯上分爲兩張表

外連接是隻限制一張表中的數據必須滿足連接條件,而另一張表中的數據可以不滿足連接條件的連接方式

4. SQL 的 select 語句完整的執行順序?

1、from 子句組裝來自不同數據源的數據;

2、where 子句基於指定的條件對記錄行進行篩選;

3、group by 子句將數據劃分爲多個分組;

4、使用聚集函數進行計算;

5、使用 having 子句篩選分組;

6、計算所有的表達式;

7、select 的字段;

8、使用 order by 對結果集進行排序。

5. 說一下 Mysql 數據庫存儲的原理?

儲存過程是一個可編程的函數,它在數據庫中創建並保存。它可以有 SQL 語句和一些特殊的控制結構組成。

當希望在不同的應用程序或平臺上執行相同的函數,或者封裝特定功能時,存儲過程是非常有用的。數據庫中的存

儲過程可以看做是對編程中面向對象方法的模擬。它允許控制數據的訪問方式。存儲過程通常有以下優點:

1、存儲過程能實現較快的執行速度

2、存儲過程允許標準組件是編程。

3、存儲過程可以用流程控制語句編寫,有很強的靈活性,可以完成複雜的判斷和較複雜的運算。

4、存儲過程可被作爲一種安全機制來充分利用。

5、存儲過程能夠減少網絡流量

6. 事務的特性?

1、原子性(Atomicity):事務中的全部操作在數據庫中是不可分割的,要麼全部完成,要麼均不執行。

2、一致性(Consistency):幾個並行執行的事務,其執行結果必須與按某一順序串行執行的結果相一致。

3、隔離性(Isolation):事務的執行不受其他事務的干擾,事務執行的中間結果對其他事務必須是透明的。

4、持久性(Durability):對於任意已提交事務,系統必須保證該事務對數據庫的改變不被丟失,即使數據庫出現

故障

7. 數據庫索引?l

數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現

通常使用 B_TREE。B_TREE 索引加速了數據訪問,因爲存儲引擎不會再去掃描整張表得到需要的數據;相反,它

從根節點開始,根節點保存了子節點的指針,存儲引擎會根據指針快速尋找數據。

8. 數據庫怎麼優化查詢效率?

1、儲存引擎選擇:如果數據表需要事務處理,應該考慮使用 InnoDB,因爲它完全符合 ACID 特性。如果不需

要事務處理,使用默認存儲引擎 MyISAM 是比較明智的

2、分表分庫,主從。

3、對查詢進行優化,要儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引

4、應儘量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描

5、應儘量避免在 where 子句中使用!= 或<> 操作符,否則將引擎放棄使用索引而進行全表掃描

6、應儘量避免在 where 子句中使用 or 來連接條件,如果一個字段有索引,一個字段沒有索引,將導致引擎

放棄使用索引而進行全表掃描

7、Update 語句,如果只更改 1、2 個字段,不要 Update 全部字段,否則頻繁調用會引起明顯的性能消耗,

同時帶來大量日誌

8、對於多張大數據量(這裏幾百條就算大了)的表 JOIN,要先分頁再 JOIN,否則邏輯讀會很高,性能很差。

9. 你用的 Mysql 是哪個引擎,各引擎之間有什麼區別?

主要 MyISAM 與 InnoDB 兩個引擎,其主要區別如下:InnoDB 支持事務,MyISAM 不支持,這一點是非常

之重要。事務是一種高級的處理方式,如在一些列增刪改中只要哪個出錯還可以回滾還原,而 MyISAM 就不可以了;

MyISAM 適合查詢以及插入爲主的應用,InnoDB 適合頻繁修改以及涉及到安全性較高的應用;

InnoDB 支持外鍵,MyISAM 不支持;

MyISAM 是默認引擎,InnoDB 需要指定;

InnoDB 不支持 FULLTEXT 類型的索引;

InnoDB 中不保存表的行數,如 select count() from table 時,InnoDB;需要掃描一遍整個表來計算有多少行,

但是 MyISAM 只要簡單的讀出保存好的行數即可。注意的是,當 count()語句包含 where 條件時 MyISAM 也需要

掃描整個表;

對於自增長的字段,InnoDB 中必須包含只有該字段的索引,但是在 MyISAM 表中可以和其他字

段一起建立聯合索引;清空整個表時,InnoDB 是一行一行的刪除,效率非常慢。MyISAM 則會重建表;

InnoDB 支持行鎖(某些情況下還是鎖整表,如 update table set a=1 where user like '%lee%'

10.如何對查詢命令進行優化?

a. 應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索。

b. 應儘量避免在 where 子句中對字段進行 null 值判斷,避免使用!=或<>操作符,避免使用 or

連接條件,或在 where 子句中使用參數、對字段進行表達式或函數操作,否則會導致權標掃描

c. 不要在 where 子句中的“=”左邊進行函數、算術運算或其他表達式運算,否則系統將可能無

法正確使用索引。

d. 使用索引字段作爲條件時,如果該索引是複合索引,那麼必須使用到該索引中的第一個字段作爲

條件時才能保證系統使用該索引,否則該索引將不會被使用。

e. 很多時候可考慮用 exists 代替 in。

f. 儘量使用數字型字段。

g. 儘可能的使用 varchar/nvarchar 代替 char/nchar。

h. 任何地方都不要使用 select from t ,用具體的字段列表代替“”,不要返回用不到的任何字段。

i. 儘量使用表變量來代替臨時表。

j. 避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。

k. 儘量避免使用遊標,因爲遊標的效率較差。

l. 在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF。

m. 儘量避免大事務操作,提高系統併發能力。

n. 儘量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。

11.數據庫的優化?

1.優化索引、SQL 語句、分析慢查詢;

2.設計表的時候嚴格根據數據庫的設計範式來設計數據庫;

3.使用緩存,把經常訪問到的數據而且不需要經常變化的數據放在緩存中,能節約磁盤 IO

4.優化硬件;採用 SSD,使用磁盤隊列技術(RAID0,RAID1,RDID5)等

5.採用 MySQL 內部自帶的表分區技術,把數據分層不同的文件,能夠提高磁盤的讀取效率;

6.垂直分表;把一些不經常讀的數據放在一張表裏,節約磁盤 I/O;

7.主從分離讀寫;採用主從複製把數據庫的讀操作和寫入操作分離開來;

8.分庫分表分機器(數據量特別大),主要的的原理就是數據路由;

9.選擇合適的表引擎,參數上的優化

10.進行架構級別的緩存,靜態化和分佈式;

11.不採用全文索引;

12.採用更快的存儲方式,例如 NoSQL 存儲經常訪問的數據。

12.Sql 注入是如何產生的,如何防止?

程序開發過程中不注意規範書寫 sql 語句和對特殊字符進行過濾,導致客戶端可以通過全局變量 POST 和 GET

提交一些 sql 語句正常執行。產生 Sql 注入。下面是防止辦法:

a. 過濾掉一些常見的數據庫操作關鍵字,或者通過系統函數來進行過濾。

b. 在 PHP 配置文件中將 Register_globals=off;設置爲關閉狀態

c. SQL 語句書寫的時候儘量不要省略小引號(tab 鍵上面那個)和單引號

d. 提高數據庫命名技巧,對於一些重要的字段根據程序的特點命名,取不易被猜到的

e. 對於常用的方法加以封裝,避免直接暴漏 SQL 語句

f. 開啓 PHP 安全模式:Safe_mode=on;

g. 打開 magic_quotes_gpc 來防止 SQL 注入

h. 控制錯誤信息:關閉錯誤提示信息,將錯誤信息寫到系統日誌。

i. 使用 mysqli 或 pdo 預處理。

13.NoSQL 和關係數據庫的區別?

a. SQL 數據存在特定結構的表中;而 NoSQL 則更加靈活和可擴展,存儲方式可以省是 JSON 文檔、哈希表

或者其他方式。

b. 在 SQL 中,必須定義好表和字段結構後才能添加數據,例如定義表的主鍵(primary key),索引(index),觸發

器(trigger),存儲過程(stored procedure)等。表結構可以在被定義之後更新,但是如果有比較大的結構變更的話就會

變得比較複雜。在 NoSQL 中,數據可以在任何時候任何地方添加,不需要

先定義表。

c. SQL 中如果需要增加外部關聯數據的話,規範化做法是在原表中增加一個外鍵,關聯外部數據表。而在

NoSQL 中除了這種規範化的外部數據表做法以外,我們還能用如下的非規範化方式把外部數據直接放到原數據集

中,以提高查詢效率。缺點也比較明顯,更新審覈人數據的時候將會比較麻煩。

d. SQL 中可以使用 JOIN 錶鏈接方式將多個關係數據表中的數據用一條簡單的查詢語句查詢出來。

NoSQL 暫未提供類似 JOIN 的查詢方式對多個數據集中的數據做查詢。所以大部分 NoSQL 使用非規範化的

數據存儲方式存儲數據。

e. SQL 中不允許刪除已經被使用的外部數據,而 NoSQL 中則沒有這種強耦合的概念,可以隨時刪除任何數

據。

f. SQL 中如果多張表數據需要同批次被更新,即如果其中一張表更新失敗的話其他表也不能更新成

功。這種場景可以通過事務來控制,可以在所有命令完成後再統一提交事務。而 NoSQL 中沒有事務這個概念,

每一個數據集的操作都是原子級的。

g. 在相同水平的系統設計的前提下,因爲 NoSQL 中省略了 JOIN 查詢的消耗,故理論上性能上是優於 SQL 的。

14.MySQL 與 MongoDB 本質之間最基本的差別是什麼

差別在多方面,例如:數據的表示、查詢、關係、事務、模式的設計和定義、速度和性能。MongoDB 是由 C++

語言編寫的,是一個基於分佈式文件存儲的開源數據庫系統。在高負載的情況下,添加更多的節點,可以保證服務

器性能。

MongoDB 旨在爲 WEB 應用提供可擴展的高性能數據存儲解決方案。

MongoDB 將數據存儲爲一個文檔,數據結構由鍵值(key=>value)對組成。MongoDB 文檔類似於 JSON 對象。

字段值可以包含其他文檔,數組及文檔數組。

MongoDB 是一個面向文檔的數據庫,目前由 10gen 開發並維護,它的功能豐富齊全,所以完全可以替代

MySQL。

與 MySQL 等關係型數據庫相比,MongoDB 的優點如下:

①弱一致性,更能保證用戶的訪問速度。

②文檔結構的存儲方式,能夠更便捷的獲取數據。

③內置 GridFS,支持大容量的存儲。

④內置 Sharding。

⑤第三方支持豐富。(這是與其他的 NoSQL 相比,MongoDB 也具有的優勢)

⑥性能優越:

MongoDB 本身它還算比較年輕的一個產品,所以它的問題,就是成熟度肯定沒有傳統 MySQL 那麼成熟穩定。

所以在使用的時候:

儘量使用穩定版,不要在線上使用開發版,這是一個大原則;

另外一點,備份很重要,MongoDB 如果出現一些異常情況,備份一定是要能跟上。除了通過傳統的複製的方

式來做備份,離線備份也還是要有,不管你是用什麼方式,都要有一個完整的離線備份。往往最後出現了特殊情況,

它能幫助到你;另外,MongoDB 性能的一個關鍵點就是索引,索引是不是能有比較好的使用效率,索引是不是能

夠放在內存中,這樣能夠提升隨機讀寫的性能。如果你的索引不能完全放在內存中,一旦出現隨機讀寫比較高的時

候,它就會頻繁地進行磁盤交換,這個時候,MongoDB 的性能就會急劇下降,會出現波動。

另外,MongoDB 還有一個最大的缺點,就是它佔用的空間很大,因爲它屬於典型空間換時間原則的類型。那

麼它的磁盤空間比普通數據庫會浪費一些,而且到目前爲止它還沒有實現在線壓縮功能,在 MongoDB 中頻繁的進

行數據增刪改時,如果記錄變了,例如數據大小發生了變化,這時候容易產生一些數據碎片,出現碎片引發的結果,

一個是索引會出現性能問題。

另外一個就是在一定的時間後,所佔空間會莫明其妙地增大,所以要定期把數據庫做修復,定期重新做索引,

這樣會提升 MongoDB 的穩定性和效率。在最新的版本里,它已經在實現在線壓縮,估計應該在 2.0 版左右,應該

能夠實現在線壓縮,可以在後臺執行現在 repair DataBase 的一些操作。

如果那樣,就解決了目前困擾我們的大問題。

15.Mysql 數據庫中怎麼實現分頁?

select * from table limit (start-1)*limit,limit; 其中 start 是頁碼,limit 是每頁顯示的條數。

16.sql 語句怎麼看效率?

17.提取數據庫中倒數 10 條數據?

18.Mysql 數據庫的操作?

修改表-修改字段,重命名版:

alter table 表名 change 原名新名類型及約束;

alter table students change birthday birth datetime not null;

修改表-修改字段,不重名版本:

alter table 表名 modify 列名類型和約束;

alter table students modify birth date not null

全列插入:insert into 表名 values(...)

insert into students values(0,"郭靖", 1,"內蒙","2017-6");

部分插入:值的順序與給出的列順序對應:

insert into students(name, birthday) values("黃蓉","2017-8");

修改:update 表名 set 列 1=值 1,列 2=值 2.。。where

update students set gender=0, homwtown="古墓", where id = 5;

備份:mysqldump -uroot -p 數據庫名 > python.sql,

恢復:mysql -uroot -p 數據庫名< python.sql

19.優化數據庫?提高數據庫的性能?

1.對語句的優化

①用程序中,保證在實現功能的基礎上,儘量減少對數據庫的訪問次數;通過搜索參數,儘量減少對錶的訪問

行數,最小化結果集,從而減輕網絡負擔;

②能夠分開的操作儘量分開處理,提高每次的響應速度;在數據窗口使用 SQL 時,儘量把使用的索引放在選

擇的首列;算法的結構儘量簡單;

③在查詢時,不要過多地使用通配符如 SELECT * FROM T1 語句,要用到幾列就選擇幾列如:SELECT

COL1,COL2 FROM T1;

④在可能的情況下儘量限制儘量結果集行數如:SELECT TOP 300 COL1,COL2,COL3 FROMT1,因爲某些情況

下用戶是不需要那麼多的數據的。

⑤不要在應用中使用數據庫遊標,遊標是非常有用的工具,但比使用常規的、面向集的 SQL 語句需要更大的

開銷;按照特定順序提取數據的查找。

2. 避免使用不兼容的數據類型

例如 float 和 int、char 和 varchar、binary 和 varbinary 是不兼容的。

數據類型的不兼容可能使優化器無法執行一些本來可以進行的優化操作。

例如:

SELECT name FROM employee WHERE salary > 60000

在這條語句中,如 salary 字段是 money 型的,則優化器很難對其進行優化,因爲 60000 是個整型數。我們應當在

編程時將整型轉化成爲錢幣型,而不要等到運行時轉化。若在查詢時強制轉換,查詢速度會明顯減慢。

3.避免在 WHERE 子句中對字段進行函數或表達式操作

若進行函數或表達式操作,將導致引擎放棄使用索引而進行全表掃描。

4.避免使用!=或<>、IS NULL 或 IS NOT NULL、IN ,NOT IN 等這樣的操作符

5.儘量使用數字型字段

6.合理使用 EXISTS,NOT EXISTS 子句。

7.儘量避免在索引過的字符數據中,使用非打頭字母搜索。

8.分利用連接條件

9.消除對大型錶行數據的順序存取

10. 避免困難的正規表達式

11. 使用視圖加速查詢

12. 能夠用 BETWEEN 的就不要用 IN

13. DISTINCT 的就不用 GROUP BY

14. 部分利用索引

15. 能用 UNION ALL 就不要用 UNION

16. 不要寫一些不做任何事的查詢

17. 儘量不要用 SELECT INTO 語句

18. 必要時強制查詢優化器使用某個索引

19. 雖然 UPDATE、DELETE 語句的寫法基本固定,但是還是對 UPDATE 語句給點建議:

a) 儘量不要修改主鍵字段。

b) 當修改 VARCHAR 型字段時,儘量使用相同長度內容的值代替。

c) 儘量最小化對於含有 UPDATE 觸發器的表的 UPDATE 操作。

d) 避免 UPDATE 將要複製到其他數據庫的列。

e) 避免 UPDATE 建有很多索引的列。

f) 避免 UPDATE 在 WHERE 子句條件中的列。

20.存儲過程和函數的區別?

相同點:存儲過程和函數都是爲了可重複的執行操作數據庫的 sql 語句的集合。

1)存儲過程和函數都是一次編譯,就會被緩存起來,下次使用就直接命中已經編譯好的 sql 語句,不需要重複

使用。減少網絡交互,減少網絡訪問流量。

不同點:標識符不同,函數的標識符是 function,存儲過程是 proceduce。

1)函數中有返回值,且必須有返回值,而過程沒有返回值,但是可以通過設置參數類型(in,out)來實現多個參

數或者返回值。

2)存儲函數使用 select 調用,存儲過程需要使用 call 調用。

3)select 語句可以在存儲過程中調用,但是除了 select..into 之外的 select 語句都不能在函數中使用。

4)通過 in out 參數,過程相關函數更加靈活,可以返回多個結果。

21.Mysql 開啓 General-log 日誌?

Show variables like ‘general%’;

Set global general_log=1;

Set global general_log=0;

二、 查詢聯繫

22.Student-Sourse-SC-Teacher 表關係如下:

l Student(sid,Sname,Sage,Ssex)學生表

l Course(cid,Cname,tid)課程表

l SC(sid,cid,score)成績表

l Teacher(tid,Tname)教師表

寫出 sql 語句:

l 查詢課程“001“課程比”002“課程成績高的所有學生的學號

l 修改學號爲 20131201 的語文成績爲 100‘

l 插入一條名爲“李四”的教師記錄

l 刪除學習“葉平”老師課程的 sc 表記錄

23.員工信息 A-員工親屬信息表 B 表關係如下:

l 員工信息表A:員工標號(codecode,PK),員工姓名(codename),員工性別(codesex),聯繫電話(codetel),

備註(remarks)

l 員工親屬信息表 B:員工編碼(codecode),親屬編碼(recodecode,PK),親屬姓名(recodename),

聯繫電話(recodetel),備註(remarks)

寫出 sql 語句:

l 向員工信息表中插入一條數據:(001,張三,男,010-62570007,北京市海淀區)

l 查詢出親屬數量大於 1 的員工編碼,員工姓名,員工親屬數量有部分員工親屬信息重複錄入(親屬編碼不

同,其他相同),出現這種情況的員工編碼,重複的親屬編碼,親屬姓名查詢出來。

24.部門表 dept-僱員表 emp 表關係如下:

l 部門表 dept:部門標號(DEPTNO),部門名稱(DNAME),所在位置(LOC)

l 僱員表 emp:員工標號(Empno),員工名稱(Emname),員工工位(Job),經理(Mgr),僱傭日期(Hiredate),

薪水(Sal),部門編號(Deptno)

寫出 sql 語句:

l 找出部門名稱爲 ACCOUNTING 的部門下的所有員工名稱?

l 找出部門名稱爲 SALES 的部門下每月需要發出的薪水總額?

l 找出部門名稱爲 SALES 的部門的部門經理?

l 找出部門名稱爲 RESEARCH 的部門下僱傭日期爲 1980-12-17 的員工?

25.Student-coures-Studentcourse 表關係如下:

l student(sno,sname,age,sdept) 學生表

l course(cno,cname,teacher) 課程表

l Studentcourse(sno,cno,grade)選課表

寫出 sql 語句:

l 查詢所有課程都及格的學生號和姓名

l 查詢平均分不及格的課程號和平均成績

l 找出各門課程的平均成績,輸出課程號和平均成績

l 找出沒有選擇 c2 課程的學生信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章