MySQL 面試總結

SQL 注入

所謂SQL注入,就是經過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。php

咱們永遠不要信任用戶的輸入,咱們必須認定用戶輸入的數據都是不安全的,咱們都須要對用戶輸入的數據進行過濾處理。html

如下實例中,輸入的用戶名必須爲字母、數字及下劃線的組合,且用戶名長度爲 8 到 20 個字符之間:mysql

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){
   $result = mysqli_query($conn, "SELECT * FROM users 
                          WHERE username=$matches[0]");
} else {
   echo "username 輸入異常";
}

讓咱們看下在沒有過濾特殊字符時,出現的SQL狀況:正則表達式

// 設定$name 中插入了咱們不須要的SQL語句
$name = "Qadir'; DELETE FROM users;";
 mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");

以上的注入語句中,咱們沒有對 $name 的變量進行過濾,$name 中插入了咱們不須要的SQL語句,將刪除 users 表中的全部數據。sql

在PHP中的 mysqli_query() 是不容許執行多個 SQL 語句的,可是在 SQLite 和 PostgreSQL 是能夠同時執行多條SQL語句的,因此咱們對這些用戶的數據須要進行嚴格的驗證。數據庫

防止SQL注入,咱們須要注意如下幾個要點:安全

  1. 永遠不要信任用戶的輸入。對用戶的輸入進行校驗,能夠經過正則表達式,或限制長度;對單引號和 雙"-"進行轉換等。
  2. 永遠不要使用動態拼裝sql,可使用參數化的sql或者直接使用存儲過程進行數據查詢存取。
  3. 永遠不要使用管理員權限的數據庫鏈接,爲每一個應用使用單獨的權限有限的數據庫鏈接。
  4. 不要把機密信息直接存放,加密或者hash掉密碼和敏感的信息。
  5. 應用的異常信息應該給出儘量少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝
  6. sql注入的檢測方法通常採起輔助軟件或網站平臺來檢測,軟件通常採用sql注入檢測工具jsky,網站平臺就有億思網站安全平臺檢測工具。MDCSOFT SCAN等。採用MDCSOFT-IPS能夠有效的防護SQL注入,XSS攻擊等

防止SQL注入

在腳本語言,如Perl和PHP你能夠對用戶輸入的數據進行轉義從而來防止SQL注入。服務器

PHP的MySQL擴展提供了mysqli_real_escape_string()函數來轉義特殊的輸入字符。函數

if (get_magic_quotes_gpc()) {
  $name = stripslashes($name);
}
$name = mysqli_real_escape_string($conn, $name);
 mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");

Like語句中的注入

like查詢時,若是用戶輸入的值有"_"和"%",則會出現這種狀況:用戶原本只是想查詢"abcd_",查詢結果中卻有"abcd_"、"abcde"、"abcdf"等等;用戶要查詢"30%"(注:百分之三十)時也會出現問題。工具

在PHP腳本中咱們可使用addcslashes()函數來處理以上狀況,以下實例:

$sub = addcslashes(mysqli_real_escape_string($conn, "%something_"), "%_");
// $sub == \%something\_
 mysqli_query($conn, "SELECT * FROM messages WHERE subject LIKE '{$sub}%'");

addcslashes() 函數在指定的字符前添加反斜槓。

語法格式:

addcslashes(string,characters)
參數 描述
string 必需。規定要檢查的字符串。
characters 可選。規定受 addcslashes() 影響的字符或字符範圍。

具體應用能夠查看:PHP addcslashes() 函數

查看: http://www.runoob.com/mysql/mysql-sql-injection.html

MySQL中myisam與innodb的區別

(1)、不一樣;

  1. InnoDB支持事物,而MyISAM不支持事物
  2. InnoDB支持行級鎖,而MyISAM支持表級鎖
  3. InnoDB支持MVCC, 而MyISAM不支持
  4. InnoDB支持外鍵,而MyISAM不支持
  5. InnoDB不支持全文索引,而MyISAM支持。

(2)、innodb引擎的4大特性

插入緩衝(insert buffer),二次寫(double write),自適應哈希索引(ahi),預讀(read ahead)

(3)、2者select count(*)哪一個更快,爲何

myisam更快,由於myisam內部維護了一個計數器,能夠直接調取。

數據庫優化的思路

1.SQL語句優化

  1. 應儘可能避免在 where 子句中使用!=或<>操做符,不然將引擎放棄使用索引而進行全表掃描。
  2. 應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描,如:select id from t where num is null,能夠在num上設置默認值0,確保表中num列沒有null值,而後這樣查詢:select id from t where num=0
  3. 不少時候用 exists 代替 in 是一個好的選擇
  4. 用Where子句替換HAVING 子句 由於HAVING 只會在檢索出全部記錄以後纔對結果集進行過濾

2.索引優化

3.數據庫結構優化

1)範式優化: 好比消除冗餘(節省空間。。)

2)反範式優化:好比適當加冗餘等(減小join)

3)拆分表: 分區將數據在物理上分隔開,不一樣分區的數據能夠制定保存在處於不一樣磁盤上的數據文件裏。這樣,當對這個表進行查詢時,只須要在表分區中進行掃描,而沒必要進行全表掃描,明顯縮短了查詢時間,另外處於不一樣磁盤的分區也將對這個表的數據傳輸分散在不一樣的磁盤I/O,一個精心設置的分區能夠將數據傳輸對磁盤I/O競爭均勻地分散開。對數據量大的時時表可採起此方法。可按月自動建表分區。

4)拆分其實又分垂直拆分和水平拆分: 案例: 簡單購物系統暫設涉及以下表:

  1. 產品表(數據量10w,穩定)
  2. 訂單表(數據量200w,且有增加趨勢)
  3. 用戶表 (數據量100w,且有增加趨勢) 以mysql爲例講述下水平拆分和垂直拆分,mysql能容忍的數量級在百萬靜態數據能夠到千萬 垂直拆分:解決問題:表與表之間的io競爭 不解決問題:單表中數據量增加出現的壓力 方案: 把產品表和用戶表放到一個server上 訂單表單獨放到一個server上 水平拆分: 解決問題:單表中數據量增加出現的壓力 不解決問題:表與表之間的io爭奪

方案: 用戶表經過性別拆分爲男用戶表和女用戶表 訂單表經過已完成和完成中拆分爲已完成訂單和未完成訂單 產品表 未完成訂單放一個server上 已完成訂單表盒男用戶表放一個server上 女用戶表放一個server上

數據類型

大體能夠分爲三類:數值、日期/時間和字符串(字符)類型。

相關文章
相關標籤/搜索