JAVA經典面試題-數據庫

1. 存儲過程的作用?

存儲過程可以使得對數據庫的管理、以及顯示關於數據庫及其用戶信息的工作容易得多。存儲過程是 SQL 語句和可選控制流語句的預編譯集合, 以一個名稱存儲並作爲一個單元處理。存儲過程存儲在數據庫內,可由應用程序通過一個調用執行,

而且允許用戶聲明變量、有條件執行以及其它強大的編程功能。 

存儲過程可包含程序流、邏輯以及對數據庫的查詢。它們可以接受參數、輸出參數、返回單個或多個結果集以及返回值。 

可以出於任何使用 SQL 語句的目的來使用存儲過程,它具有以下優點: 

可以在單個存儲過程中執行一系列 SQL 語句。 

可以從自己的存儲過程內引用其它存儲過程,這可以簡化一系列複雜語句。 

存儲過程在創建時即在服務器上進行編譯,所以執行起來比單個 SQL 語句快。

2. sqlserveroracle數據庫的性能優化

3.1選用適合的ORACLE優化器

        ORACLE的優化器共有3:  

     a. RULE (基於規則) b. COST (基於成本) c. CHOOSE (選擇性)

       在缺省情況下,ORACLE採用CHOOSE 優化器爲了避免那些不必要的全表掃描(full table scan) , 你必須儘量避免使用CHOOSE優化器,而直接採用基於規則或者基於成本的優化器.

訪問Table的方式

3.2ORACLE 採用兩種訪問表中記錄的方式

     a. 全表掃描                                                    

        全表掃描就是順序地訪問表中每條記錄. ORACLE採用一次讀入多個數據塊(database block)的方式優化全表掃描.

     b. 通過ROWID訪問表                                         

          你可以採用基於ROWID的訪問方式情況,提高訪問表的效率,RowId包含了表中記錄的物理位置信息.ORACLE採用索引(INDEX)實現了數據和存放數據的物理位置(RowId)之間的聯繫。 通常索引提供了快速訪問ROWID的方法,因此那些基於索引列的查詢就可以得到性能上的提高.

3.3. 選擇最有效率的表名順序(只在基於規則的優化器中有效

3.4. WHERE子句中的連接順序.

       ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾.

3.5. SELECT子句中避免使用 ‘ * ‘                           

       當你想在SELECT子句中列出所有的COLUMN,使用動態SQL列引用 ‘*’ 是一個方便的方法.不幸的是,這是一個非常低效的方法實際上,ORACLE在解析的過程中會將’*’ 依次轉換成所有的列名這個工作是通過查詢數據字典完成的這意味着將耗費更多的時間

3.6. 減少訪問數據庫的次數

       當執行每條SQL語句時, ORACLE在內部執行了許多工作解析SQL語句估算索引的利用率綁定變量 讀數據塊等等由此可見減少訪問數據庫的次數 就能實際上減少 ORACLE的工作量.

3.7. 整合簡單,無關聯的數據庫訪問 

       如果你有幾個簡單的數據庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關係)

3.8. 使用表的別名(Alias) 

       當在SQL語句中連接多個表時請使用表的別名並把別名前綴於每個Column.這樣一來,就可以減少解析的時間並減少那些由Column歧義引起的語法錯誤.

3.9. 對經常要查詢的字段可以建立一個視圖

3.10. 在表中的某個字段上建立索引,可以提高檢索速度。

3. 模糊查詢可以用索引嗎?

     (1)如果模糊查詢是下邊這個樣子:where a like '*****%',就可以用索引;

       如果模糊查詢是 where a like '%****'的形式,就不能使用索引!

(2)建全文索引後使用constain

