1. 程式人生 > >數據庫——oracle

數據庫——oracle

數據庫

為什麽要用數據庫?
文件存儲:
1、不易於管理和分析(Linux操作系統下輸入ls命令會卡死)
2、不易於共享
3、文件內容不斷增大,不易於存儲
數據庫:用數據結構來管理、存儲數據的倉庫
DB:Database數據庫
DBMS:數據庫管理系統
數據庫軟件:Oracle  MySQL  db2    sql-server   sybase
關系型數據庫:由二維表組成
非關系型數據庫(NOSQL   not only  sql):
Web  高並發性mongodb   redis
關系:二維表
二維表:由行和列組成的表格
行:Record一條記錄信息
列:字段(Feild) 屬性
SQL:(structured  query  language 結構化查詢語言)
Oracle甲骨文
Java   sun ---> oracle收購
Mysql   my ----> sun(2008年1) ---> oracle(2009年4)
db2IBM
Sybasesybase  C/S數據庫
Sql server  MS 微軟
現在是oracle的天下
Oracle商業(收費)大型數據庫個人使用
Sql server
Windows 商業(收費)
Mysql開源免費  --->收費免費版本(不提供服務)
一般中小型企業用mysql阿裏用mysql
移動、聯通、電信都用oracle
 
數據庫是以二維表的形式存儲數據
數據庫客戶端:sqldeveloper
plsql developer(公司一般用)
查看數據庫裏有哪些表:
select * from all_tables;顯示用戶有權限看到的所有的表,包括系統表
select *from user_tables;當前用戶的所有表
selet *from dba_tables;是管理員可以看到的數據庫中所有的表
數據庫不難,提升效率難:如雙11
SQL:所有數據庫基本通用的語言
所有數據庫都遵循一套規則
主體語言:Java
腳本:
數據庫:
數據結構和算法:
業務知識,業務框架:
SQL:
DDL:Data Definition Language數據定義語言(操作對象是表)
關鍵字:CREATE:創建數據庫對象  建表
DROP:刪表
ALTER:改表結構
TRUNCATE:刪除表數據,不刪除表結構
DML:Data Manipulation Language數據操作語言(操作對象是表的記錄)
關鍵字:INSERT:插入數據
DELETE:刪除數據
UPDATE:修改數據
影響的數據,需要事物控制語句才能生效
eg:一張表裏兩個字段的值
Update** set coll=**,col=**;
TCL:Transaction Control Language事物控制語句
關鍵字:COMMIT:提交,確定把數據提交到數據庫
ROLLBACK:回滾,把影響數據的操作撤銷
SAVEPOINT:設置保存點,更有利於回滾到特定的場景
DCL:Data Contro Language數據控制語句(操作對象是用戶student)
關鍵字:GRANT:賦權
REVOKE:回收權限
CREATE USER:創建用戶
企業中對權限管理非常嚴格:允許插數據,不允許刪數據
DQL:Data Query Language數據查詢語句
關鍵字:SELECT
 
oracle數據類型:
1、數字類型(只用NUMBER)
NUMBER(p,s)
P表示總位數
S:表示小數的位數
可正可負,最多位數為38位
INTERGER == NUMBER(38)
例子:NUMBER(7,3)能表示的最大的數:9999.999
 
2、字符串類型
CHAR(n):固定長度的字符,定長字符串
n可以省略,默認為1
指定n,代表n個字節寬度,即使存儲的數據的字節小於n,也占n個字節,其余的補空格
最長只能存儲2000個字節
VARCHAR2(n):變長字符串
N表示字符串最大的長度
Varchar2(100)只存儲10個字符,實際上字符串占的內存和它自身長度是一致的
如:varchar2(100) hello存儲5個字節
節省內存
最長能存儲4000個字節
LONG:2GB
CLOB
 
3、時間類型
DATE
默認‘DD-MON-YY(RR)’
Systimestamp  時間輟  (時間毫秒)
Sysdate 系統時間
 
DDL:
CREATEcreate
建表:
Create  table  table_name(
字段名1   字段類型,
字段名2   字段類型,
....
);
自動提交,不用COMMIT
 
all_tables:記錄數據庫所有的表
//owner屬有者,擁有者
Table_name:表名
user_tables:記錄當前用戶下所有的表
//dba_tables:記錄所有的表,包括系統表(現在不講)
 
