1. 程式人生 > >最近整理的一些常見的面試題,面試大全,黑馬程式設計師面試寶典題庫---資料庫--篇

最近整理的一些常見的面試題,面試大全,黑馬程式設計師面試寶典題庫---資料庫--篇

一、 Mysql


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


SQL Select 語句完整的執行順序:
1、 from 子句組裝來自不同資料來源的資料;
2、 where 子句基於指定的條件對記錄行進行篩選;
3、 group by 子句將資料劃分為多個分組;
4、使用聚集函式進行計算;
5、使用 having 子句篩選分組;
6、計算所有的表示式;
7、 select 的欄位;
8、使用 order by 對結果集進行排序。
SQL 語言不同於其他程式語言的最明顯特徵是處理程式碼的順序。在大多資料庫語言中,程式碼按編碼順序被處理。但在 SQL 語句中,第一個被處理的子句式 FROM,而不是第一齣現的 SELECT。 SQL 查詢處理的步驟序號:
(1) FROM <left_table>
(2) <join_type> JOIN <right_table>
(3) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE | ROLLUP}
(7) HAVING <having_condition>
(8) SELECT
(9) DISTINCT
(9) ORDER BY <order_by_list>
(10) <TOP_specification> <select_list>
以上每個步驟都會產生一個虛擬表,該虛擬表被用作下一個步驟的輸入。這些虛擬表對呼叫者(客戶端應用程式或者外部查詢)不可用。只有最後一步生成的表才會會給呼叫者。如果沒有在查詢中指定某一個子句,將跳過相應的步驟。

邏輯查詢處理階段簡介:
1、 FROM:對 FROM 子句中的前兩個表執行笛卡爾積(交叉聯接),生成虛擬表 VT1。
2、 ON:對 VT1 應用 ON 篩選器,只有那些使為真才被插入到 TV2。
3、 OUTER (JOIN):如果指定了 OUTER JOIN(相對於 CROSS JOIN 或 INNER JOIN),保留表中未找到
匹配的行將作為外部行新增到 VT2,生成 TV3。如果 FROM 子句包含兩個以上的表,則對上一個聯接生成的
結果表和下一個表重複執行步驟 1 到步驟 3,直到處理完所有的表位置。
4、 WHERE:對 TV3 應用 WHERE 篩選器,只有使為 true 的行才插入 TV4。
5、 GROUP BY:按 GROUP BY 子句中的列列表對 TV4 中的行進行分組,生成 TV5。
6、 CUTE|ROLLUP:把超組插入 VT5,生成 VT6。
7、 HAVING:對 VT6 應用 HAVING 篩選器,只有使為 true 的組插入到 VT7。
8、 SELECT:處理 SELECT 列表,產生 VT8。
9、 DISTINCT:將重複的行從 VT8 中刪除,產品 VT9。
10、 ORDER BY:將 VT9 中的行按 ORDER BY 子句中的列列表順序,生成一個遊標(VC10)。
11、 TOP:從 VC10 的開始處選擇指定數量或比例的行,生成表 TV11,並返回給呼叫者。
where 子句中的條件書寫順序

2. SQL 之聚合函式


聚合函式是對一組值進行計算並返回單一的值的函式,它經常與 select 語句中的 group by 子句一同使用。
a. avg():返回的是指定組中的平均值,空值被忽略。
b. count():返回的是指定組中的專案個數。
c. max():返回指定資料中的最大值。
d. min():返回指定資料中的最小值。
e. sum():返回指定資料的和,只能用於數字列,空值忽略。
f. group by():對資料進行分組,對執行完 group by 之後的組進行聚合函式的運算, 計算每一組的值。
最後用having去掉不符合條件的組,having子句中的每一個元素必須出現在select列表中(只針對於mysql)。
3. SQL 之連線查詢(左連線和右連線的區別)
外連線:
       左連線(左外連線):以左表作為基準進行查詢,左表資料會全部顯示出來,右表如果和左表匹配的資料則顯示相應欄位的資料,如果不匹配則顯示為 null。
       右連線(右外連線):以右表作為基準進行查詢,右表資料會全部顯示出來,左表如果和右表匹配的資料則顯示相應欄位的資料,如果不匹配則顯示為 null。
       全連線:先以左表進行左外連線,再以右表進行右外連線。
       內連線:顯示錶之間有連線匹配的所有行。

4. SQL 之 sql 注入


通過在 Web 表單中輸入(惡意) SQL 語句得到一個存在安全漏洞的網站上的資料庫,而不是按照設計者意圖去執行 SQL 語句。舉例:當執行的 sql 為 select * from user where username = “admin”or “a” =“a” 時, sql 語句恆成立,引數 admin 毫無意義。
防止 sql 注入的方式:
1. 預編譯語句:如, select * from user where username = ?, sql 語句語義不會發生改變, sql 語句中變數用?表示,即使傳遞引數時為“admin or ‘a’ = ‘a’ ”,也會把這整體當做一個字元創去查詢。
2. Mybatis 框架中的 mapper 方式中的 # 也能很大程度的防止 sql 注入($無法防止 sql 注入)。