4. sql的關鍵字及其一些函數

    sql關鍵字:all, alter, as, asc, container, create, delete, desc, drop, first, from, in, index,

               insert, into, join, last, on, schema, select, selectschema, selectsecurity, table,

               to, update, updateidentity, updateowner, updatesecurity, user, with;

    函數:Avg(), Count(), First(), Last(), Max(), Min(), Sum(),StDev()

          StDevP()[StDev,StDevP返回總體或總體樣本的標準偏差的估計值], Var(), VarP()[Var,VarP返回一個總體或總體樣本的方差的估計值

          

ODBC標量函數:

    1. 字符串函數 ASCII   LENGTH  RTRIM   CHAR  LOCATE   SPACE CONCAT    LTRIM  SUBSTRING  LCASE  RIGHT  UCASE   LEFT

    2. 數字函數 ABS  FLOOR  SIN  ATAN  LOG  SQRT CEILING   POWER      TAN          COS  RAND   MOD  EXP  SIGN 

    3. 時間和日期函數  CURDATE   DAYOFYEAR  MONTH  CURTIME   YEAR        WEEK  NOW  HOUR QUARTER  DAYOFMONTH   MINUTE    MONTHNAME   DAYOFWEEK   SECOND    DAYNAME 

    4. 數據類型變換    CONVERT

ORACLE

5. Oracle中的事務

Oracle在缺省情況下任何一個DML語句都會開始一個事務,直到用戶發出CommitRollback操作,這個事務纔會結束。在Oracle中,執行DDL語句(Create TableCreate View)時,會在執行之前自動發出一個Commit命令,並在隨後發出一個Commit或者Rollback命令。

(1) 提交事務 

提交一事務,即將在事務中由SQL語句所執行的改變永久化。在提交前,ORACLE已有下列情況: 
   在SGA的回滾段緩衝區已生成回滾段記錄,回滾信息包含有所修改值的老值。 
   在SGA的日誌緩衝區已生成日誌項。這些改變在事務提交前可進入磁盤。 
   對SGA的數據庫緩衝區已作修改,這些修改在事務真正提交之前可進入磁盤。 
   在事務提交之後,有下列情況: 
   對於與回滾段相關的內部事務表記錄提交事務,並賦給一個相應的唯一系統修改號(SCN),記錄在表中。 
   在SGA的日誌緩衝區中日誌項由LGWR進程寫入到在線日誌文件, 這是構成提交事務的原子事務。 
   在行上和表上的封鎖被釋放。 
   該事務標誌爲完成 。 
   注意:對於提交事務的數據修改不必由DBWR後臺進程立即寫入數據文件,可繼續存儲在SGA的數據庫緩衝區中,在最有效時將其寫入數據文件。

(2) 回滾事務 

 回滾事務的含義是撤消未提交事務中的SQL語句所作的對數據修改。ORALCE允許撤消未提交的整個事務,也允許撤消部分。 
   在回滾整個事務(沒有引用保留點)時,有下列情況: 
   在事務中所有SQL語句作的全部修改,利用相應的回滾段被撤消。 
   所有數據的事務封鎖被釋放。 
   事務結束。 
   當事務回滾到一保留點(具有SAVEPOINT)時,有下列情況: 
   僅在該保留點之後執行的語句被撤消。 
   該指定的保留點仍然被保留,該保留點之後所建立的保留點被刪除。 
   自該保留點之後所獲取的全部表封鎖和行封鎖被釋放,但指定的保留點以前所獲取的全部數據封鎖繼續保持。 
   該事務仍可繼續。 

(3) 保留點 

保留點(savepoint)是在一事務範圍內的中間標誌,經常用於將一個長的事務劃分爲小的部分。保留點可標誌長事務中的任何點,允許可回滾該點之後的工作。在應用程序中經常使用保留點;例如一過程包含幾個函數,在每個函數前可建立一個保留點,如果函數失敗,很容易返回到每一個函數開始的情況。在回滾到一個保留點之後,該保持點之後所獲得的數據封鎖被釋放。

6. 視圖在什麼情況下可以對其,刪除,修改操作:

DML操作應遵循的原則:

1.簡單視圖可以執行DML操作;

2.在視圖包含GROUP 函數,GROUP BY子句,DISTINCT關鍵字時不能刪除數據行;

3.在視圖不出現下列情況時可通過視圖修改基表數據或插入數據:

 a.視圖中包含GROUP 函數,GROUP BY子句,DISTINCT關鍵字;

 b.使用表達式定義的列;

 c.ROWNUM僞列。

 d.基表中未在視圖中選擇的其他列定義爲非空且無默認值。

WITH CHECK OPTION 子句限定:

通過視圖執行的INSERTSUPDATES操作不能創建該視圖檢索不到的數據行,

因爲它會對插入或修改的數據行執行完整性約束和數據有效性檢查。

視圖的刪除:

DROP VIEW  VIEW_NAME語句刪除視圖。

刪除視圖的定義不影響基表中的數據。

只有視圖所有者和具備DROP VIEW權限的用戶可以刪除視圖。

視圖被刪除後,基於被刪除視圖的其他視圖或應用將無效。

7. oracle中各種連接的寫法:

內連接,外連接 ,左外連接,右外連接
以上幾種連接一般用於多表之間複雜的查詢,
 下面先說說內連接,也即相等連接,如右兩張表 dept employee
dept裏有字段deptiddeptnameemployee有字段empnodeptidenamesalage
那連接查詢語句如下:select A.* ,B.* from dept A,employee B where A.deptid=B.deptid
一般出現這種情況的是一張是主表,另一張是子表,主表的主鍵作爲子表的外鍵,顯示結果按照子表的顯示, 內連接簡單,這裏就不多說了
 外連接在oralce裏用(+)表示,先看例子
select empno,ename,sal,emp.deptno,dept.deptno from emp,dept where emp.deptno(+) =dept.deptno
這是一個右連接
看下面的例子
select empno,ename,sal,emp.deptno,dept.deptno from emp,dept where dept.no=emp.deptno(+)
這是一個左連接
兩個查詢顯示的查詢結果是一樣的,剛開始學oracle的時候很多人都很難明白這個,現在有個笨辦法,
大家不防記下來,(+)出現查詢條件的左邊即右連接,出現在右邊即左連接。(+)可以放在左邊也可以
放在右邊,但是一定要放在缺少條件的那一邊,如上面的例子中,如果公司最近準備成立一個新的部門,
測試部門,但現在還沒有招新員工,而現在Boss想知道公司有知道公司的員工在那個部門並且想知道
沒有員工的部門,我們可以用上面的查詢語句實現。
左外連接(left outer join)和右外連接(reght outer join)如同上面的外連接,查詢的結果是一樣的。
左外連接:select empno,ename,sal,emp.deptno,dept.deptno from dept left outer join emp on (emp.deptno=dept.deptno)
右外連接:select empno,ename,sal,emp.deptno,dept.deptno from emp reight outer join dept on (emp.deptno=dept.deptno)
以上顯示的結果和外連接查詢出來的結果是一樣的 ,只是寫法不一樣而已,實際工作中外連接用的比較多,沒有必要都要去用它,但是概念大家一定要了解。
全外關聯 :FULL OUTER JOIN
SELECT e.last_name, e.department_id, d.department_name  
FROM employees e  
FULL OUTER JOIN departments d  
ON (e.department_id = d.department_id);  
結果爲:所有員工及對應部門的記錄,包括沒有對應部門編號department_id的員工記錄和沒有任何員工的部門記錄。

8. 查詢的優化

1.根據查詢條件建立合適的index

2.因爲SQL是從右向左解析,多表查詢時,記錄數少的表放在右邊

3.多個條件時,收斂快的條件放在右邊。

4.避免使用複雜的集合函數,象not in等。

5.避免在條件中對字段進行函數操作

6.儘量避免使用select *,應該寫出需要查詢的字段

7.java中儘量使用preparestatement執行sql,從而共享執行計劃"

9. 怎麼看執行計劃

使用explain或者autotrace查看執行計劃

10. 如何強制一個SQL語句使用索引? 使用index hints

11. Oracle中的PL/SQL塊是否熟悉?Oracle中的內置函數是否熟悉?

內置函數:ASCIICHRCONCAT, decode,to_date,to_char,to_number等等。

12. 如何取一個沒有排序的查詢結果中的前10條記錄?

select fielda from tablea where rownum<=10;

13. 問:如何取一個有排序的查詢結果中的前10條記錄?

select fielda from  (select fielda from tablea order by fieldb ) where rownum<=10;

錯誤寫法:select fielda from tablea where rownum<=10 order by fieldb;

14. 如何取一個沒有排序的查詢結果中的第11條到第20條記錄?

select fielda from 

(select fielda,rownum rn from tablea where rownum<=20) 

where rn>=11;

15. 如何取一個有排序的查詢結果中的第11條到第20條記錄?

select fielda from (select fielda ,rownum rn from (select fielda from tablea order by fieldb ) 

where rownum<=20) where rn>=11;

16. 數據庫設計中,主鍵的作用?

主鍵的作用保持數據表記錄的唯一性,建立主鍵索引和作爲外鍵使用.使用主鍵與外鍵的配對來表示實體間的連接.

17. Oracle數據庫設計中,建立外鍵的方法?

1)用Create table命令語句在設計數據庫表時建立外鍵