約法三章:
1、同一個數據庫,同一個用戶下,只能有唯一的標識符,同名的表只能有一個;
2、不要用別人的表;
3、自己建了之後記得刪掉
Sql語句除了字符串裏的內容,都要是英文的
創建表:create  table  ly_student(
name varchar2(20),
id number(12),
gender  char(1),
birth  date
);
Number:默認38位
查看表結構:desc wly_student;
能夠查看表的所有字段以及字段類型
 
往裏面插入數據:
Insert into table_name(字段名)   values(值);
字符串用單引號表示 ’ ’
日期:to_date(‘2017-08-02’,’YYYY-MM-DD’)
alter session set nls_date_format = ‘yyyy mm dd hh24:mi:ss‘;
select sysdate-1,sysdate,sysdate+1 from dual;
查找昨天,今天,明天這一時刻的時間,按指定格式輸出
插入:
insert into ly_student(name,id,gender,birth)
values(‘龍’,001,’M’,to_date(‘2017-08-02’,’YYYY-MM-DD’));
精度或者位數超長,報錯!
Commit;//插入後要提交
EMPLOYEE_ID NUMBER Primary Key:主鍵(唯一非空:值不能有重復)
當前面賦值過的值,後面再次被賦值時,會報錯,必須賦值
查看表的內容:seletct * from wly_student;
comment on table ly_student is ’student information’;
comment on column ly_student.name is ‘student name’;
comment on column ly_student.id is ‘student id’;
comment on column ly_student.gender is ‘student gender’;
comment on column ly_student.birth is ‘student birth’;
完整的建表語句:
建表的sql腳本及表和字段的詳盡說明
===============================================
drop:刪除表
drop table ly_student;
按照表名查找特定的表:
select * from user_tables where table_name like ‘%LY_STUDENT&‘;
like ‘%LY_STUDENT&‘ 可以換成=table_name
需要註意的是:表名大寫
drop table ly_student;
create  table  ly_student(
name varchar2(20),
id number(12),
gender  char(1),
birth  date
);
 
Alter table table_name add(字段名 字段類型);
alter table ly_student add(address VARCHAR2(100));
Alter table table_name drop column字段名;
Alter table table_name drop column address;
刪除字段時,要逐行刪除該字段的數據,當數據量較大時,效率會比較慢
Alter table table_name modify(字段名 字段類型);
Rename  old_table_name to new_table_name;修改一個表的名字
 
 
模型
DDL語句  CREATE  drop  alter
提交DB變量
流程,提供
 
建表:
1、emp:員工表
id:員工idnumber(5)
first_namelast_name     varchar2(20)
Gender性別char(1)
birth 生日date
hiredate  入職時間date
Deptid  部門idchar(2)
2、Dept表:部門表
Id:部門idchar(2)
Name:部門名稱varchar2(40)
插入三個部門,每個部門插入若幹員工
 
建表加復制數據
Create table table_name as select * from other_table_name;
*表示復制所有字段
Create table table_name as select id,name from other_table_name;可以
Create table table_name as select id*2,name from other_table_name;不可以(因為other_table_name裏面沒有“id*2”這個字段名)
表名不區分大小寫
修改字段的類型,(如果有記錄可能報錯)
Alter table table_name modify column_name type;
修改字段的名字
Alter table table_name rename column old_column to new_column
 
DML:(所有操作只有不commit,都可以通過回退,得到原來的數據)
Insert into  table_name(字段名)  values(值);
csex CHAR(6) check(csex=‘男‘ OR csex=‘女‘),//如果插入數據不是男或者女,會報錯
如果插入全表的字段,table_name後面可以省略字段名;
如果是指定插入某些字段,或者值的順序和字段名的順序不一樣,則需要字段名和值一一匹配。
修改字段的值:
Update table_name set
字段名1=值1,字段名2=值2;
全表所有記錄的該字段的值都被修改了
Update table_name set 字段=值 where condition;
不帶where條件的update請慎重!
刪除記錄:
Delete [ from ] table_name;
全表的數據被刪除,不帶where條件的delete請慎重!
刪除指定數據:Delete [from] table_name where condition;
Truncate:清空表數據,不會對表結構造成影響
Truncate table table_name和delete table_name
都可以把表裏的數據全部清空(刪除)
1、truncate 不可以帶條件,delete可以有
2、Truncate 刪除數據不可以修復,delete可以通過rollback將刪除的數據回復回來(如果commit了,則回退不了)
3、Truncate效率非常高,delete效率比較慢,如果實際中需要清空一張表,優先選擇truncate
 