5. Mysql 效能優化


1、 當只要一行資料時使用 limit 1
查詢時如果已知會得到一條資料,這種情況下加上 limit 1 會增加效能。因為 mysql 資料庫引
擎會在找到一條結果停止搜尋,而不是繼續查詢下一條是否符合標準直到所有記錄查詢完畢。
2、 選擇正確的資料庫引擎
       Mysql 中有兩個引擎 MyISAM 和 InnoDB,每個引擎有利有弊。
       MyISAM 適用於一些大量查詢的應用,但對於有大量寫功能的應用不是很好。甚至你只需要update 一個欄位整個表都會被鎖起來。而別的程序就算是讀操作也不行要等到當前 update 操作完成之後才能繼續進行。另外, MyISAM 對於 select count(*)這類操作是超級快的。
       InnoDB 的趨勢會是一個非常複雜的儲存引擎,對於一些小的應用會比 MyISAM 還慢,但是支援“行鎖”,所以在寫操作比較多的時候會比較優秀。並且,它支援很多的高階應用,例如:事物。

3. 用 not exists 代替 not in
Not exists 用到了連線能夠發揮已經建立好的索引的作用, not in 不能使用索引。 Not in 是最慢的方式要同每條記錄比較,在資料量比較大的操作紅不建議使用這種方式。

4. 對操作符的優化,儘量不採用不利於索引的操作符
如: in not in is null is not null <> 等
某個欄位總要拿來搜尋,為其建立索引:
Mysql 中可以利用 alter table 語句來為表中的欄位新增索引,語法為: alter table 表明
add index (欄位名);


6. 必看 sql 面試題(學生表_課程表_成績表_教師表)


給大家推薦一篇非常好的部落格,該部落格中收集了最常見的 Mysql 常見面試題和筆試題。
部落格連結: http://www.cnblogs.com/qixuejia/p/3637735.html


7. Mysql 資料庫架構圖(2017-11-25-wzz)


MyISAM 和 InnoDB 是最常見的兩種儲存引擎,特點如下。


MyISAM 儲存引擎
MyISAM 是 MySQL 官方提供預設的儲存引擎,其特點是不支援事務、表鎖和全文索引,對於一些 OLAP(聯機分析處理)系統,操作速度快。
每個 MyISAM 在磁碟上儲存成三個檔案。檔名都和表名相同,副檔名分別是.frm(儲存表定義)、.MYD (MYData,儲存資料)、 .MYI (MYIndex,儲存索引)。這裡特別要注意的是 MyISAM 不快取資料檔案,只快取索引檔案。
InnoDB 儲存引擎
InnoDB 儲存引擎支援事務,主要面向 OLTP(聯機事務處理過程)方面的應用,其特點是行鎖設定、支援外來鍵,並支援類似於 Oracle 的非鎖定讀,即預設情況下讀不產生鎖。 InnoDB 將資料放在一個邏輯表空間中(類似 Oracle)。
InnoDB 通過多版本併發控制來獲得高併發性,實現了 ANSI 標準的 4 種隔離級別,預設為 Repeatable,使用一種被稱為 next-key locking 的策略避免幻讀。
對於表中資料的儲存, InnoDB 採用類似 Oracle 索引組織表 Clustered 的方式進行儲存。
InnoDB 儲存引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。但是對比 Myisam 的儲存引擎, InnoDB 寫的處理效率差一些並且會佔用更多的磁碟空間以保留資料和索引。
InnoDB 體系架構


8. Mysql 架構器中各個模組都是什麼?(2017-11-25-wzz)


(1)、連線管理與安全驗證是什麼?
每個客戶端都會建立一個與伺服器連線的執行緒,伺服器會有一個執行緒池來管理這些 連線;如果客戶端需要連線到 MYSQL 資料庫還需要進行驗證,包括使用者名稱、密碼、 主機資訊等。
(2)、解析器是什麼?
解析器的作用主要是分析查詢語句,最終生成解析樹;首先解析器會對查詢語句的語法進行分析,分析語法是否有問題。還有解析器會查詢快取,如果在快取中有對應的語句,就返回查詢結果不進行接下來的優化執行操作。前提是快取中的資料沒有被修改,當然如果被修改了也會被清出快取。
(3)、優化器怎麼用?
優化器的作用主要是對查詢語句進行優化操作,包括選擇合適的索引,資料的讀取方式,包括獲取查詢的開銷資訊,統計資訊等,這也是為什麼圖中會有優化器指向儲存引擎的箭頭。之前在別的文章沒有看到優化器跟儲存引擎之間的關係,在這裡我個人的理解是因為優化器需要通過儲存引擎獲取查詢的大致資料和統計資訊。
(4)、執行器是什麼?
執行器包括執行查詢語句,返回查詢結果,生成執行計劃包括與儲存引擎的一些處理操作。


