5.1.7.1 事務的四大特性是什么?
⑴ 原子性(Atomicity)
原子性是指事務包含的所有操作要么全部成功,要么全部失敗回滾。
⑵ 一致性(Consistency)
一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處於一致性狀態。
⑶ 隔離性(Isolation)
隔離性是當多個用戶並發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個並發事務之間要相互隔離。
⑷ 持久性(Durability)
持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。
5.1.7.2 共享鎖和排斥鎖的含義以及用途?
共享鎖又稱讀鎖,若事務T對數據對象A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。
排他鎖又稱寫鎖。若事務T對數據對象A加上X鎖,事務T可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到T釋放A上的鎖。這保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A。排他鎖很好理解,是自己獨占資源。
5.1.7.3 樂觀鎖和悲觀鎖的含義以及用途?
樂觀鎖總是認為不會產生並發問題,每次去取數據的時候總認為不會有其他線程對數據進行修改,因此不會上鎖,但是在更新時會判斷其他線程在這之前有沒有對數據進行修改,一般會使用版本號機制或CAS操作實現。
悲觀鎖總是假設最壞的情況,每次取數據時都認為其他線程會修改,所以都會加鎖(讀鎖、寫鎖、行鎖等),當其他線程想要訪問數據時,都需要阻塞掛起。可以依靠數據庫實現,如行鎖、讀鎖和寫鎖等,都是在操作之前加鎖,在Java中,synchronized的思想也是悲觀鎖。
5.1.7.4 內連接、外連接、全連接和左連接的語法以及用途。
1、內聯接使用比較運算符根據每個表共有的列的值匹配兩個表中的行。例如,檢索 students和courses表中學生標識號相同的所有行。
2、外聯接。外聯接可以是左向外聯接、右向外聯接或完整外部聯接。在 FROM子句中指定外聯接時,可以由下列幾組關鍵字中的一組指定:
3左連接和左外連接
左向外聯接的結果集包括 LEFT OUTER子句中指定的左表的所有行,而不僅僅是聯接列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關聯的結果集行中右表的所有選擇列表列均為空值。
FULL JOIN 或 FULL OUTER JOIN,完整外部聯接返回左表和右表中的所有行。當某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結果集行包含基表的數據值。
4 交叉聯接 交叉聯接返回左表中的所有行,左表中的每一行與右表中的所有行組合。交叉聯接也稱作笛卡爾積。
5.1.7.5 第一、第二和第三范式的含義以及反范式的含義。你在建表時,用到的是哪種范式?
“設計過表”標志着一個初級程序員開始成熟,這里我姑且不論數據表的業務邏輯,一般的公司是怎么“合理地設計數據表”?其實在設計一個商業項目的數據表時,離不開“業務需求”。
第一,如果在設計的時候,已經明確地知道這個系統的數據量不會太大,比如一個中學的圖書管理系統,最多有10萬條書本的數據,過去一個月里借閱記錄不會超過1萬條,也就是說表之間的關聯代價不會太高,那么用“三范式”的原則是必須的。畢竟三范式能避免數據冗余帶來的更新插入上“需要同時多表里相同字段”的麻煩。
第二,如果表的數據量很大,比如我剛才舉的在線購物網站的例子,我們可能就需要冗余數據。在訂單流水表里,同時放入用戶郵件地址和商品名的字段。
在得到“免去連接操作”的好處同時,這樣做也是有代價的,比如用戶一旦更新了郵件地址,那么我們就需要同時在會員表和訂單流水表里修改該字段,這就是冗余帶來的后果。
除去一些技術點的描述,本篇更想告訴大家的是,你不僅需要掌握諸如“連接”和“范式”之類的技術,你更該從業務角度,從權衡各種“建表代價”,從而挑選一種最符合本項目的解決方案。
我在以往的面試官的經驗里,有過兩個案例,第一位他簡歷上項目很多,也具有1年相關經驗,但他說建數據表要符合“三范式”,同時不清楚左連接,內連接等的具體做法,經過我細問,原來他在簡歷上的項目是自己在學習中搭建的,並非商業項目。
第二位,他雖然工作經驗只有半年,但把“建表需要權衡數據冗余和連接代價”的意思描述了一下。這樣至少在數據庫層面,第二位的得分就要比第一位要高。
5.1.7.6 什么是SQL注入?它有什么后果?一般怎么預防?
我們一般用如下的SQL來驗證身份:
Select userName from users where username = ‘輸入的用戶名’ and pwd = ‘輸入的密碼’
一般來說,如果用戶名和密碼不匹配,就無法通過驗證,但有人可以在User Name里輸入1,在User Passwor部分輸入
1’ and pwd = ‘1’ or ‘1’=’1
那么整個SQL語句就會變成
Select userName from users where username = ‘1’ and pwd = ‘1’ or ‘1’=’1’
這樣就能繞過驗證。
而處理對象PreparedStatement能有效防止這個現象,因為一個?就是一個占位符,無法擴展。以此能防止SQL注入。