Create table Depart (

DepNO Number(2), 

DepName varchar2(10), 

CONSTRAINT pk_dept PRIMARY KEY (DepNO)

);

Create table Emp (

EmpNo Number(4), 

EmpName varchar2(20), 

DepNo  CONSTRAINT fk_deptno References Depart(DepNo)

);

2)用Alter table命令語句,爲一個存在的表添加外鍵

Create table Depart (

DepNO Number(2), 

DepName varchar2(10), 

CONSTRAINT pk_dept PRIMARY  KEY (DepNO)

);

Create table Emp( 

EmpNo Number(4), 

EmpName varchar2(20), 

DepNo Number(2)

);

Alter table Emp  

ADD  CONSTRAINT  fk_deptno  Foreign   key(DepNo)  References Depart(DepNo);

18. oracle中的常用函數,如:日期函數

1. 日期函數

       ADD_MONTHS:返回給指定的日期加上指定的月數後的日期。其格式爲add_months(d,n) , 其中d是日期,n表示月數。

       MONTHS_BETWEEN:返回兩個日期之間的月數。其格式爲:months_between(d1,d2) , d1晚於d2,結果返回正數,否則返回負數。

       LAST_DAY:返回指定日期當月的最後一天的日期值。格式爲:last_day(d)

       ROUND:返回日期值,此日期四捨五入爲格式模型指定的單位。格式爲:round(d,[fmt])

       NEXT_DAY:返回指定的下一個星期幾的日期,格式爲:next_day(d,day)

       TRUNC:將指定日期截斷爲由格式模型指定的單位的日期,與round函數不同的是它只舍不入。 格式爲:trunc(d,[fmt]),如果不指定fmt,日期則被截斷爲天。

       EXTRACT:提取日期時間類型中的特定部分。 格式爲:extract(fmt from d)。注意:此處的格式不用使用單引號。

