數據庫面試題總結二(varchar / char、delete / drop / truncate、MyISAM / InnoDB、優化方法)

目錄

char 和 varchar區別、numeric

delete、drop 和 truncate 區別

MyISAM 和 InnoDB 區別

數據庫優化方式


數據庫面試題總結一(範式、視圖、索引、授權、事務、觸發器、連接方式)

https://blog.csdn.net/zhsihui429/article/details/86530609

 

char 和 varchar區別、numeric

  • char(n):固定長度的字符串,用戶指定長度n
  • varchar(n):可變長度的字符串,用戶指定最大長度n

例子:屬性A的類型是char(10),若爲此屬性存入“Avi”,那麼該字符串後會追加7個空格來使其達到10個字符的串長度。反之,如果屬性B的類型是varchar(10),在屬性B中存放字符串“Avi”,則不會增加空格。

當比較兩個char類型的值時,如果它們的長度不同,在比較之前會自動在短值後加上額外的空格以使它們的長度一致。

但當比較一個char類型和一個varchar類型時,不一定會在varchar後加上額外的空格以使長度一致,取決於數據庫系統,因此,即使都存放“Avi”,A = B的比較也可能返回假。

建議使用varchar類型來存放字符串。

  • numeric(p,d):定點數,精度由用戶指定。這個數有p位數字(加上一個符號位,即不含符號位)其中d位數字在小數點右邊

 

delete、drop 和 truncate 區別

【1】delete

  • delete是DML,執行delete操作時,每次從表中刪除一行,並且同時將該行的的刪除操作記錄在redo和undo表空間(日誌)中以便進行回滾(rollback)和重做操作,但要注意表空間要足夠大,事務需要手動提交(commit)操作才能生效,可以通過rollback撤消操作。如果有相應的 tigger,執行的時候將被觸發。
  • delete 可對 table 和 view 操作只刪除數據。delete 操作不會減少表或索引所佔用的空間。
  • delete可根據條件刪除表中滿足條件的數據,如果不指定where子句,那麼刪除表中所有記錄。
  • delete語句不影響表所佔用的extent,高水線(high watermark)保持原位置不變。
  • 使用:如果想刪除部分數據注意帶上where子句,回滾段要足夠大;如果和事務有關,或者想觸發trigger;如果想保留標識計數值,用delete。

【2】truncate

  • truncate是DDL,會隱式提交,操作立即生效,原數據不放到 rollback segment中,即刪除操作記錄不寫入日誌保存,所以執行速度快,但不能回滾,不會觸發觸發器。
  • 只能對 table 操作只刪除數據。當表被 truncate 後,這個表和索引所佔用的空間會恢復到初始大小。
  • truncate會一次性刪除表中所有行,但表結構及其列、約束、索引等保持不變
  • 對於外鍵(foreignkey)約束引用的表,不能使用 truncate table,而應使用不帶 where 子句的 delete 語句。
  • truncatetable不能用於參與了索引視圖的表。
  • truncate 會重新設置高水線和所有的索引,缺省情況下將空間釋放到minextents個extent,除非使用reuse storage。
  • 如果一不小心把一個表truncate掉,也是可以恢復的,只是不能通過rollback來恢復。
  • 使用:如果想保留表而將所有數據刪除,且和事務無關,用truncate;如果是整理表內部的碎片,可以用truncate跟上reuse stroage,再重新導入/插入數據。

【3】drop

  • drop是DDL,會隱式提交,操作立即生效,原數據不放到 rollback segment中,不能回滾,不會觸發觸發器。
  • 刪除整個表(結構和數據)。drop語句將表所佔用的空間全釋放掉。
  • drop語句將刪除表的結構所依賴的約束,觸發器,索引,依賴於該表的存儲過程/函數將保留,但是變爲invalid狀態。
  • 使用:如果想刪除表定義及其數據,用drop。