9. Mysql 儲存引擎有哪些?(2017-11-25-wzz)

(1)、 InnoDB 儲存引擎
InnoDB 是事務型資料庫的首選引擎,支援事務安全表(ACID),支援行鎖定和外來鍵, InnoDB 是預設的 MySQL引擎。
(2)、 MyISAM 儲存引擎
MyISAM 基於 ISAM 儲存引擎,並對其進行擴充套件。它是在 Web、資料倉儲和其他應用環境下最常使用的儲存引擎之一。 MyISAM 擁有較高的插入、查詢速度,但不支援事物。
(3)、 MEMORY 儲存引擎
MEMORY 儲存引擎將表中的資料儲存到記憶體中,未查詢和引用其他表資料提供快速訪問。
(4)、 NDB 儲存引擎
DB 儲存引擎是一個叢集儲存引擎,類似於 Oracle 的 RAC,但它是 Share Nothing 的架構,因此能提供更高級別的高可用性和可擴充套件性。 NDB 的特點是資料全部放在記憶體中,因此通過主鍵查詢非常快。
關於 NDB,有一個問題需要注意,它的連線(join)操作是在 MySQL 資料庫層完成,不是在儲存引擎層完成,這意味著,複雜的 join 操作需要巨大的網路開銷,查詢速度會很慢。
(5) 、 Memory (Heap) 儲存引擎
Memory 儲存引擎(之前稱為 Heap)將表中資料存放在記憶體中,如果資料庫重啟或崩潰,資料丟失,因此它非常適合儲存臨時資料。
(6) 、 Archive 儲存引擎
正如其名稱所示, Archive 非常適合儲存歸檔資料,如日誌資訊。它只支援 INSERT 和 SELECT 操作,其設計的主要目的是提供高速的插入和壓縮功能。
(7) 、 Federated 儲存引擎
Federated 儲存引擎不存放資料,它至少指向一臺遠端 MySQL 資料庫伺服器上的表,非常類似於 Oracle 的透明閘道器。
(8)、 Maria 儲存引擎
Maria 儲存引擎是新開發的引擎,其設計目標是用來取代原有的 MyISAM 儲存引擎,從而成為 MySQL 預設的儲存引擎。
上述引擎中, InnoDB 是事務安全的儲存引擎,設計上借鑑了很多 Oracle 的架構思想,一般而言,在 OLTP應用中, InnoDB 應該作為核心應用表的首先儲存引擎。 InnoDB 是由第三方的 Innobase Oy 公司開發,現已被Oracle 收購,創始人是 Heikki Tuuri,芬蘭赫爾辛基人,和著名的 Linux 創始人 Linus 是校友。


10. MySQL 事務介紹(2017-11-25-wzz)

MySQL 和其它的資料庫產品有一個很大的不同就是事務由儲存引擎所決定,例如 MYISAM,MEMORY,ARCHIVE都不支援事務,事務就是為了解決一組查詢要麼全部執行成功,要麼全部執行失敗。
MySQL 事務預設是採取自動提交的模式,除非顯示開始一個事務。
SHOW VARIABLES LIKE 'AUTOCOMMIT';


修改自動提交模式, 0=OFF,1=ON
注意:修改自動提交對非事務型別的表是無效的,因為它們本身就沒有提交和回滾的概念,還有一些命令是會強制自動提交的,比如 DLL 命令、 lock tables 等。
SET AUTOCOMMIT=OFF 或 SET AUTOCOMMIT=0


10.1 事務的四大特徵是什麼?


資料庫事務 transanction 正確執行的四個基本要素。 ACID,原子性(Atomicity)、一致性(Correspondence)、隔離性(Isolation)、永續性(Durability)。
(1)原子性:整個事務中的所有操作,要麼全部完成,要麼全部不完成,不可能停滯在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
(2)一致性:在事務開始之前和事務結束以後,資料庫的完整性約束沒有被破壞。
(3)隔離性:隔離狀態執行事務,使它們好像是系統在給定時間內執行的唯一操作。如果有兩個事務,執行在相同的時間內,執行 相同的功能,事務的隔離性將確保每一事務在系統中認為只有該事務在使用系統。這種屬性有時稱為序列化,為了防止事務操作間的混淆, 必須序列化或序列化請 求,使得在同一時間僅有一個請求用於同一資料。
(4)永續性:在事務完成以後,該事務所對資料庫所作的更改便持久的儲存在資料庫之中,並不會被回滾。


10.2 Mysql 中四種隔離級別分別是什麼?

 