TCL:(transaction)
Commit:提交
Rollback:執行DML語句之後,只要沒有commit;都可以回退;但是如果執行了commit,再去rollback都無法回退。
DQL:select
Select * from table_name;
*代表所有字段都顯示,查詢tabble_name所有字段的所有記錄
Selete 字段1,字段2,...from table_name
查詢指定字段的信息
字符串函數:concat   ||拼接字符串
Concat(char1,char2)  concat可以連用
註意轉義字符 ’
select concat(first_name,last_name) from ly_emp;  //拼接
select first_name||‘ ‘||last_name name from ly_emp; //拼接,中間加空格
select first_name||‘‘’‘||last_name name from ly_emp; //拼接,中間加 ’
 
dual 測試表
Length:求字符串的長度
char類型的長度是固定的,varchar2是根據字符串的長度
Lower:將字符串小寫
Upper:將字符串大寫
Initcap:首字母大寫,其余小寫
Trim(c1 from c2):把字符c1從字符串c2兩端去掉
Ltrm(c1 c2):把字符c2從字符串c1左邊去掉
Rtrim(c1,c2):把字符c2從字符串c1右邊去掉
Lpad(char1,n,char2):把char1填充為n個字節,在左邊補char2
如果n小於length(char1),則會截斷,右邊截斷,剩下左邊
Rpad:與lpad相反
select rpad(‘abcd‘,7,‘*‘) from dual; ---> abcd***
translate(char1,char2,char3);把字符串char1裏面和char2相同的字符,變成char3
select translate(‘hello‘,‘le‘,‘WX‘) from dual; ----> hXWWo
replace(char1,char2,char3):把char1中的char2子字符串換成char3字符串,如果沒有char3,則表示去掉char2子字符串部分;
Substr(char1,n,m)從字符串char1中,從第n個開始截取,截取m個字符
n=0(或1)表示從第一個字符開始截取,n<0表示從末尾倒數第n個開始,-1表示最後一個字符
Instr(char1,char2,n,m)
在char1中匹配char2,從第n個字符開始,匹配第m個,返回下標
如果匹配不到,返回0
Ascii(char1):求字符串char1第一個字母的ASCII碼值
 
Number函數:
Round(n,m):m>0,表示保留m位小數,四舍五入
m<0,表示保留m+1位數字,四舍五入
select round(123.23,-2) from dual;------> 100
Trunc(n,m):和round是一樣,但方法不一樣,直接舍棄
Ceil(n):向上(大的)取整select ceil(-125.56) from dual; ---> -125
Floor(n):向下(小的)取整select floor(-125.56) from dual; ---> -126
Mod(n,m):取余n%m:當m=0時,直接返回0
函數可以直接作用於字段
Emp(salary number(8,2) );
Select salary*12 from number;
To_date();按格式把字符串轉換成一個日期
YYYY ---> 年; MM---> 月 ; DD ---> 日;
Mon--->英文的月份;day --->星期幾(1表示日)
HH ---> 小時; HH24 ---> 24小時制;mi --->分鐘;ss ---> 秒
Add_month:select add_months(birth,3) from ly_emp;所有月份加3
Last_day():select last_day(birth) from ly_emp;返回月的最後一天
Months_between(a,b):select months_between(birth,hiredate) from ly_emp;    //兩個日期相差的月份
Next_day():select next_day(sysdate,1) from dual;//下周的星期日的日期To_char():可以把時間和數字轉換成字符串
select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss‘) from dual;將當前時間轉化成指定格式
Trunc
Round
 
 
 
Select:查詢數據庫的數據
單表查詢:
1、查詢所有字段所有記錄:select * from 表名
2、查詢指定字段所有記錄:select字段,...  form 表名;
3、可以給字段取別名:
Select 字段 字段別名,... from 表名
4、可以用字符串、數字、日期函數對字段進行處理
5、Select可以帶條件用where來過濾數據
1、指定字段的值  where  字段=值
2、指定字段的值在某個區間,數字的值可以通過< 和 >來匹配,
< >  != 來匹配不等於某個值的數據
可以用and來連接兩個有表達式,表示兩個表達式都滿足的情況下的所有記錄
可以用or來連接兩個表達式,只要滿足其中之一的表達式則匹配
Select * from table_name where id=1;
Select*from table_name where sal <> 800(或者sal !=800)
Select * from table_name where sal>800 and sal<1800;
3、字符串
可以用= 和 != 來匹配;  
模糊匹配:like
% 匹配任意多個任意字符
_  能夠匹配任意一個字符
Select*from emp where ename like ‘A%’;把名字是以A開頭的匹配出來
Select*from emp where ename like ‘_A%’;匹配第二個字符是A的
匹配以A開頭或者S結尾的名字:
Select*from emp where ename like ‘A%’ or ename like ‘%s’;
4、between  and
相當於  字段 <= **  and  字段 >=**
Select * from table_name where sal>=800 and sal<=1800;
Select * from table_name where sal between 800 and 1800;
5、in 來匹配零散的值
Select * from table_name where sal in(1250,800,1300);匹配工資為這三個值的數據,括號裏可以有多個值
Select * from table_name where sal not in(1250,800,1300);匹配除了這三條的其他數據;
 
