oracle 數據庫
java編寫一個程序 數據存在哪里呢?
目前: 數組 集合
文本文件
一、數據的存儲
文本文件存儲的缺陷:
1.沒有數據類型
2.不安全
3.存儲的數據量小
4.對數據的訪問和修改效率低
....
二、關系型數據庫
1.RDBMS(關系型數據庫管理系統 relationship Database Management System)
2.常見的關系型數據庫: oracle Mysql DB2 SqlServer
3.基本的概念:
3.1 表(table): 數據庫中存儲數據的單元 也叫做 實體集 entitySet
3.2 行(row):代表一條具體的數據 也叫實體 entity
3.3 列(column):代表每一條具體數據的屬性(特點) 也叫 字段 field
3.3 主鍵(primary key):唯一標識表里的一條信息, 唯一、不能為空
3.4 外鍵(foreign key):代表本表的記錄與其他表記錄之間的關系
4.運行的方式
client --- db server (客戶端 -- 數據庫服務器)
客戶端通過sql命令與數據庫服務器進行通信
三、oracle數據庫
1.安裝:
(見word)
OracleServiceXE: 核心服務
OracleXETNSListener:對外提供鏈接服務的
2.幾種訪問oracle的方式
2.1 sqlplus 基于命令窗口的
window 鍵 + R ---輸入 cmd 回車
在dos窗口下輸入sqlplus
alter user hr account unlock; -- 解鎖hr賬戶
命令:desc 表名 -- 查看表的結構
2.2 isqlplus:oracle提供的基于瀏覽器的訪問方式
http://127.0.0.1:8080/apex
2.3 pl/sql Developer -- 第三方提供的訪問oracle的方式
登陸用戶名 : hr
密碼: hr
database:XE
Connect as: normal
file -- new -- SqlWindow 進入到命令窗口
四、sql命令 -- 基本的查詢
1.簡單查詢
select 字段名1,字段名2... from 表名;
select : 指定查找的字段
from:從那張表查詢
1.1 -- 查詢 員工的編號、名字、郵箱、工資 的信息
select employee_id,last_name,email,salary from employees;
1.2 -- 查詢全表的信息
select * from employees;
注意:在實際開發中不建議使用 select *的方式進行全表查詢,因為*的語義
不明確,效率低
1.3 -- 查詢所有人員的 編號、名字、年薪、部門編號
select employee_id,last_name,salary*12,department_id from employees
允許對查詢結果的字段進行算數運算 + - * /
注意:+ 號不能作用于字符串
可以對日期類型進行算數運算,以天為單位
1.4 字段起別名 -- as
語法:select 字段名 as 別名 from 表名;(as可以省略)
-- 查詢所有人員的 employee_id,last_name,salary*12(年薪),department_id
編號 名字 年薪 部門編號
select employee_id as "編號",
last_name as "名字" ,
salary*12 as "年薪",
department_id as "部門編號"
from employees;
1.5 字符串拼接 ||
語法: 字符串1 || 字符串2
--查詢 員工編號、姓名、部門編號 的信息
select employee_id,first_name||'.'||last_name,department_id
from employees;
2.排序 -- order by【重點】
語法: select 字段名 ,.. from 表名 order by 字段名 asc(默認)/desc
asc:升序 desc:降序
--查詢員工表全部信息,對查詢結果按工資升序顯示
select * from employees order by salary asc;
--查詢員工表全部信息,對查詢結果按工資降序顯示
select * from employees order by salary desc;
--查詢員工表全部信息,對查詢結果 按工資升序排列,
如果工資相同 按部門編號升序排列
select * from employees order by salary asc,employee_id asc;
注意:asc/desc 作用于 前面的字段
3.條件判斷查詢 -- where 【重點】
語法:select 字段名 ... from 表名 where 條件 order by 字段名
作用于一行數據,對數據庫的每行數據進行篩選
3.1 等值查詢 =
--查詢90號部門的員工信息
select *
from employees where department_id = 90;
3.2 不等值條件 > >= < <= !=(<>) and(并且) or (或者)
--查詢工資大于5000的員工信息
select *
from employees where salary > 5000;
--查詢工資大于5000 并且 小于 10000的員工信息
select *
from employees
where salary > 5000 and salary < 10000;
-- 查詢90號部門的信息和工資大于5000的所有人員信息
select *
from employees
where department_id = 90 or salary>5000;
3.3 區間查詢 --- between ... and ..(包括邊界值)
語法: where 字段名 between 條件1 and 條件2
--查詢工資大于等于5000 并且 小于等于10000 的員工信息
select *
from employees
where salary between 5000 and 10000;
3.4 枚舉查詢 -- in
語法:where department_id in (條件1,條件2,...)
-- 查詢50,70,90號部門的員工信息
select *
from employees
where department_id in(50,70,90) ;
3.5 oracle對null值的處理 is null is not null
--查詢沒有提成(commission_pct)的員工信息
select *
from employees
where commission_pct is null;
3.6 模糊查詢 -- like
語法: select 字段名.... from 表名 where 字段名 like '條件'
通配符: _ 代表一個字符
% 代表n個字符
-- 查詢first_name由4個字符組成的人員信息
select *
from employees
where first_name like '____';
--查詢first_name以字母 'S'開頭的人員信息 'S%'
select *
from employees
where first_name like 'S%';
--查詢first_name以S開頭的 由 5個字母組成的人員信息
select *
from employees
where first_name like 'S____';
注意:' '里面嚴格區分大小寫
select 語句oracle中不分大小寫
五、函數
dual(啞表) -- oracle給我們提供的一個啞表,用于維護select語句的完整性
這個表只有一行一列。
--打印當前系統的時間 -- sysdate
select sysdate from dual;
abs(數值) -- 求絕對值
--select abs(-2) from dual;
mod(num1,num2) -- 求num1模num2的值
1.單行函數
作用于一行數據,產生一個結果
1.1 to_char(time,'字符串格式')【重點】
年 yyyy yy rr rrrr year
月 mm month
日 dd ddth
星期 day
小時 hh hh24
分 mi
秒 ss
--打印當前系統時間,按格式:年-月-日 星期 時:分:秒
yyyy-mm-dd day hh24:mi:ss
select to_char(sysdate,'yyyy-mm-dd, day,hh24:mi:ss') from dual;
--打印今天是星期幾
select to_char(sysdate,'day') from dual;
1.2 to_date('字符串格式的日期','對應日期格式的字符串')【重點】
'2016-08-11' 'yyyy-mm-dd'
注意:字符串的表現格式 必須和前面的日期格式一樣
作用:將一個字符串格式的日期,轉換成oracle數據庫的標準日期顯示
-- 將'2000-8-11' 轉換成數據庫標準時間格式 顯示
select to_date('2000-08-11','yyyy-mm-dd') as "時間" from dual
-- 打印'2000-08-11'是星期幾
select
to_char(to_date('2000-08-11','yyyy-mm-dd'),'day') from dual;
-- 查詢員工表中 1997年 入職的員工
select *
from employees
where to_char(hire_date,'yyyy') = '1997';
2、組函數(作用于每一組,產生一個值)
2.1 sum() 求和 -- 適用于數值類型
--求所有人員月工資的和
select sum(salary) from employees;
2.2 avg() 求平均值 -- 適用于數值類型
--求所有人員平均工資
select avg(salary) from employees;
2.3 min() 求最小值
--求所有人員工資最小值
select min(salary) from employees;
2.4 max() 求最大值
--求所有人員工資最大值
select max(salary) from employees;
注意:oracle中null是最大值
2.5 count() :統計個數 -- 括號里面可以寫 * 也可以寫字段名
--打印 1997 年入職的員工總人數
select count(*)
from employees
where to_char(hire_date,'yyyy') = '1997';
count(字段):容易出現統計不準確的情況,因為他會自動忽略null
count(1) 和 count(*) 效果是一樣的
六.分組語句 -- group by 【重點】
語法: select 字段名 ... from 表名 where 條件 group by 字段名 order by
-- 查詢人員的信息,按照部門編號進行分組
select department_id
from employees
group by department_id;
語法規則:
*只有出現在group by 語句里的字段 才能單獨出現在select語句當中
在group by語句當中對字段使用了哪個單行函數,那么select語句里面
*也必須使用相同的
*如果一個字段沒有出現在group by語句中,那么他必須配合組函數才能
出現在select 語句中
--查詢1997年入職員工 各個月份的總人數
1)確定分組條件: 月份分組
2)where to_char(hire_date,'yyyy')= '1997'
-- select to_char(hire_date,'mm'),count(*)
from employees
where to_char(hire_date,'yyyy')= '1997'
group by to_char(hire_date,'mm');
--統計查詢 各個部門員工的總工資
分組條件: department_id
select sum(salary)
from employees
group by department_id;
七、having -- 對分組后的數據做條件判斷的【了解】
where 是對分組前的數據進行篩選,堅決不能跟組函數
having 對分組后的數據進行再次篩選,不能跟單行函數
--查詢1997年入職員工 各個月份的總人數(人數大于2的月份)
select to_char(hire_date,'mm'),count(*)
from employees
where to_char(hire_date,'yyyy')= '1997'
group by to_char(hire_date,'mm')
having count(*)>2;
注意:如果where having都可以完成一個需求的時候,優選where
八、select 命令語句總結
select 字段名... from 表名 where 條件 group by 字段名 having 條件 order by 字段名 asc/desc;
from 確定查詢數據來自的表
where 對表中的數據進行篩選,生成查詢的基礎數據
group by 對基礎數據進行分組
having 對分組后的數據進一步篩選
select 對篩選后的數據生成結果集
order by 對結果集排序
一、偽列
他就是個不存在的列,通過select 語句是查詢不到的,我們可以通過
手動給出。
常見的偽列:rowid rownum
rowid:數據庫里面一條數據的唯一標識,通過對物理地址計算得出的。
rownum:數據庫會給每次出現在查詢結果里的行 進行編號,從1開始,查詢執行一次
編一次號。
--可以給表起別名
--select e.,rowid,rownum from employees e
--取出employees表里面的前5行數據
select *
from employees
where rownum <=5;
--取出表里前6 到 10 條的數據
select *
from employees
where between 6 and 10; -- !error(錯誤的)
注意:rownum 必須從一開始 ,只能做 >=1 =1 < <= 關系運算
二、子查詢(嵌套查詢)
--查詢employees表里面 最高工資的員工
1.查詢出最高工資
select max(salary) from employees; -- r1
2.查詢出最高工資的員工
select * from employees where salary = r1;
3.合并
select *
from employees
where salary = (select max(salary) from employees);
1.子查詢結果是一行一列,常用在where里面做條件判斷
--查詢公司里工資高于平均工資的人員信息
1.1 統計查詢平均工資
select avg(salary) from employees; -- r1
1.2 查詢出高于平均工資的人員信息
select * from employees where salary > r1;
1.3 合并
select *
from employees
where salary > (select avg(salary) from employees);
2.子查詢結果是多行一列,經常用于 where的條件判斷
--查詢和'King'在一個部門的人員信息
1.查詢出'King'(last_name)所在的部門
select department_id from employees where last_name = 'King'; -- r2
2.查詢出和'King'在一個部門的人員
select * from employees wher
e department_id in r2;
3.合并
select *
from employees
where department_id in (select department_id
from employees where last_name = 'King');
3.子查詢結果是多行多列,經常出現在from 子句里,他其實是個虛表,可以再次
對虛表進行查詢;
--查詢工資最高的前5個員工信息
1.對employees表進行按工資排序(由高到低)
select * from employees order by salary desc; -- tab1
2.在tab1里面取出前5個人員的信息
select * from tab1 where rownum <=5;
3.合并
select *
from (select * from employees order by salary desc)
where rownum <=5;
三、數據庫的分頁 【重點】
--查詢工資最高的第6個到第10個人員的信息
笨方法:
1.對employees表按工資進行排序(從高到低)
select * from employees order by salary desc; -- tab1
2.從tab1里面取出前10條,再次按工資排序(倒序)
select * from tab1 where rownum <=10 order by salary ; -- tab2
3. 從tab2里面取出前5條(就是工資最高的第6-10 個人員的信息)
select *
from (select * from
(select * from employees order by salary desc)
where rownum <=10 order by salary )
where rownum <=5;
專業的:
1.對employees表按工資進行排序(降序)
select * from employees order by salary desc; -- tab1
2.給rownum起個別名rn,讓他成為 employees表的一個具體字段
select e. , rownum rn
from tab1 e; --tab2
3.從tab2里面取出 第6 到第10條信息
select *
from tab2
where rn between 6 and 10;
4.合并
select *
from (select e. , rownum rn
from (select * from employees order by salary desc) e)
where rn between 6 and 10;
四、表連接
概念:同過某個條件將兩張表或者多張表的記錄 合并成一個記錄結果展示
1.內連接
關鍵字: inner join (inner可以省略) on給定連接條件
--查詢員工的信息 以及其對應部門的信息
select e.,d.*
from employees e join departments d
on e.department_id = d.department_id;
注意:內連接不能處理null值
2.外連接 :左外連接,右外連接,全外連接
關鍵字:
左外連接 left [outer] join on連接條件【重要】 outer可以省略
以左表為主表,右表為輔表,左表數據會全部出現在查詢結果里
右外連接 right [outer] join on連接條件
以右表為主表,左表為輔表,主表的記錄會全部出現在查詢結果里面
注意:如果輔表的連接條件跟主表的連接 沒匹配上 會用null來代替
全外連接 full outer join on連接條件
所有的數據都會出現在結果里
語法:
select 字段名...from 表1 連接關鍵字 表2 on 連接條件 where ...group by ... having...order by.
--查詢員工的所有信息 以及其部門的所有信息
左連 --select e.*,d.*
from employees e left outer join departments d
on e.department_id = d.department_id;
右連 --select e.*,d.*
from employees e right outer join departments d
on e.department_id = d.department_id;
全連:-- select e.*,d.*
from employees e full join departments d
on e.department_id=d.department_id;
3.多表連接
--查詢員工的姓名、部門的名稱、城市名稱
select e.last_name,d.department_name,l.city
from employees e left join departments d on e.department_id = d.department_id
left join locations l on d.location_id = l.location_id;
4.自連接
--查詢員工的姓名以及 他的領導的姓名
select e1.last_name,e2.last_name
from employees e1 left join employees e2
on e1.manager_id = e2.employee_id;
一、建表 -- create table
1.確定表名
2.確定表有哪些字段(屬性)
3.語法:
create table 表名(
列名1 數據類型 默認值(default) 約束 ,
列名2 數據類型 約束
....
);
4.標示符命名規范
4.1 由字母、數字、、$、#組成,數字不能作為開頭
4.2 長度不能超過30個字符,不能與關鍵字重名
5.數據類型
5.1 數值類型
number(大小限制) -- 相當于JAVA中的double 【---常用】
比如: number(2) -- 最大存兩位數
number(5,2) -- 最多存儲5位數,其中小數最多2位
整數位最多3三位
integer -- 一個很大的整數
5.2 字符串類型
varchar2(大小限制) -- 表示一個可變長的字符串,按照你實際存儲的數據
大小來開辟空間,最多4000個字符
比如:varchar2(20) -- 最多存儲20個字符 【---常用】
char(大小限制) -- 表示一個定長的字符串,限定大小是多少,就按多少開辟
存儲空間
比如:char(5) -- aa 他的大小還是5個字符大小
5.3 日期類型
date -- 精確到秒 【---常用】
timestamp -- 精確到秒后面的小數
5.4 大數據類型
clob -- 存儲字符型大對象,最大限制4G
blob -- 存儲二進制大對象,最大限制4G
long -- 存儲字符,最大限制2G
6.約束
6.1 主鍵約束 -- primary key: 唯一、非空 ,一張表只能有一個主鍵
6.2 非空約束 -- not null: 此列值不能是null
6.3 唯一約束 -- unique : 值必須唯一 ,可以為空, 空值可以重復
6.4 檢查約束(自定義約束) -- check() : 比如說對手機號碼和郵箱的驗證 等等
郵箱驗證:check(字段名 like '%@%')
6.5 外鍵約束(foreign key)-- references : 代表本表記錄和其他表記錄之間的
關系,通常作為表連接的條件,值可以為空,可以重復,但是值必須來自
其他表的主鍵,唯一約束的列
7.創建一個學生表和一個班級表
create table clazzs( -- 父表
c_id number(3) primary key, -- 班級編號
c_name varchar2(20) not null, -- 班級名稱
create_date date -- 創建日期
);
create table t_students( -- 子表
s_id number(3) primary key,
s_name varchar2(20) not null ,
sex char(1) check(sex in ('m','g')),
mobile_num varchar2(11) unique check(length(mobile_num) = 11),
email varchar2(50) check(email like '%@_%'),
c_id number(3) references clazzs(c_id)
);
二、sql命令的分類
1.DQL: 數據查詢語言 比如 select
2.DML: 數據操縱語言 insert update delete
3.DDL: 數據定義語言 create drop alter
4.DCL: 數據控制語言 grant revoke
5.TCL: 事務控制語言 commit rollback
DML:
--insert -- 插入 向表里面插入數據
語法:inser into 表名 values (值1,值2 ...) -- 全部字段插入
inser into 表名(字段1,字段2,...) values (值1,值2 ...)
注意:values 里面的值 一定要與表名后面的字段相匹配
例子:
insert into clazzs values (62,'JAVA班',sysdate);
insert into t_students(s_id,s_name,sex,mobile_num,email,c_id)
values(1,'小明','g','11111111111','xiaom@zpark.com.cn',1)
--update -- 更新數據
語法:
update 表名 set 字段1= 新值1,字段2= 新值2 where ..
注意:如果沒有條件判斷會全表更新
例子:
update t_students set s_name = '小貝';
--delete -- 刪除
語法:delete from 表名 where ...
注意:在使用delete命令的時候 ,務必要確定好條件
例子:
delete from t_students where s_id = 1;
DDL:
drop -- 用于刪除數據庫的實例對象
語法: drop table 表名;
drop table clazzs;
drop table clazzs cascade constraint; -- 級聯刪除
注意:在刪除父表前,必須刪除字表的外鍵關系
alter -- 修改列的一些操作 【了解】
修改列名:
alter table 表名 rename column 老名 to 新名;
加列:
alter table 表名 add 列名 數據類型
修改列的數據類型:
alter table 表名 modify 列名 數據類型
注意:被修改的列,必須沒有數據
DCL:
grant -- 授權
grant 權限 to 用戶
revoke --撤銷授權
revoke 權限 from 用戶
TCL:
commit -- 提交事務
rollback -- 事務回滾
三、序列 -- sequence 【重點】
1.概念:
sequence是由數據庫系統提供的,一個自增長序列號,經常用于生成
表的主鍵(PK)
2.創建:
create sequence 序列名 【..】
start with n -- 代表此序列從n開始生成
increment by n -- 代表此序列每次自增長的數量
maxvalue n -- 最大可生成的值
minvalue n -- 最小從幾開始
cycle no cycle -- 是否循環生成
cache n /no cache -- 每次緩存多少 默認緩存20個
3.使用:
序列名.nextval
比如: select clazzs_seq.nextval from dual
4.刪除序列
drop sequence 序列名;
四、視圖 -- view
其實就是對一個查詢語句起個別名,存在數據庫里面,以便以后重復使用
注意:視圖實質上是存儲的sql語句
創建:create view 視圖名 as 查詢語句
create view emp_view as (select * from employees);
1.簡化查詢
-- 查詢工資最高的第6 到第10個人的信息
1.select * from employees order by salary desc; -- tab1
2.select e.,rownum rn from tab1 e; -- tab2
select *
from (select e.,rownum rn from
(select * from employees order by salary desc) e)
where rn between 6 and 10;
通過創建視圖實現;
create view emps1 as (select * from (select e.*,rownum rn from
(select * from employees order by salary desc) e));
select * from emps1 where rn between 6 and 10;
刪除: drop view 視圖名;
注意:對視圖的操作會影響到原表 ,盡量不要對視圖做 update delete insert
五、索引 -- index
相當與一個目錄,提高查詢的效率
創建:
create index 名字 on 表名(列名);
刪除:
drop index 索引名字
主要作用:提高查詢效率
在oracle中會自動給主鍵和唯一列 加上索引
注意:并不是說什么情況都需要加索引提高效率,一般是在復雜的表中才需要,
因為他會占用我們的內存資源
六、事務控制 (transaction)
銀行轉賬:
1.驗證賬戶 -- 張三給他的兒子轉賬
2.輸入轉賬金額 -- money 1000
3.更新余額
更新本人賬戶的余額 -- -money 1000
(銀行停電 出現意外 導致系統終止)
更新對方賬戶余額 -- +money
1、是由一條或多條SQL組成,是操作數據庫的最小單位
2、事務的原理:
數據庫會為每一個連接上來的client開辟一小塊內存(回滾段),用于暫時緩存
sql命令的執行結果,當事務結束的時候,需要client給出明確指示:
commit -- 提交事務 永久保存數據
rollback -- 事務回滾 丟棄所有sql的執行結果。
3、事務的邊界
begin:從寫第一條sql開始
end:
3.1 如果是DML命令,那么需要 顯示的輸入commit/rollback
3.2 如果是DDL,那么事務成功后 會自動帶commit/rollback
**注意:正常退出事務會自動提交,如果非正常退出 事務自動回滾;
4. 事務的特性 (ACID)
A 原子性 :組成事務的一組sql是一個不可再分的整體,要么一起成功
要么一起失?。? C 一致性 :當事務結束的時候,保證數據的狀態要與事務操作里的完全一致
I 隔離性 : 多用戶并發訪問數據庫的時候,要保證事務之間不能互相影響
D 持久性 :事務結束的時候,保證事務對數據庫數據的影響是永久性的(持久化)
=============================================================
總結:
一、簡單查詢
select * from 表名 where 條件 group by 條件字段 having 再次篩選條件
order by 可跟多個字段 asc/desc;
二、函數
單行函數
to_char(time,'字符串格式') -- 將日期轉成字符串
to_date('字符串','字符串') -- 將字符串轉成oracle標準日期格式
length(字符串) -- 求字符串長度
分組函數:
sum() -- 求和
avg() -- 求平均值
max() -- 最大值
min() -- 最小值
count() -- 統計數量
三、子查詢
1.結果是一行一列 -- 常用在 where子句 做條件判斷
2.結果是多行一列 -- 常用在 where子句 做條件判斷
3.結果是多行多列 -- 常用在from子句中
偽列:
rownum -- 每次從一開始 只能做 =1 >=1 < <=
***數據庫分頁:
主要是用 子查詢 和rownum 來解決的
四、表鏈接
1.內連接 -- inner join .. on .. 不能處理null值
2.外連接
左外鏈接 -- left join .. on ..
右外鏈接 -- right join .. on ..
全外鏈接 -- full join .. on ..
3.多表連接
oracle中表與表之間的連接 是兩兩連接
4.自連接
把一張表看成兩張表
五、建表
create table 表名(
列名 數據類型 約束
);
1.數據類型
number()
varchar2()
date
2.約束
primary key --主鍵約束 非空 且 唯一
unique -- 唯一約束
not null -- 非空約束
check() -- 檢查約束 也成自定義約束
references -- foreign key 外鍵約束 值必須來自其他表的主鍵或是
唯一列,可以為null,可以重復
六、DML
insert into 表名 (列名 ...) values(對應的值 ...);
update 表名 set 列名 = 新值 where 條件;
delete from 表名 where 條件;
七、DDL
drop table 表名;
drop sequence 序列名;
drop view 視圖名;
drop index 索引名;
alter table 表名 add 列名 數據類型;
八、事務
commit -- 提交事務
rollback -- 事務回滾
1.事務的原理
2.事務的邊界
3.事務的特性 ACID