讀未提交(READ UNCOMMITTED) :未提交讀隔離級別也叫讀髒,就是事務可以讀取其它事務未提交的資料。
讀已提交(READ COMMITTED) :在其它資料庫系統比如 SQL Server 預設的隔離級別就是提交讀,已提交讀隔離級別就是在事務未提交之前所做的修改其它事務是不可見的。
可重複讀(REPEATABLE READ) :保證同一個事務中的多次相同的查詢的結果是一致的,比如一個事務一開始查詢了一條記錄然後過了幾秒鐘又執行了相同的查詢,保證兩次查詢的結果是相同的,可重複讀也是 mysql 的預設隔離級別。
可序列化(SERIALIZABLE) :可序列化就是保證讀取的範圍內沒有新的資料插入,比如事務第一次查詢得到某個範圍的資料,第二次查詢也同樣得到了相同範圍的資料,中間沒有新的資料插入到該範圍中。


11. MySQL 怎麼建立儲存過程(2017-11-25-wzz)


MySQL 儲存過程是從 MySQL5.0 開始增加的新功能。儲存過程的優點有一籮筐。不過最主要的還是執行效率和SQL 程式碼封裝。特別是 SQL 程式碼封裝功能,如果沒有儲存過程,在外部程式訪問資料庫時,要組織很多 SQL 語句。
特別是業務邏輯複雜的時候,一大堆的 SQL 和條件夾雜在程式碼中,讓人不寒而慄。現在有了 MySQL 儲存過程,業務邏輯可以封裝儲存過程中,這樣不僅容易維護,而且執行效率也高。
一、建立 MySQL 儲存過程
下面程式碼建立了一個叫 pr_add 的 MySQL 儲存過程,這個 MySQL 儲存過程有兩個 int 型別的輸入引數“a”、“b”,返回這兩個引數的和。
1) drop procedure if exists pr_add; (備註:如果存在 pr_add 的儲存過程,則先刪掉)
2)計算兩個數之和(備註:實現計算兩個整數之和的功能)
create procedure pr_add ( a int, b int ) begin declare c int;
if a is null then set a = 0;
end if;
if b is null then set b = 0;
end if;
set c = a + b;
select c as sum;
二、 呼叫 MySQL 儲存過程
call pr_add(10, 20);
12. MySQL 觸發器怎麼寫?(2017-11-25-wzz)
MySQL 包含對觸發器的支援。觸發器是一種與表操作有關的資料庫物件,當觸發器所在表上出現指定事件時,將
呼叫該物件,即表的操作事件觸發表上的觸發器的執行。
在 MySQL 中,建立觸發器語法如下:
CREATE TRIGGER trigger_name
trigger_time
trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
其中:
trigger_name:標識觸發器名稱,使用者自行指定;
trigger_time:標識觸發時機,取值為 BEFORE 或 AFTER;
trigger_event:標識觸發事件,取值為 INSERT、 UPDATE 或 DELETE;
tbl_name:標識建立觸發器的表名,即在哪張表上建立觸發器;
trigger_stmt:觸發器程式體,可以是一句 SQL 語句,或者用 BEGIN 和 END 包含的多條語句。
由此可見,可以建立 6 種觸發器,即: BEFORE INSERT、 BEFORE UPDATE、 BEFORE DELETE、 AFTER INSERT、
AFTER UPDATE、 AFTER DELETE。
另外有一個限制是不能同時在一個表上建立 2 個相同型別的觸發器,因此在一個表上最多建立 6 個觸發器。
假設系統中有兩個表:
1)班級表 class(班級號 classID, 班內學生數 stuCount)
2)學生表 student(學號 stuID, 所屬班級號 classID)
要建立觸發器來使班級表中的班內學生數隨著學生的新增自動更新,程式碼如下:
create trigger tri_stuInsert after insert
on student for each row
begin
declare c int;
set c = (select stuCount from class where classID=new.classID);
update class set stuCount = c + 1 where classID = new.classID;
檢視觸發器:
和檢視資料庫(show databases;)查看錶格(show tables;)一樣,檢視觸發器的語法如下:
SHOW TRIGGERS [FROM schema_name];
其中, schema_name 即 Schema 的名稱,在 MySQL 中 Schema 和 Database 是一樣的,也就是說,可以指定資料庫名,這樣就不必先“USE database_name;”了。
刪除觸發器:
和刪除資料庫、刪除表格一樣,刪除觸發器的語法如下:
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
13. MySQL 語句優化(2017-11-26-wzz)
13.1 where 子句中可以對欄位進行 null 值判斷嗎?
可以,比如 select id from t where num is null 這樣的 sql 也是可以的。但是最好不要給資料庫留 NULL,儘可能的使用 NOT NULL 填充資料庫。不要以為 NULL 不需要空間,比如: char(100) 型,在欄位建立時,空間就固定了,不管是否插入值(NULL 也包含在內),都是佔用 100 個字元的空間的,如果是 varchar 這樣的變長欄位, null 不佔用空間。可以在 num 上設定預設值 0,確保表中 num 列沒有 null 值,然後這樣查詢: select id from t where num= 0。