In(list) 用表的記錄來list裏面進行逐一比較(=),如果相等,則匹配該條記錄;List裏面如果有null,null匹配不出來
Not in(list) 用表裏的記錄來list裏逐一進行比較(!=),如果全部都不相等,則匹配該記錄;表中null的記錄匹配不出來
Not in(list)所有值都不等於list裏面的值才匹配,null只要list裏面有null值,not in(list)將沒有一個被匹配出來。
 
 
 
 
例子:建表時:給默認值default設置默認值
字段非空:not null表示不為空
Create emp(id number(10) not null,//不插入數據,報錯
Name varchar2(20),//不插入數據,為null
Gender char(1) default ‘F’//不插入,默認為F
);
插入數據時,如果該字段沒有值,默認為null,但是如果該字段是not null,則插入失敗,非空字段一定要有值存在
Null值在oracle中非常關鍵
Null:是一種特殊的值,空值
任何數據類型都可以是空值
一個字段的值未確定或者沒有必要時可以為null;
Null值不可以用= 和 !=來進行比較判斷
select * from emp where mgr is (not)null;
 
空值處理函數
Nvl(expr1,expr2)
如果expre1為空,則取expr2的值
如果expr1不為空,則取它自身的值
select empno,ename,(nvl(comm,0)+sal)*12 from emp;
Nvl2(expr1,expr2,expr3)
如果expr1為空,則取expr2的值
如果不為空,則取expr3的值
select empno,ename,(nvl(comm,comm,0)+sal)*12 from emp;
給字段取別名會自動變成大寫的,如果想保持原狀,可以用雙引號“”;
如果別名需要空格,也可以用雙引號“”
可以給字段取別名,用as關鍵字,但as可以省略
select empno,ename,(nvl(comm,0)+sal)*12 “salary” from emp;
 
查找所有的部門emp:
去重:去除重復的沒必要的數據  distinct
Distinct可以對單個字段去重,也可以對多個字段一起進行去重
select distinct deptno,job from emp;  //查找每個部門都有哪些崗位
 
排序:
Order by 字段asc/desc   升序/降序
默認是按升序排序,所以asc可以省略
//查找所有的員工,按部門升序顯示所有的員工的薪資從多到少
select * from emp order by deptno asc , sal desc;
對多個字段進行排序時,先按前面的字段進行排序(分組),然後再按後面的字段進行排序,註意:每一個字段都要指定排序方式(asc/desc,asc可以省略(默認值));order by和distinct只出現一次。
Null最大,asc排序,null排在最後面
 
 
 
 
日期:
要對日期進行判斷
select sysdate +1 from dual;系統時間加n天
select trunc(sysdate,‘dd‘)-to_date(‘2017-01-01‘,‘yyyy-mm-dd‘) from dual;截取系統時間到天,距離2017-1-1日的天數;
日期可以直接加減運算,也可以用<,>,<=,>=,=,!=來判斷兩個日期
 
To_char() 整數按格式轉換為字符串
格式字符串裏以fm開頭
9 代表任意一個數字
0 強制顯示前導0,如果該位置有數字,則顯示數字,數字不足則顯示0
. 代表小數點
$ 代表美元符號
L 代表本地貨幣符號
select to_char(123.34,‘fm09999.99‘) from dual; ==》00123.34
select to_char(123.34,‘fm99.99‘) from dual; ==》######
select to_char(123.456,‘fmL999.999‘) from dual; ==》¥123.456
select to_char(123456.456,‘fm$999,999.999‘) from dual; ==》$123,456.456
 
聚合函數:
對數據進行分組,然後進行統計工作
一個組返回一條記錄
分組函數,集合函數
Max:select max(sal) from emp;//找到sal最高的員工
Min:select min(sal) from emp;
select max(sal) max_sal,min(sal) min_sal from emp;//找到並重命名
可以用於number,char,date類型
過濾掉記錄裏的null值
 
