java面試④資料庫部分
2.3.1 資料庫的分類及常用的資料庫
資料庫分為:關係型資料庫和非關係型資料庫
關係資料庫:mysql,oracle,sqlServer
非關係型:redis,mongoDB
2.3.2 簡單介紹一下關係資料庫三正規化
正規化就是規範,就是關係型資料庫在設定表時,要遵循的三個規範。
要滿足第二正規化必須先滿足第一正規化,要滿足第三正規化必須先滿足第二正規化。
所謂第一正規化(1NF)是指資料庫表的每一列都是不可分割的基本資料項,同一列中不能有多個值,即實體列中的某個屬性不能有多個值或者不能有重複的屬性,列資料的不可分割。
二正規化(2NF)要求資料庫表中的每個行必須可以被唯一的區分,為實現區分通常需要為表加上一列,以儲存各個例項的唯一標識。
滿足第三正規化(3NF)必須先滿足第二正規化,簡而言之,第三正規化要求一個數據庫表中不包含已在其他表中已包含的非關鍵字資訊。(外來鍵)
反三正規化,有的時候為了效率,可以設定重複或者可以推導的欄位,訂單(總價)和訂單項(單價)
2.3.3 事務的四個基本特徵
事物是併發控制的單位,是使用者定義的一個操作序列,這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。
一個轉賬必須A帳號扣錢成功,B帳號加錢成功,才算真正的轉賬成功。
事務必須滿足四大特徵:
原子性:表示事務內操作不可分割,要麼成功,要麼都失敗
一致性:要麼成功,要麼失敗,後面的失敗了要對前面的操作進行回滾
隔離性:一個事務開始後,不能與其他事務干擾
永續性(持續性):表示事務開始了,就不能終止。
2.3.4 mysql資料庫的預設的最大連線數?
為什麼需要最大連線數?特定伺服器上面的資料庫只能支援一定數目同時連線,這時候需要我們設定最大連線數(最多同時服務多少連線),在資料庫安裝時都會有一個預設的最大連線數。最大連線數為100.
max_connections=100;
2.3.5 說一下mysql的分頁?Oracle的分頁?
為什麼需要分頁?在很多資料庫時,不可能完全顯示資料,進行分段顯示。
mysql是使用關鍵字limit 來進行分頁的,limit offset,size 表示從多少索引取多少位。
Oracle的分頁。大部分情況下,我們是記不住了,說思路,要使用三層巢狀查詢
oracle的分頁優點記不住了,只記得一些大概,是使用類三層巢狀查詢,如果在工作中使用了,可以到原來的專案中拷貝或上網查詢。
2.3.6 簡單講一下資料庫的觸發器的使用場景
觸發器,需要觸發條件,當條件滿足以後做什麼操作。
觸發器用處還是很多的,比如校內網、Facebook,你發一個日誌,自動通知好友,其實就是在增加日誌做一個後觸發,再向通知表中寫入條目,因為觸發效率高,而UCH沒有用觸發器,效率和資料處理能力很低。
每插入一個帖子,都希望將版面表中的最後發帖時間,帖子數字段進行同步更新,用觸發器做效率更高。
關鍵字:trigger
2.3.7 簡單講一下資料庫的儲存過程的使用場景?
資料庫儲存過程具有如下優點:
1)儲存過程只在建立時進行編譯,以後每次執行儲存過程都不需要重新編譯,而一般SQL語句每執行一次就編譯一次,因此使用儲存過程可以大大提高資料執行數度,
2)通常,複雜的業務邏輯需要多條SQL語句,這些語句要分別地從客戶端傳送到伺服器,當客戶端和伺服器之間的操作很多時,將產生大量的網路傳輸,如果將這些操作放在一個儲存過程中,那麼客戶機和伺服器之間的網路傳輸就會大大減少,降低類網路負載,
3)儲存過程建立一次便可以重複使用,從而可以減少資料庫開發人員的工作量,
4)安全性高,儲存過程可以遮蔽對底層資料庫物件的直接訪問,使用exectu許可權呼叫儲存過程,無需擁有訪問底層資料庫物件的顯示許可權。
定義儲存過程:
create procedure studen(name varchar(50),age int,id in);
begin
insert into student values('lisi',22,1);
select name,age from student;
end;
呼叫儲存過程
call student();
select
2.3.8 用jdbc怎麼呼叫儲存過程?
載入驅動
獲取連線
設定引數
執行
釋放連線
public static void main(String[]args) { Connection conn = null; CallableStatement st = null; try { //這裡最好不要這麼幹,因為驅動名寫死在程式中了 Class.forName("com.mysql.jdbc.Driver"); //實際專案中,這裡應用DataSource資料,如果用框架 //這個資料來源不需要我們編碼建立,我們只需DataSourceds=context.lookup(); //conn = ds.getConnection(); conn = DriverManager.getConnection("jdbc:mysql:///test","root","root"); st = conn.prepareCall("{call insert_Student(?,?,?)}"); st.registerOutParameter(3, Types.INTEGER); st.setString(1, "laowang"); st.setInt(2, 25); st.execute(); //get第幾個,不同的資料庫不一樣,建議不寫 System.out.println(st.getString(3)); } catch(Exception e){ e.printStackTrace(); } } |
2.3.9 常用的SQL
略
2.3.10 簡單說一下你對jdbc的理解
Java database connection java資料庫連線,資料庫關係系統(mysql,oracle)是很多,每個資料庫管理系統支援的命令是不一樣的,
java只定義介面,讓資料庫廠商自己實現介面,對於我們而言只需要匯入對應廠商開發的實現介面,然後以介面方式進行呼叫(mysql+mysql驅動+jdbc)
2.3.11 寫一個簡單的jdbc的程式,寫一個訪問oracle資料庫的jdbc程式?
載入驅動(oracle.jdbc.driver.OracleDriver)
獲取連線(DriverManager.getConnection(url, user, password))
設定引數
Statement st = conn.createStatement();
st.setXXX(index,value)
執行(execute)
釋放連線(是否連線要從小到大,必須放到finally)
2.3.12 JDBC中的PreparedStatement相比Statement的好處
大多數時候都使用PreparedStatement代替
1)PreparedStatement是預編譯的,比Statement速度快
2)程式碼的可讀性和可維護性
雖然PreparedStatement來代替Statement會使程式碼多出幾行,但這樣的程式碼無論從可讀性還是可維護性上來說,都比直接用Statement的程式碼高很多檔次。
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
不用我多說,對於第一種方法.別說其他人去讀你的程式碼,就是你自己過一段時間再去讀,都會覺得傷心.
3)安全性
PreparedStatement可以防止SQL注入攻擊,而Statement卻不能,比如:
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
如果我們把[' or '1' = '1]作為varpasswd傳入進來.使用者名稱隨意,看看會成為什麼?
select * from tb_name = '隨意' and passwd = '' or '1' = '1';
因為'1'='1'肯定成立,所以可以任何通過驗證.更有甚者:
把[';drop table tb_name;]作為varpasswd傳入進來,則:
select * from tb_name = '隨意' and passwd = '';drop table tb_name;有些資料庫是不會讓你成功的,但也有很多資料庫就可以使這些語句得到執行.
而 如果你使用預編譯語句.你傳入的任何內容就不會和原來的語句發生任何匹配的關係.(前提是資料庫本身支援預編譯,但上前可能沒有什麼服務端資料庫不支援編 譯了,只有少數的桌面資料庫,就是直接檔案訪問的那些)只要全使用預編譯語句,你就用不著對傳入的資料做任何過慮.而如果使用普通的statement, 有可能要對drop,;等做費盡心機的判斷和過慮.
2.3.13 資料庫連線池的作用
1)限定資料庫的個數,不會導致由於資料庫過多導致系統執行緩慢或者崩潰。
2)資料庫連線池不需要每次建立或者銷燬,節約資源。
3)資料庫連線池不需要每次建立,響應時間快。