2. 字符函數

       INITCAP(char) :將首字母轉換爲大寫。

       LOWER(char) : 轉換爲小寫

       UPPER(char) :  轉換爲大寫

       LTRIM(char,set) :左剪裁

       RTRIM(char,set) :右剪裁

       TRANSLATE(char,from):按字符翻譯

       REPLACE(char,search_str,replace_str): 字符串替換

       INSTR(char,substr[,pos]) :查找子串位置

       SUBSTR(char,pos,len) : 取子字符串

       CONCAT(char1,char2) : 連接字符串

       CHR:根據提供的ASCII碼返回對應的字符

       LPADRPAD: 左填充和右填充

       LENGTH:返回字符串的長度

       DECODE:與執行逐個字符替換的translate函數不同的是,decode函數進行逐個值的替換。

3. 數字函數

       ABS(n) : 取絕對值                 SIGN(n) :  取符號

       CEIL(n) : 向上取整                FLOOR(n) : 向下取整

       SIN(n) : 正弦                     FOWER(m,n): mn次冪

       COS(n) : 餘弦                     MOD(m,n): 取餘數

       ROUND(m,n): 四捨五入              TRUNC(m,n): 截斷                      

       SQRT(n): 平方根

4. 轉換函數

       TO_CHAR

       TO_DATE

       TO_NUMBER

5. 其他函數

       NVL(expre1,expre2) : 將空值替換爲指定的值

       NVL2(expre1,expre2,expre3): expre1不是空值,NVL2返回expre2,否則返回expre3

       NULLIF(expre1,expre2) : 比較兩個表達式,如果相等,返回空值,否則返回expre1

6. 分組函數

       AVG

       MIN :參數列中所有值的最小值

       MAX

       SUM

       COUNT

7. 分析函數

       ROW_NUMBERRANKDENSE_RANK