Avg  sum  平均值  和值
1、求所有員工的平均工資select avg(sal) avg_sal from emp;
2、求公司一個月要發放的工資select sum(sal+nvl(comm,0)) from emp;
Avg  sum只能用於number,自動過濾掉null
3、平均獎金 select avg(nvl(comm,0)) from emp;
Select avg(comm) from emp;求有獎金員工的每個人的平均獎金
 
Count求記錄的數目
Select count(*) from emp;//emp裏面有多少個員工
Select count(1) from emp;//計數所有的記錄,可以隨便填
Select count(ename) from emp;//emp裏面有多少個名字
Count可以對任意內容進行統計,會自動過濾掉null值
 
 
 
1、每個部門裏工資最大、最小
select deptno,max(sal),min(sal) from emp group by deptno;
2、統計每個部門的平均工資和工資總和
select deptno,avg(sal),sum(sal) from emp group by deptno;
3、每個部門有多少員工
select deptno,count(1) from emp group by deptno;
分組:
Group by 字段
組函數自動過濾null記錄
1、查找部門編號大於10的部門的員工平均工資
Select avg(sal) from emp where deptno>10;
2、查找部門編號大於10的部門平均工資:先過濾數據然後再組函數
Select avg(sal) from emp where deptno>10 group by deptno;
3、查找部門平均工資大於1600的部門編號及其平均工資:先用組函數求值(分組),然後再過濾數據
Select deptno,avg(sal) from emp group by deptno having avg(sal)>1600;
Having:用來過濾分組數據,只能用在group by之後;
 
 
SQL語句的執行順序:
1、from語句:從右往左,從後往前執行,建議把數據量少的放後面,數據大的表放前面;
2、Where語句:從右往左,從下往上執行;建議把過濾數據量多的語句放後面;
3、Group by語句:非常消耗資源,建議少用;建議在where的時候盡量過濾多的數據;
4、Having語句:從左往右
5、Select語句:oracle在解析*的時候,會先根據表名去查找這個表的字段(解析字段),需要消耗時間,所以盡量避免使用*,而是用具體的字段替代;
6、Order by語句:從左往右,非常耗資源。
 
 
多表查詢:
1、顯示員工編號、員工姓名、員工所在部門編號及部門名稱
關聯查詢
select * from emp;//14條數據
Select * from dept;//4條語句
Select * from emp,dept;//56條數據
笛卡爾積:兩個表數據的記錄相乘得到的就是笛卡爾積
等值連接
Select empno,ename,emp.deptno,dname from emp,dept 
where emp.deptno=dept.deptno
 
多表查詢:
多個表之間用逗號隔開;如果兩個表有同名的字段,需要顯示同名的字段時,需要表名.字段名來區別,對於表,也可以有別名
Select e.empno,e.ename,d.deptno,d.dname
From emp e,dmpt d
Where e.deptno=d.deptno;
內連接:把等值連接中表名之間‘,’換成join,再把where換成on;
Select e.empno,e.ename,d.deptno,d.dname
From emp e join dept d
On e.deptno=d.deptno
外連接:
左外連接:left join左邊表裏的數據一條都不會少(全部匹配),左邊表也稱為驅動表,然後根據條件去右邊的表匹配,匹配不上的記錄,該表的字段自動填充為null值。
Select e.empno,e.ename,d.deptno,d.dname
From emp e left join dept d
On e.deptno=d.deptno;
也可以寫成:Select e.empno,e.ename,d.deptno,d.dname
From emp e ,dept d
Where e.deptno=d.deptno(+);
//(+) 一定寫在驅動表的對面
 
右外連接:
Select d.deptno,d.dname,e.empno,e.ename
From emp e right join dept d
On e.deptno=d.deptno;
也可以寫成:Select d.deptno,d.dname,e.empno,e.ename
From emp e , dept d
Where e.deptno(+)=d.deptno;
全外連接:
Select d.deptno,d.dname,e.empno,e.ename
From emp e full join dept d
On e.deptno=d.deptno;
自連接:對同一張表用別名的方式擴展為兩張表,然後再進行關聯匹配
select distinct e1.empno,e1.ename 
from emp e1 , emp e2 
where e1.empno=e2.mgr;
記住:外連接有個關鍵字outer;left outer join
 
 
Sql高級查詢:
條件、表可能是從一個select語句中獲得
Select語句作為where的子句:
可能where依賴的條件不是一個確定的值,也不是通過函數求得;依賴於一條select的返回值
select語句中嵌套一個select語句,這個嵌入的select語句稱為select子句
Select 子句先執行,得到結果之後,再進行父select比較
根據select語句的返回值,可以分為:
單行select子句(= in < > != ...)
多行select子句(ANY  ALL  in  not in)
多列select子句(in)
Select語句:返回一行數據,多行數據,多列數據
 