【總結】

  • 執行速度:drop> truncate > delete
  • 在沒有備份情況下,謹慎使用 drop 與 truncate。
  • truncate table 在功能上與不帶 where 子句的 delete 語句相同:二者均刪除表中的全部行。但 truncate 比 delete 速度快,且使用的系統和事務日誌資源少。delete 語句每次刪除一行,並在事務日誌中爲所刪除的每行記錄一項。truncate 通過釋放存儲表數據所用的數據頁來刪除數據,並且只在事務日誌中記錄頁的釋放。
  • truncate與不帶where的delete :只刪除數據,而不刪除表的結構(定義)

 

MyISAM 和 InnoDB 區別

  • MyISAM默認表類型,它是基於傳統的ISAM類型,ISAM是Indexed Sequential Access Method (有索引的順序訪問方法) 的縮寫,它是存儲記錄和文件的標準方法。不支持事務,而且不支持外鍵,如果執行大量的select的時候,MyISAM比較適合。只支持表級鎖,select,update,delete,insert語句都會給表自動加鎖,如果加鎖以後的表滿足insert併發的情況下,可以在表的尾部插入新的數據。提供高速存儲和檢索,以及全文搜索能力。支持(FULLTEXT類型的)全文索引。索引和數據分離,是天生非聚簇索引,最多有一個unique性質。佔用空間小。執行速度更快,性能好。
  • InnoDB:支持事務安全的引擎,支持外鍵、行級鎖、事務是它最大特點。如果有大量的update和insert,建議使用InnoDB,可以提高多用戶併發操作的性能,特別是針對多個併發和QPS較高的情況。主要用於事務處理應用程序。索引和數據不分離,其本身就是主鍵索引文件(聚簇索引)。主鍵範圍更大。

MySQL主要的兩種鎖的特性可大致歸納如下:

  • 表級鎖: 開銷小,加鎖快;不會出現死鎖(因爲MyISAM會一次性獲得SQL所需的全部鎖);鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
  • 行級鎖: 開銷大(佔更多內存),加鎖慢(因爲要獲得更多的鎖);會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高,即使有許多線程訪問不同的行時,也只存在少量的衝突;回滾時只有少量的更改;可以長時間鎖定單一的行。

考慮上述特點,表級鎖使用與併發性不高,以查詢爲主,少量更新的應用,比如小型的web應用;而行級鎖適用於高併發環境下,對事務完整性要求較高的系統,如在線事務處理系統。

  • 頁級鎖:頁級鎖是表級鎖和行級鎖的折中,一次鎖定相鄰的一組記錄。

 

數據庫優化方式

  • 使用索引:成本最低,見效最快的解決方案。但索引不是越多越好,因爲寫入時可能重建索引結構,降低了效率。
  • 對查詢進行優化。要儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
  • 避免使用NULL值。儘量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描。char中null佔空間,varchar中不佔空間。可設置默認值爲0。
  • 儘量避免在 where 子句中對字段進行表達式操作 / 儘量避免在where子句中對字段進行函數操作 / 儘量避免在 where 子句中使用 != 或 <> 操作符 / 儘量避免在 where 子句中使用參數 / 儘量避免在 where 子句中使用 or 來連接條件,如果一個字段有索引,一個字段沒有索引,否則將引擎放棄使用索引而進行全表掃描
  • in 和 not in 也要慎用。對於連續的數值,儘量用 between 代替 in 。有時也可用 exists 代替 in 。
  • 不要Update全部字段,否則頻繁調用會引起明顯的性能消耗,同時帶來大量日誌。
  • 儘可能的使用 varchar / nvarchar 代替 char / nchar。首先變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高些。
  • 儘量使用表變量來代替臨時表。如果使用到了臨時表,在存儲過程的最後務必將所有的臨時表顯式刪除,先 truncate table ,然後 drop table ,這樣可以避免系統表的較長時間鎖定。
  • 儘量避免使用遊標,因爲遊標的效率較差。
  • 數據庫引擎選擇:myisam 和 innodb。一般,由於mysiam的索引結構是在內存中存的,所以比innodb快一些。但mysiam是表級鎖,而innodb是行級鎖,所以,mysiam適用於一次插入,多次查詢的表,或者是讀寫分離中的讀庫中的表,而對於修改插入刪除操作比較頻繁的表,就很不合適了。
  •  儘量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進行全表掃描。MySQL只有對以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE。
  • 儘量避免大事務操作,提高系統併發能力。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章