13.2 select * from admin left join log on admin.admin_id = log.admin_id where
log.admin_id>10 如何優化?
優化為: select * from (select * from admin where admin_id>10) T1 lef join log on T1.admin_id =log.admin_id。
使用 JOIN 時候,應該用小的結果驅動大的結果(left join 左邊表結果儘量小如果有條件應該放到左邊先處理,right join 同理反向),同時儘量把牽涉到多表聯合的查詢拆分多個 query(多個連表查詢效率低,容易到之後鎖表和阻塞)。
13.3 limit 的基數比較大時使用 between
例如: select * from admin order by admin_id limit 100000,10
優化為: select * from admin where admin_id between 100000 and 100010 order by admin_id。
13.4 儘量避免在列上做運算,這樣導致索引失效
例如: select * from admin where year(admin_time)>2014
優化為: select * from admin where admin_time> '2014-01-01′


14. MySQL 中文亂碼問題完美解決方案(2017-12-07-lwl)


解決亂碼的核心思想是統一編碼。我們在使用 MySQL 建資料庫和建表時應儘量使用統一的編碼,強烈推薦的是 utf8 編碼,因為該編碼幾乎可以相容世界上所有的字元。
資料庫在安裝的時候可以設定預設編碼,在安裝時就一定要設定為 utf8 編碼。設定之後再建立的資料庫和表如果不指定編碼,預設都會使用 utf8 編碼,省去了很多麻煩。
資料庫軟體安裝好之後可以通過如下命令檢視預設編碼:
1、 查詢資料庫軟體使用的預設編碼格式
show variables like “%colla%”;
show varables like “%char%”
其中 collation,代表了字串排序(比較)的規則,如果值是 utf8_general_ci,代表使用 utf8 字符集大小寫
不敏感的自然方式比較。
如果 character_set 的值不為 utf8,那麼可以使用如下命令修改為 utf8。
2、 修改資料庫預設編碼為 utf8
SET character_set_client='utf8';
SET character_set_connection='utf8';
SET character_set_results='utf8';
如果不想設定資料庫軟體的全域性預設編碼,也可以單獨修改或者設定某個具體資料庫的編碼也可以單獨修改或設定某個資料庫中某個表的編碼。
3、 建立資料庫的時候指定使用 utf8 編碼
CREATE DATABASE `test`
CHARACTER SET 'utf8'
COLLATE 'utf8_general_ci';
4、 建立表的時候指定使用 utf8 編碼
CREATE TABLE `database_user` (
`ID` varchar(40) NOT NULL default '',
`UserID` varchar(40) NOT NULL default '',
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
如果資料庫已經建立好了,可以使用 show database 資料庫名;和 show create table 表名;檢視一下資料庫和表的字符集是否為 utf8 , 如果不是則在命令列下面可以用如下命令,將資料庫和表編碼修改為 utf8.
5、 修改具體某資料庫或表的編碼
ALTER DATABASE `db_name` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE `tb_name` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
15. 如何提高 MySQL 的安全性(2017-12-8-lwl)
1.如果 MySQL 客戶端和伺服器端的連線需要跨越並通過不可信任的網路,那麼需要使用 ssh 隧道來加密該連線的通訊。
2.使用 set password 語句來修改使用者的密碼,先“mysql -u root”登陸資料庫系統,然後“mysql> update mysql.user set password=password(’ newpwd’ )”,最後執行“flush privileges”。
3.MySQL 需要提防的攻擊有,防偷聽、篡改、回放、拒絕服務等,不涉及可用性和容錯方面。對所有的連線、查詢、其他操作使用基於 ACL(ACL(訪問控制列表)是一種路由器配置和控制網路訪問的一種有力的工具,它可控制路由器應該允許或拒絕資料包通過,可監控流量,可自上向下檢查網路的安全性,可檢查和過濾資料和限制不必要的路由更新,因此讓網路資源節約成本的 ACL 配置技術在生活中越來越廣泛應用。) 即訪問控制列表的安全措施來完成。
4.設定除了 root 使用者外的其他任何使用者不允許訪問 mysql 主資料庫中的 user 表;
5.使用 grant 和 revoke 語句來進行使用者訪問控制的工作;
6.不要使用明文密碼,而是使用 md5()和 sha1()等單向的哈系函式來設定密碼;
7.不要選用字典中的字來做密碼;
8.採用防火牆可以去掉 50%的外部危險,讓資料庫系統躲在防火牆後面工作,或放置在 DMZ(DMZ 是英文“demilitarized zone”的縮寫,隔離區,它是為了解決安裝防火牆後外部網路的訪問使用者不能訪問內部網路伺服器的問題,而設立的一個非安全系統與安全系統之間的緩衝區。) 區域中;
9.從因特網上用 nmap 來掃描 3306 埠,也可用 telnet server_host 3306 的方法測試,不允許從非信任網路中訪問資料庫伺服器的 3306 號 tcp 埠,需要在防火牆或路由器上做設定;
10.服務端要對 SQL 進行預編譯,避免 SQL 注入攻擊, 例如 where id=234,別人卻輸入 where id=234 or 1=1。
11.在傳遞資料給 mysql 時檢查一下大小;
12.應用程式連線到資料庫時應該使用一般的使用者帳號,開放少數必要的許可權給該使用者;
13.學會使用 tcpdump 和 strings 工具來檢視傳輸資料的安全性,例如 tcpdump -l -i eth0 -w -src or dst port 3306 strings。以普通使用者來啟動 mysql 資料庫服務;
14.確信在 mysql 目錄中只有啟動資料庫服務的使用者才可以對檔案有讀和寫的許可權;
15.不許將 process 或 super 許可權付給非管理使用者,該 mysqladmin processlist 可以列舉出當前執行的查詢文字;super 許可權可用於切斷客戶端連線、改變伺服器執行引數狀態、控制拷貝複製資料庫的伺服器;
16.如果不相信 dns 服務公司的服務,可以在主機名稱允許表中只設置 ip 數字地址;
17.使用 max_user_connections 變數來使 mysqld 服務程序,對一個指定帳戶限定連線數;
18.grant 語句也支援資源控制選項;
19.啟動 mysqld 服務程序的安全選項開關, –local-infile=0 或 1, 若是 0 則客戶端程式就無法使用 local load data 了,賦權的一個例子 grant insert(user) on mysql.user to ‘user_name’ @'host_name’ ;若使用–skip-granttables 系統將對任何使用者的訪問不做任何訪問控制,但可以用 mysqladmin flush-privileges 或 mysqladmin reload 來開啟訪問控制;預設情況是 show databases 語句對所有使用者開放,可以用–skip-show-databases 來關閉掉。
23.碰到 error 1045(28000) access denied for user ‘root’ @'localhost’ (using password:no)錯誤時,你需要重 新 設 置 密 碼 , 具 體 方 法 是 : 先 用 – skip-grant-tables 參 數 啟 動 mysqld , 然 後 執 行 mysql -u root mysql,mysql>update user set password=password(’ newpassword’ ) where user=’ root’ ;mysql>flush privileges;,最後重新啟動 mysql 就可以了。


二、 Oracle


1. 什麼是儲存過程,使用儲存過程的好處?(2017-11-25-wzz)


儲存過程(Stored Procedure )是一組為了完成特定功能的 SQL 語句集,經編譯後儲存在資料庫中。使用者
通過指定儲存過程的名字並給出引數(如果該儲存過程帶有引數)來執行它。儲存過程是資料庫中的一個重要對
象,任何一個設計良好的資料庫應用程式都應該用到儲存過程。
優點:
(1)允許模組化程式設計,就是說只需要建立一次過程,以後在程式中就可以呼叫該過程任意次。
(2)允許更快執行,如果某操作需要執行大量 SQL 語句或重複執行,儲存過程比 SQL 語句執行的要快。
(3)減少網路流量,例如一個需要數百行的 SQL 程式碼的操作有一條執行語句完成,不需要在網路中傳送數百行程式碼。
(4) 更好的安全機制,對於沒有許可權執行儲存過程的使用者,也可授權他們執行儲存過程。
儲存過程的具體使用詳見: http://www.cnblogs.com/yank/p/4235609.html


2. Oracle 儲存過程怎麼建立?(2017-11-25-wzz)


儲存過程建立語法:
create or replace procedure 儲存過程名(param1 in type, param2 out type)
as
變數 1 型別(值範圍) ;
變數 2 型別(值範圍) ;
Begin
Select count(*) into 變數 1 from 表 A where 列名=param1;
If (判斷條件) then
Select 列名 into 變數 2 from 表 A where 列名=param1;
Dbms_output。 Put_line(‘列印資訊’ );
Elsif (判斷條件) then
Dbms_output。 Put_line(‘列印資訊’ );
Else
Raise 異常名(NO_DATA_FOUND) ;
End if;
Exception
When others then
Rollback;
End;
注意事項:
1. 儲存過程引數不帶取值範圍, in 表示傳入, out 表示輸出
2. 變數帶取值範圍,後面接分號
3. 在判斷語句前最好先用 count(*)函式判斷是否存在該條操作記錄
4. 用 select 。。。 into。。。給變數賦值
5. 在程式碼中拋異常用 raise+異常名


3. 如何使用 Oracle 的遊標?(2017-11-25-wzz)


參考部落格: https://www.cnblogs.com/sc-xx/archive/2011/12/03/2275084.html
(1)、 Oracle 中的遊標分為顯示遊標和隱式遊標
(2)、顯示遊標是用 cursor...is 命令定義的遊標,它可以對查詢語句(select)返回的多條記錄進行處理;
(3)、隱式遊標是在執行插入 (insert)、刪除(delete)、修改(update) 和返回單條記錄的查詢(select)語句時
由 PL/SQL 自動定義的。
(4)、顯式遊標的操作:開啟遊標、操作遊標、關閉遊標; PL/SQL 隱式地開啟 SQL 遊標,並在它內部處理 SQL
語句,然後關閉它。


4. Oracle 中字串用什麼連線?(2017-11-25-wzz)


Oracle 中使用 || 這個符號連線字串 如 ‘abc’ || ‘d’ 的結果是 abcd。


5. Oracle 中是如何進行分頁查詢的?(2017-11-25-wzz)


Oracle 中使用 rownum 來進行分頁, 這個是效率最好的分頁方法, hibernate 也是使用 rownum 來進行 Oralce分頁的
select * from
( select rownum r,a from tabName where rownum <= 20 )
where r > 10


6. 儲存過程和儲存函式的特點和區別?(2017-11-25-wzz)


特點:
(1) 、一般來說,儲存過程實現的功能要複雜一點,而函式的實現的功能針對性比較強。
(2) 、對於儲存過程來說可以返回引數,而函式只能返回值或者表物件。
(3) 、儲存過程一般是作為一個獨立的部分來執行,而函式可以作為查詢語句的一個部分來呼叫,由於函式可以返回一個表物件,因此它可以在查詢語句中位於 FROM 關鍵字的後面。
區別:
(1)、函式必須有返回值,而過程沒有.
(2)、函式可以單獨執行.而過程必須通過 execute 執行.
(3)、函式可以嵌入到 SQL 語句中執行.而過程不行.
其實我們可以將比較複雜的查詢寫成函式.然後到儲存過程中去呼叫這些函式.


7. 儲存過程與 SQL 的對比? (2017-11-21-gxb)


優勢:
1、提高效能
SQL 語句在建立過程時進行分析和編譯。 儲存過程是預編譯的,在首次執行一個儲存過程時,查詢優化器對其進行分析、優化,並給出最終被存在系統表中的儲存計劃,這樣,在執行過程時便可節省此開銷。
2、降低網路開銷
儲存過程呼叫時只需用提供儲存過程名和必要的引數資訊,從而可降低網路的流量。
3、便於進行程式碼移植
資料庫專業人員可以隨時對儲存過程進行修改,但對應用程式原始碼卻毫無影響,從而極大的提高了程式的可移植性。
4、更強的安全性
1)系統管理員可以對執行的某一個儲存過程進行許可權限制,避免非授權使用者對資料的訪問
2)在通過網路呼叫過程時,只有對執行過程的呼叫是可見的。 因此,惡意使用者無法看到表和資料庫物件名稱、嵌入自己的 Transact-SQL 語句或搜尋關鍵資料。
3)使用過程引數有助於避免 SQL 注入攻擊。 因為引數輸入被視作文字值而非可執行程式碼,所以,攻擊者將命令插入過程內的 Transact-SQL 語句並損害安全性將更為困難。
4)可以對過程進行加密,這有助於對原始碼進行模糊處理。
劣勢:
1、儲存過程需要專門的資料庫開發人員進行維護,但實際情況是,往往由程式開發員人員兼職
2、設計邏輯變更,修改儲存過程沒有 SQL 靈活