返回多條語句:
ANY,ALL函數,不能單獨使用,只能和< > <= >= 一起使用
<ANY( list ) 小於其中一個
<ALL( list ) 小於所有的
 
Exists:(用的很多)用在where條件中,對於exists裏面如果有返回記錄,則表示條件為true,否則返回false
 
Select語句作為from的子句:
From的目標是一個表,當用select語句作為from的目標時,select子句稱之為行內視圖,或者匿名視圖
 
 
 
Rownum:
用來標識表裏數據,用數字對所有的記錄進行編號,編號從1開始,全部連續,也稱之為偽列;
用了之後,會出現一條標記行號的一列,但是訪問只能從1開始,不能從中間開始或直接訪問後面的;
可以把一個select出來的rownum當做一個行內視圖,把rownum取一個別名,這時候偽列就變成真的字段
Oracle的分頁記錄:rownum
 
 
Decode(expr[,expr1,result1[,expr2,result2]][,default])
 
 
集合操作:對分表時非常重要
Union結果是並集:a+b-重復的
union all結果是a+b,
Intersect並集
Minus  a-重復的(不會為負的)
對多個select語句的結果進行集合操作
每一個select語句的字段個數、順序和類型必須相同
 
Rownum
分組函數:
Row_number() over(PARTiTION BY col1 ORDER BY col2【,col3 desc】)
返回一個和rownum相識的東西(編號)
對coll字段進行分組,然後再對col2進行排序
編號從1開始,連續且不重復,也不能直接截取
 
Rank()
Rank( ) over(PARTiTION BY col1 ORDER BY col2【,col3 desc】)
對coll字段進行分組,然後再對col2進行排序,編號從1開始,如果排序值相同,然後會跳躍,如果兩個並列第二,後面從第4開始
 
Dense_rank()
Dense_rank() over(PARTiTION BY col1 ORDER BY col2【,col3 desc】)
對coll字段進行分組,然後再對col2進行排序,編號從1開始,如果排序值相同,則編號相同,不會跳躍,如果兩個並列第二,後面從第3開始
 
高級分組:
按年統計銷售額
按月統計銷售額
Group by rollup(a,b,c)
按a,b,c
A,b
A
 
Group by cube(a,b,c)
Group by grouping sets((a),(b)...)
小括號裏填分組的字段
指定需要的分組,顯示數據
 
 
 
 
約束
條件約束
為了維護數據的完整性及邏輯性
用約束來限制(DML  insert update  delete)表裏的數據
非空約束(NOT NULL) 簡寫 NN
唯一約束(UNIQUE) 簡寫UK
主鍵約束(PRIMARY KEY) 簡寫 PK
外鍵約束(FREIGN KEY)簡寫 FK
檢查約束(CHECK) 簡寫 CK
 
默認值(default) 這不是約束
約束可以在建表時指定,也可以在建表之後添加
所有的約束都在 user_constraints表中 
1、非空約束
Insert時,如果有字段為not null,那麽一定得插入該字段的值,否則會報錯;update時,無法將該字段更新為null。
什麽時候用:為了確保該字段一定有值
在建表之後添加非空約束
Alter table wly_stu add constraints constraints_name check(id is not null); 其中id是一個字段
刪除約束
Alter  table  wly_stu  drop  constraint  constraints_name
改變非空屬性
Alter  table wly_stu  modify  (id number(7) not null) 添加非空約束
Alter  table wly_stu  modify  (id number(7) null) 刪除非空約束
如果是匿名約束,需要先去user_constraints表中找到相應的約束,以及默認的約束名,然後再把它刪除
 
2、唯一約束:
值唯一,不能重復
建表時建唯一約束
 create table wly_stu(
  id number(10) ,
  name varchar2(30) not null,
  gener char(1)
constraint id_constraint_uk unique(id)//id字段有唯一約束,不能插入兩個相同的值
(null值例外,可以有多個id為null的行)
 );
建表之後添加唯一約束
Alter table wj_stu add constraint constraint_name unique(coll);
唯一約束可以是一個字段也可以是多個字段,多個字段時表示只要有一個字段不相同即為不相同
Alter table wj_stu add constraint constraint_name unique(id,name);
Insert into wj_stu values(110,’’xiaohong’);
Insert into wj_stu values(110,’xiaohei’);這兩條都可以插入,如果完全相同,則不能插入
 
