用戶的創建和權限管理、視圖、索引、增刪改
視圖
什么是視圖?
視圖是一張虛表,不占用物理內存,是一個相對的概念。實際在,視圖里面存的是邏輯代碼,每次使用的時候都會取執行SQL代碼。相當於我們定義的sql語句存在了字典里面,需要的時候就直接拿出來就可以了。
視圖看上去非常像數據庫的物理表,對它的操作同任何其它的表一樣。當通過視圖修改數據時,實際上是在改變基表中的數據;相反地,基表數據的改變也會自動反映在由基表產生的視圖中。由於邏輯上的原因,有些Oracle視圖可以修改對應的基表,有些則不能(僅僅能查詢)
只讀視圖
create or replace view v_test01 as (
select * from emp with read only
好處:可以優化我們查詢語句的代碼,增強我們代碼的可讀性。
缺點:不建議直接對視圖進行DML語句(insert,delete,update)的操作,要想對數據的增刪改,建議直接
對數據表的增刪改。
--創建一個視圖
create or replace View V$_EMP
as select * from emp
select * from V$_EMP
--求部門平均薪資的等級最低的部門名稱,用子查詢。
select t02.*, d.dname
from (select t01.*, sg.grade
from (select e.deptno, avg(e.sal) vsal from emp e group by e.deptno) t01,
salgrade sg
where t01.vsal between sg.losal and sg.hisal) t02,
dept d
where t02.grade <= all
(select sg.grade
from (select e.deptno, avg(e.sal) vsal from emp e group by e.deptno) t01,
salgrade sg
where t01.vsal between sg.losal and sg.hisal)
and t02.deptno = d.deptno
------------
---利用視圖來簡化
create or replace View V$_EMP_SAL
as (select t01.*, sg.grade
from (select e.deptno, avg(e.sal) vsal from emp e group by e.deptno) t01,
salgrade sg
where t01.vsal between sg.losal and sg.hisal)
select es.*,d.dname
from V$_EMP_SAL es,dept d
where es.grade <= all(select grade from V$_EMP_SAL)
and es.deptno = d.deptno
創建數據庫用戶和賦予權限
通過sys或者system解鎖用戶:alter user 用戶名 account unlock/lock;
創建用戶:通過sys或者是system用戶來創建。
create user 用戶名 identified by 密碼;
賦予權限:(grant)
-
賦予登錄的權限:grant create session to 用戶名;
(查看用戶是否創建 SQL>select username from dba_users;)
-
賦予表的權限 : grant all on scott.emp to 用戶名;
- 收回權限:revoke all on scott.emp from 用戶名;
-
賦予創建表,創建視圖,創建索引,創建序列 的權限
grant create 權限名 to 用戶名;
-
授予普通用戶的 三大權限:
- connect
- resource
- dba
DDL語句
創建表結構的三大權限:
- create:用來創建表----->create table 表名(字段名 類型,字段名 類型,.....);
- drop:用來刪除表------>drop table 表名;
- alter:用來修改表------->alter table 表名 modify 字段名 所要修改的約束條件;
要想創建一張表結構與另一張表結構一樣的話。
insert into user 01 select * from user02 where 1=2(寫一個不成立的條件);
將一張表的數據全部都移到另一張表,表結構必須要一樣。
insert into user01 select * from user02(不加條件)
DML語句
-
insert:插入一條記錄。---->insert into 表名 (所需要插入的字段) values (所需要插入的數據);
-
delete:刪除一條記錄。----->delete from 表名 +條件;
如果沒有條件就刪除所有的記錄。
-
update:修改一條記錄。----->update 表明 set 所需要修改的字段 =所需要修改的字段的值 +條件。
如果沒有條件就更改所要列中的改字段。
-
刪除表中所有的行,建議使用truncate table 語句。不要使用delete
事務處理
當我們需要等所有的邏輯都運行完才能算成功的話,我們需要用到事務管理。
比如說銀行的取錢操作,我們必須等同時完成減錢和加錢的操作都完成了才算完成一個操作,同時減錢和加錢的兩個操作把他當成一個事務,只有當事務正常的執行完畢或者事務回滾到操作之前。
產生事務的幾個條件:
- 使用DML語句的時候,需要手動的提交事務,否則只能在本窗口才能查詢,其他的不能夠查詢到你修改的數據。手動提交
- 對表結構進行操作的時候(DDL語句)(create ,drop,alter語句執行后)會自動的將之前為提交的事務進行提交。自動提交
- 正常退出當前用戶的時候,也會自動的提交事務。
- 當程序不正常退出,比如說突然斷電等,此時會自動回滾事務。
-
commit:提交事務。
提交事務后的狀態:數據的修改被永久寫在數據庫中.
數據以前的狀態永久性丟失.
所有的用戶都能看到操作后的結果.
記錄鎖被釋放,其他用戶可操作這些記錄. -
rollback:回滾事務。
以前的數據可恢復
當前的用戶可以看到DML操作的結果
其他用戶不能看到DML操作的結果
被操作的數據被鎖住,其他用戶不能修改這些數據 -
savepoint:創建一個保存點。
......
savepoint 名稱;
......
rollback to 名稱;
--手動提交事務
commit;
--手動回滾事務
rollback;
---可以回滾到某個節點
insert into user01 values ('101',123);
insert into user01 values ('102',123);
insert into user01 values ('103',123);
--保存一個節點,不完全回滾到最初狀態。
savepoint t01;
insert into user01 values ('104',123);
insert into user01 values ('105',123);
rollback to t01;
序列化sequence
序列是oracle專有的對象,它用來產生一個自動遞增的數列
創建序列的語法:
create sequence seq_name
increment by n
start with n
實例:create sequence seq_empcopy_id start with 1 increment by 1;
有兩個方法:seq_name.nextval 獲取下一個數據
seq_name.currval 獲取當前的數據
--序列(創建一個自增不重復的一組數據)sequence
--用法:(sequence sq_no) sq_no.nextval獲取下一個步數。
-- sq_no.currval 獲取當前的
create sequence sq_no start with 100 increment by 1;
create or replace View V$_EMP as select * from user01;
create table emp001(
eno number(5),
ename varchar2(10),
eage number(3)
);
select * from emp001;
insert into emp001 values (sq_no.nextval,'張三',18);
delete from emp001;
數據類型
- number(x,y) :數字類型 ,最長x位,y位小數
- varchar2(maxlength):變長字符串,這個參數的上限是32767字節
- 聲明方式如下VARCHAR2(L),L為字符串長度,沒有缺省值,作為變量最大32767個字節
- char(max_length) 定長字符串 最大2000字節
- DATE:日期類型 (只能精確到秒。)
- TIMESTAMP:時間戳 (精確到微秒)
- long:長字符串,最長2GB
- 了解類型
CLOB:最大長度4G -->大對象很少使用:如果存在大對象,一般的解決方案存入文件地址(地址為程序所在應用服務器的相對路徑)。
BLOB:存二進制文件
數據類型 | 含義 |
---|---|
Varchar2(n) | 變長字符串,存儲空間等與實際空間的數據大小,最大為4K,長度以字節為單位指定(注意中文字符) |
Char(n) | 定長字符串,存儲空間大小固定 |
Number(p,s) | 整數或小數 ,p是精度(所有數字位的個數,最大38),s是刻度范圍(小數點右邊的數字位個數,最大127) |
Date /timestamp(精確到毫秒) | 年、月、日、時、分、秒 Date 精確到秒timestamp(精確到毫秒) |
Long 長字符串,最長2GB
CLOB 最長長度4G 存儲大對象,但是一般都不會將大對象存入數據庫 而是保存地址
BLOB 存二進制文件
數據庫的對象
對象名稱 | 描述 |
---|---|
表 | 基本的數據存儲對象,以行和列的形式存在,列 也就是字段,行也就是記錄 |
約束 | 執行數據校驗,保證了數據完整性的 |
視圖 | 一個或者多個表數據的邏輯顯示 |
索引 | 用於提高查詢的性能 |
Sequence | 自增序列 |
命名規則:
必須以字母開頭
可包括數字和三個特殊字符(# _ $)
不要使用oracle的保留字
同一用戶下的對象不能同名
約束
--表的約束
create table ys(
u_id number(5),
username varchar2(10) ,--constraint ys_username_null not null,--not null,
usex varchar2(2),
uage number(3),
address varchar2(150),
deptno number(3),
--constraint ys_username check(username is not null)
foreign key (deptno) references dept (deptno)
);
create table dept(
deptno number(3) primary key,
dname varchar2(10)
);
select * from ys;
drop table ys;
--主鍵,外鍵,非空,年齡的大小,性別合法,唯一性。
--主鍵:非空的唯一的。
--主鍵能夠唯一的區分一條數據。
----問題一,t_id怎么能夠重復。
insert into ys values(001,'張三','男',18,'廣東省某某',12);
insert into ys values(001,'張三','男',18,'廣東省某某');
--加主鍵。
--第一第二種是列約束
--第一種:直接在字段名后面加 primary key
--模板:字段名 類型 primary key;
create table ys(
u_id number(5) ,--constraint ys_u_id primary key,--primary key,
username varchar2(10),
usex varchar2(2),
uage number(3),
address varchar2(150),
constraint pk_ys_uid primary key (u_id)
);
--第二種:用constraint關鍵字。
--1.放在字段類型后面
--例如:字段名 類型 constraint 聲明名稱 primary key,
u_id number(5) constraint ys_u_id primary key,
--第三種:表約束:
--放在字段的后面,結束之前。
--模板 constraint 聲明錯誤名 primary key(所要聲明主鍵的字段)
constraint pk_ys_uid primary key (u_id)
--移除主鍵約束
alter table ys modify u_id primary key;
--問題二: select * from ys;
--名字怎么能為空呢?
insert into ys (u_id) values (1234);
--解決:not null 非空約束1
--第一種: 直接在字段后面加 not null
-- 字段名 類型 not null;
username varchar2(10)
--第二種: constraint 變量名 not null;
username varchar2(10) constraint ys_username_null not null,
--第三種: 在字段后面添加 constraint 名稱 check(需要非空的字段 not null )
constraint ys_username check(username is not null)
--表已存在的時候修改
alter table ys modify username not null;
--問題三:外鍵約束
--當一張表與另一張表關聯的時候,而這個字段又是關聯表的主鍵,
--此時需要外鍵約束他,只能讓其填入關聯表里主鍵的數據,其他數據則不能存進去
--關鍵字:foreign key(與外表關聯的字段) references 所要關聯的表 (與另外一張表關聯的字段)
foreign key (deptno) references dept (deptno)
--問題四 : 年齡和性別都要符合正常的邏輯
--關鍵字 check 檢查
-- check(所要判斷的邏輯)
--問題五: 里面有唯一的,比如說qq號,手機號碼。
--關鍵字 unique
--字段名 類型 not null unique;
關系模型的三類規則
為了維護數據庫中的數據與現實世界的一致性,關系數據庫的數據與更新操作必須遵循下列三類完整性規則:
實體完整性規則
這條規則要求關系中在組成主鍵的屬性上不能有空值。
參照完整性規則
這條規則要求“不引用不存在的實體”。例如:deptno是dept表的主鍵,而相應的屬性也在表emp中出現,此時deptno是表emp的外鍵。在emp表中,deptno的取值要么為空,要么等於dept中的某個主鍵值。
用戶定義的完整性規則
用戶定義的完整性規則反應了某一具體的應用涉及的數據必須滿足的語義要求。
索引
索引是為了加快對數據的搜索速度而設立的。索引是方案(schema)中的一個數據庫對象,與表獨立存放.
索引的作用:在數據庫中用來加速對表的查詢,通過使用快速路徑訪問方法快速定位數據,減少了磁盤的I/O
Sql中的索引是非顯示索引,也就是在索引創建以后,在用戶撤銷它之前不會在用到該索引的名字,但是索引在用戶查詢時會自動起作用。
索引的創建有兩種情況
- 自動: 當在表上定義一個PRIMARY KEY 或者UNIQUE 約束條件時,Oracle數據庫自動創建一個對應的唯一索引.
- 手動: 用戶可以創建索引以加速查詢
開發中使用索引的要點:
- 索引改善檢索操作的性能,但降低數據插入、修改和刪除的性能。在執行這些操作時,DBMS必須動態地更新索引。
- 索引數據可能要占用大量的存儲空間。
- 並非所有的數據都適合於索引。唯一性不好的數據(如省)從索引的到的好處不比具有更多可能值的數據(如姓名)從索引得到的好處多。
- 索引用於數據過濾和數據排序。如果你經常以某種特定的順序排序數據,則該數據可能是索引的備選。
- 可以在索引中定義多個列(如省加城市),這樣的索引只在以省加城市的順序排序時有用。如果想按城市排序,則這種索引沒有用處。
在一列或者多列上創建索引.
CREATE INDEX index ON table (column[, column]...);
下面的索引將會提高對EMP表基於 ENAME 字段的查詢速度.
CREATE INDEX emp_last_name_idx
ON emp (ename)
通過DROP INDEX 命令刪掉一個索引.
DROP INDEX index;
刪掉 UPPER_LAST_NAME_IDX 索引.
DROP INDEX upper_last_name_idx;
rowid
1、rowid 是oracle實際存在的值,是唯一的值
2、rownum 是一個虛擬的順序值 ,前提是一定要排序
select emp.*,rowid from emp;
delete from emp e where rowid not in(select min(rowid) from emp group by ename)
如何只顯示重復數據,或不顯示重復數據
顯示重復:select * from tablename group by id having count()>1
不顯示重復:select * from tablename group by id having count()=1
刪除重復數據原型:
delete from temp where rowid not in (
select min(rowid) from emp group by ename having count(*) >= 1)
and ename='wangcai'
數據庫設計的三范式
第一范式:保持原子性,就是不要將組合的東西放在一個字段里面,比如說姓名和id,這樣在取出來到java代碼中就無法有對應得一個屬性了。我們應該要做到一個字段不能夠再分成多個了,也要保持這一個字段對應java代碼的一個屬性。
第二范式:不要多個對象的將他創建成一張表,就算有聯系,也應該有主外鍵來區分。
比如說將學生和班級創建成一張表是不合理的,我們一個通過班級的id作為學生表的外鍵,這樣兩張表就有關聯 了。
第三范式:兩張表不應該多個相同的字段,只要有一個聯系的就能關聯到兩種表了。我的理解:不能存在傳遞依賴。即:除主鍵外,其他字段必須依賴主鍵。