[數據庫簡單SQL語句總結 

1.在查詢結果中顯示列名:

a.as關鍵字:select name as '姓名'   from students order by age
b.直接表示:select name '姓名'   from students order by age

2.精確查找:

a.in限定範圍:select * from students where native in ('湖南', '四川') 
b.between...andselect * from students where age between 20 and 30
c.“=”select * from students where name = '李山
d.like:select * from students where name  like  '%' (注意查詢條件中有“%”,則說明是部分匹配,而且還有先後信息在裏面,即查找以開頭的匹配項。所以若查詢有的所有對象,應該命令:'%%';若是第二個字爲李,則應爲'_%''_''__')
e.[]匹配檢查符:select * from courses where cno like '[AC]%' (表示或的關係,與"in(...)"類似,而且"[]"可以表示範圍,如:select * from courses where cno like '[A-C]%')

3.對於時間類型變量的處理

a.smalldatetime直接按照字符串處理的方式進行處理,例如:
 select * from students where birth > = '1980-1-1'  and birth <= '1980-12-31' 

4.集合函數

a.count()求和,如:select count(*)  from students (求學生總人數)
b.avg()求平均,如:select avg(mark)  from grades where cno=’B2’
c.max()min()求最大與最小

5.分組group

常用於統計時,如分組查總數:select gender,count(sno)  from students group by gender
(查看男女學生各有多少)  注意:從哪種角度分組就從哪列"group by"
對於多重分組,只需將分組規則羅列。比如查詢各屆各專業的男女同學人數 ,那麼分組規則有:屆別(grade)、專業(mno)和性別(gender),所以有"group by grade, mno, gender"
select grade, mno, gender, count(*)  from students group by grade, mno, gender
通常group還和having聯用,比如查詢1門課以上不及格的學生,則按學號(sno)分類有:
select sno,count(*) from grades  where mark<60  group by sno  having count(*)>1 

6.UNION聯合

合併查詢結果,如:SELECT * FROM students
WHERE name like ‘%’  UNION [ALL]  SELECT * FROM students  WHERE name like ‘%’

7.多表查詢

a.內連接

select g.sno,s.name,c.coursename   from grades g JOIN students s ON g.sno=s.sno  JOIN courses c ON  g.cno=c.cno
(注意可以引用別名)

b.外連接

b1.左連接

select courses.cno,max(coursename),count(sno)  from courses LEFT JOIN grades ON courses.cno=grades.cno  group by courses.cno
左連接特點:顯示全部左邊表中的所有項目,即使其中有些項中的數據未填寫完全。左外連接返回那些存在於左表而右表中卻沒有的行,再加上內連接的行。

b2.右連接

與左連接類似

b3.全連接

select sno,name,major  from students FULL JOIN majors ON students.mno=majors.mno
兩邊表中的內容全部顯示

c.自身連接 

select c1.cno,c1.coursename,c1.pno,c2.coursename  from courses c1,courses c2  where c1.pno=c2.cno
採用別名解決問題。

d.交叉連接

select lastname+firstname from lastname CROSS JOIN firstanme
相當於做笛卡兒積

8.嵌套查詢

a.用關鍵字IN,如查詢李山的同鄉:

select  *  from students  where  native  in  (select native from students where name=’ 李山’) 

b.使用關鍵字EXIST,比如,下面兩句是等價的:

select * from students  where sno in (select sno from grades where cno=’B2’)  

select * from students where exists  (select * from grades where  grades.sno=students.sno AND cno=’B2’)

 

9.關於排序order

a.對於排序order,有兩種方法:asc升序和desc降序

b.對於排序order,可以按照查詢條件中的某項排列,而且這項可用數字表示,如:

select sno,count(*) ,avg(mark) from grades   group by sno  having avg(mark)>85  order by 3 

10.其他

a.對於有空格的識別名稱,應該用"[]"括住。

b.對於某列中沒有數據的特定查詢可以用null判斷,如select sno,courseno from grades where mark IS NULL

c.注意區分在嵌套查詢中使用的anyall的區別,any相當於邏輯運算“||”all則相當於邏輯運算“&&”

d.注意在做否定意義的查詢是小心進入陷阱:
如,沒有選修‘B2’課程的學生 :
select students.*  from students, grades where students.sno=grades.sno  AND grades.cno <> ’B2’                  
上面的查詢方式是錯誤的,正確方式見下方:
select * from students where not exists  (select * from grades  where grades.sno=students.sno AND cno='B2') 

11.關於有難度多重嵌套查詢的解決思想:
如,選修了全部課程的學生:
select * from students where not exists ( select *  from courses  where NOT EXISTS 
    (select *  from grades where sno=students.sno  AND cno=courses.cno))
最外一重:從學生表中選,排除那些有課沒選的。用not exist。由於討論對象是課程,所以第二重查詢從course表中找,排除那些選了課的即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章