3、主鍵約束:
必須非空,且值唯一
一個表裏,主鍵約束只能有一個
一個表裏,約束只能
主鍵約束可以提升select效率很好,(數據量多,根據主鍵查詢時)
主鍵約束也可以是對組合字段,但不建議
 
主鍵約束建在什麽地方,什麽字段建主鍵?
1、主鍵字段不要有具體的邏輯業務
2、主鍵約束不要經常DML操作
3、主鍵值應該自然有序,用序列生成最好
4、主鍵相當於索引
 
 
4、外鍵約束:
多張表之間的關系,一張表的字段的值依賴於另一張表的字段的值
被依賴的表叫做:主表
依賴其他的表叫做:從表
在建表時建外鍵約束,得先建主表,再建從表(建外鍵約束)
Alter table wj_dept add constraint constraint_name primary key(deptno)
Alter tbale wj_emp add constraint constraint_name foreign key(deptno) 
references wj_dept(q_dept);
Create table ly_dept(  //主表
Deptno number(2) primary key,  //主鍵
Dname varchar2(30) not null,
Loc varchar2(30)
);
Create table ly_emp(  //從表
Empno number(2) primary key,
Ename varchar(30) not null,
Deptno number(2),
Constraint constraint_name foreign key(deptno) references ly_dept(deptno)   
//依賴於主鍵關系,外鍵約束
);
外鍵約束:主表列是主鍵,從表添加不需要add關鍵字
外鍵約束對性能非常損耗,在從表插入數據時,要去主表裏查詢是否有對應的值,不建議使用,
除非特殊情況
可以不用外鍵約束來限制數據的完整性,這部分功能可以在代碼裏實現
索引、視圖
從表裏外鍵約束的值可以插入null值,除了空值以外的值,只能是主表裏對應的值(主表裏有的值)
從表裏引用了主表裏的值,則主表裏的值不允許刪除或者修改
Insert into ly_emp(empno,ename,deptno) values(120,’long’,20);
Delete ly_dept where deptno=20;//錯誤的,在從表裏引用了
增加外鍵:
Alter table tbale_name add constraint constraint_name foreign key(col) references
 other_table_name(other_col) 
create table parent (c1 number(2) primary key);
child表的c2列為外鍵,引自parent表的c1列
方法一:create table child
(c1 number(4) constraint child_c1_pk primary key,
 c2 number(2) constraint child_c2_fk references parent(c1));
方法二:create table child
(c1 number(4) constraint child_c1_pk primary key,
c2 number(2) ,constraint child_c2_fk foreign key(c2) references parent(c1));
5、檢查約束:
對數據進行檢查,只有滿足條件的情況下才允許插入和修改
Check(條件)
Check(gender in(‘男’,’女’))//插入數據時只能是男或者女,否則報錯
Alter table wj_emp add constraint constraint_name check(id>1000 and 
name like ‘%A%’);
Insert into wj_emp values(110,’wng’,20);//報錯
Insert into wj_emp values(1110,’wang’,20);//不會報錯
 
非空約束 not null
唯一約束 unique 可以往裏插入多個null值
主鍵約束  不可以為空
外鍵約束  可以插入空值
檢查約束  只要不檢查是否為空,那就可以插入null值
可以在建表時建立約束,也可以在建表之後添加、刪除
Alter table table_name add constraint constraint_name ***
Unique(col)
Primary key(col)
Foreign key(col) references table_name(col)
Check(condition)
 
User_constraints 保存著用戶下所有的約束名(如果創建時沒有指定約束名,系統會
自動生成一個約束名)
 