8. 你覺得儲存過程和 SQL 語句該使用哪個? (2017-11-21-gxb)


1、在一些高效率或者規範性要求比較高的專案,建議採用儲存過程
2、對於一般專案建議採用引數化命令方式,是儲存過程與 SQL 語句一種折中的方式
3、對於一些演算法要求比較高,涉及多條資料邏輯,建議採用儲存過程


9. 觸發器的作用有哪些? (2017-11-21-gxb)


1)觸發器可通過資料庫中的相關表實現級聯更改;通過級聯引用完整性約束可以更有效地執行這些更改。
2)觸發器可以強制比用 CHECK 約束定義的約束更為複雜的約束。與 CHECK 約束不同,觸發器可以引用其它
表中的列。例如,觸發器可以使用另一個表中的 SELECT 比較插入或更新的資料,以及執行其它操作,如修改資料或顯示使用者定義錯誤資訊。
3)觸發器還可以強制執行業務規則
4)觸發器也可以評估資料修改前後的表狀態,並根據其差異采取對策。
參考資料: http://www.cnblogs.com/yank/p/4193820.html


10. 在千萬級的資料庫查詢中,如何提高效率?(2017-11-23-gxb)


1)資料庫設計方面
a. 對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
b. 應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如: select id from t where num is null 可以在 num 上設定預設值 0,確保表中 num 列沒有 null 值,然後這樣查詢: select id from t where num=0
c. 並不是所有索引對查詢都有效, SQL 是根據表中資料來進行查詢優化的,當索引列有大量資料重複時,查詢可能不會去利用索引,如一表中有欄位 sex, male、 female 幾乎各一半,那麼即使在 sex 上建了索引也對查詢效率起不了作用。
d. 索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過 6 個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
e. 應儘可能的避免更新索引資料列,因為索引資料列的順序就是表記錄的物理儲存順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應用系統需要頻繁更新索引資料列,那麼需要考慮是否應將該索引建為索引。
f. 儘量使用數字型欄位,若只含數值資訊的欄位儘量不要設計為字元型,這會降低查詢和連線的效能,並會增加儲存開銷。這是因為引擎在處理查詢和連線時會逐個比較字串中每一個字元,而對於數字型而言只需要比較一次就夠了。
g. 儘可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長欄位儲存空間小,可以節省儲存空間,其次對於查詢來說,在一個相對較小的欄位內搜尋效率顯然要高些。
h. 儘量使用表變數來代替臨時表。如果表變數包含大量資料,請注意索引非常有限(只有主鍵索引)。
i. 避免頻繁建立和刪除臨時表,以減少系統表資源的消耗。
j. 臨時表並不是不可使用,適當地使用它們可以使某些例程更有效,例如,當需要重複引用大型表或常用表中的某個資料集時。但是,對於一次性事件,最好使用匯出表。
k. 在新建臨時表時,如果一次性插入資料量很大,那麼可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果資料量不大,為了緩和系統表的資源,應先 create table,然後 insert。
l. 如果使用到了臨時表,在儲存過程的最後務必將所有的臨時表顯式刪除,先 truncate table ,然後 drop table ,這樣可以避免系統表的較長時間鎖定。
2)SQL 語句方面
a. 應儘量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。
b. 應儘量避免在 where 子句中使用 or 來連線條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or num=20 可以這樣查詢: select id from t where num=10 union all
select id from t where num=20
c. in 和 not in 也要慎用,否則會導致全表掃描,如: select id from t where num in(1,2,3) 對於連續的
數值,能用 between 就不要用 in 了: select id from t where num between 1 and 3
d. 下面的查詢也將導致全表掃描: select id from t where name like ‘%abc%’
e. 如果在 where 子句中使用引數,也會導致全表掃描。因為 SQL 只有在執行時才會解析區域性變數,但優化
程式不能將訪問計劃的選擇推遲到執行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變數的
值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描: select id from t where
[email protected] 可以改為強制查詢使用索引: select id from t with(index(索引名)) where [email protected]
f. 應儘量避免在 where 子句中對欄位進行表示式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where num/2=100 應改為: select id from t where num=100*2
g. 應儘量避免在where子句中對欄位進行函式操作,這將導致引擎放棄使用索引而進行全表掃描。如: select
id from t where substring(name,1,3)= ‘abc ’ – name 以 abc 開 頭 的 id select id from t where
datediff(day,createdate,’ 2005-11-30′)=0–‘2005-11-30’生成的 id 應改為: select id from t where name
like ‘abc%’ select id from t where createdate>=’ 2005-11-30′ and createdate<’ 2005-12-1′
h. 不要在 where 子句中的“=”左邊進行函式、算術運算或其他表示式運算,否則系統將可能無法正確使用
索引。
i. 不要寫一些沒有意義的查詢,如需要生成一個空表結構: select col1,col2 into #t from t where 1=0 這
類程式碼不會返回任何結果集,但是會消耗系統資源的,應改成這樣: create table #t(…)
j. 很多時候用 exists 代替 in 是一個好的選擇: select num from a where num in(select num from b)
用下面的語句替換: select num from a where exists(select 1 from b where num=a.num)
k. 任何地方都不要使用 select * from t ,用具體的欄位列表代替“*”,不要返回用不到的任何欄位。
l. 儘量避免使用遊標,因為遊標的效率較差,如果遊標操作的資料超過 1 萬行,那麼就應該考慮改寫。
m. 儘量避免向客戶端返回大資料量,若資料量過大,應該考慮相應需求是否合理。
n. 儘量避免大事務操作,提高系統併發能力。
3)java 方面:重點內容
a.儘可能的少造物件。
b.合理擺正系統設計的位置。大量資料操作,和少量資料操作一定是分開的。大量的資料操作,肯定不是 ORM
框架搞定的。,
c.使用 jDBC 連結資料庫操作資料
d.控制好記憶體,讓資料流起來,而不是全部讀到記憶體再處理,而是邊讀取邊處理;
e.合理利用記憶體,有的資料要快取