視圖:把一個select語句的結果集當做一個表一樣使用,虛擬的表,是數據的邏輯表示,其本質
是一個select語句加了一個名字
創建一個視圖
Create  [or  replace] view view_name   as  subquery;
Subquery:一個select語句
試圖分為:
1、簡單視圖:select 語句包含一張表,但是沒有有函數、表達式、group by的約束
2、復雜視圖:select 語句包含一張表,但是有函數、表達式、group by的條件
3、連接視圖:select  多張表
Create view emp_view_20 as select empno,ename,deptno,sal from emp
創建視圖需要權限:grant create view to 用戶(student);
所有的視圖名都保存在User_views裏
視圖是一個select語句的結果集,他沒有具體的數據,而是一種映射關系。當視圖建立以後,可以
把試圖當做一張表一樣使用(select)
視圖作用:
1、對於復雜的select語句,建立視圖之後,可以提升查詢效率
2、通過視圖只能查詢特定的記錄和字段,能夠隱藏和保護一些數據及字段,保護數據和屏蔽
數據的作用(安全措施)
3、操作視圖就等於操作視圖映射的表。(不建議通過視圖修改表裏的數據),可以在創建視圖時
指定視圖只能查詢,不能修改數據
在創建視圖的語句後面加With read only;
對於復雜的視圖,根本就不允許插入和刪除。
Create view emp_view_20 as select empno,ename,deptno,sal from emp where 
deptno = 20;
當插入部門不是20的數據時,視圖不會有變化,但是映射所對應的表會多一行數據;當修改一個
deptno為20的數據變成不是20時,視圖裏會消失。
可以通過限定用戶智能操作視圖裏有的數據:
with check option—— DML只能操作視圖裏有的數據(只對視圖可見)
Delete時只能刪除視圖裏有的數據
Insert時只能插入滿足select條件的數據
Create or replace view 可以創建和修改視圖
Drop view view_name 刪除視圖
 
在用函數和表達式進行創建視圖時,必須用別名
Create view emp_view_20 as select empno,lower(ename) name,deptno,sal from emp 
 
 
序列:(sequence)可以自動生成數字值的數據庫對象
CREATE sequence seq_name [ start with i ] [ increment by i ] [ minvalue 
n|no minvalue] [maxvalue m|no maxvalue] [cycle | nocycle] [ cache p | on cache];
Start with i表明從i開始計數
Increment by j 表明每次遞增多少(j是負數,遞減)
如果沒有指定i和j,從1開始遞增,每次遞增1
Cycle:表明值取到了最大值之後,可以從最小值開始重新開始計數
如果是取到了最小值,可以從最大值重新開始計數
Cache p:表示每次生成多少個數字,緩存的值的個數,默認是20
 
序列可以有效的用來生成主鍵的值
多個表可以共用一個序列,但是建議一個表用一個序列
user_sequences所有的序列都存儲在這個表裏
Nextval:獲取序列的下一個值,每執行一次nextval會增長一次,在序列剛創建時,
必須使用一次nextval才能使用currval
Currval:獲取序列的當前值
 
Create sequence seqly_emp2
Start witn 1000 increment by 1
Minvalue 1 maxvalue 1000000000 nocycle cache 2000
 
create table wly_emp_test(
 id number(10) primary key,
 name varchar2(30)
 );
 select seqly_emp2.nextval from dual;
 insert into wly_emp_test(id) values(seqly_emp2.nextval);
 select * from wly_emp_test;
序列可以高效的用來生成主鍵的值
 
刪除:drop sequence seq_name;
 
 
索引:
Rowid是一個偽列,用於標識數據表裏每一條記錄的地址
Pl sql developer裏面:select e.*,e.rowid from emp e;可以在表中直接修改
 
索引是保存記錄的地址及索引關鍵字,用於提升查詢效率最有效的方法
字典:通過目錄去查找
視圖:把內容大的拆分成每一塊內容較小的,再去查找
 
Create index [unique] index_name on table_name(col);
 
註意事項:
1、數據量小的時候應該避免建索引
2、一般給where條件,group by 這些經常用來查詢的字段建索引
3、索引的個數沒有限制,但不是越多越好
4、索引對於查詢的效率有很好的提高,但是得建立合適的索引
5、索引也是占用資源的(需要保存值和地址)
6、二叉樹 oracle實現索引是用二叉樹:B-tree
7、對於經常DML操作的列,應當根據情況避免建索引,因為索引會影響insert操作的執行效率
刪索引 --> 導數據 --> 再建索引 會比直接導數據的效率要高
 
Create index deptno_index on dept(deptno);
 
User_objects;---索引、視圖、序列均可在這個表裏查到
索引一旦建立之後,oracle自動維護,查詢時不需要指定使用哪個索引
Select * from emp where empno =**  ---empno
Select * from emp where ename =**  ---ename
 
如果某個字段的值是唯一的,可以建唯一索引
Create unque index empno_index on(empno);
如果索引字段的值經常DML,可以用Alter index index_name rebuild;
更新索引,將刪除的數據的索引刪掉,提高內存效率
索引:建在那個字段,經常用來查詢數據的字段,這個字段可以是組合字段,group by deptno,mgr 
      -------> On(deptno,mgr);
在生產中,索引用的非常多
索引:用空間換時間,消耗內存空間提升效率


本文出自 “Java學習” 博客,請務必保留此出處http://12181171.blog.51cto.com/12171171/1962674

數據庫——oracle