1oracle特点:
(1)支持多用户、大事务量的事务处理
(2)数据安全性和完整性控制
(3)支持分布式数据处理
(4)可移植性
oracle体系:
数据库:可以看做oracle就只有一个大数据库实例:由一系列的后台进程和内存结构组成,一个数据库有多个实例
数据文件:数据库的物理存储单位
表空间:对物理数据库上相关数据文件(ORA 或者 DBF 文件)的逻辑映射
用户:用户是在表空间下建立的,用户登陆后只能看到和操作自己的表
2.创建表空间
create tablespace waterboss -----表空间名
datafile 'c:\waterboss.dbf' -----置物理文件名称
size 100m -----表空间的初始大小 (单位:m)
autoextend on -----自动增长,如果存储量超过初始大小,则开始自动扩容
next 10m -----设置扩容的空间大小(每次扩大10m)
3.创建用户
craete user wateruser -----创建用户名
identified by itcast -----设置密码
default tablespace waterboss -----指定默认表空间
4.用户赋权
grant dba to wateruser -----用户赋
5.表的创建、修改与删除
(1)创建表
语法:
create table 表名称(
字段名 类型(长度) 约束,
字段名 类型(长度) 约束,
字段名 类型(长度) 约束
)
数据类型(特别强调:oracle与MySQL数据类型有差异)
字符型
char 固定长度类型,最多存储2000字节
varchar2 可变字符类型,最多存储4000字节
数值型
number
number(5) 最大存得数为99999
number(5,2) 最大存的数为999.99
日期型
date: 精确到秒
timestamp: 精确到秒的小数点后9位
二进制(大数据类型)
clob: 存储字符,最大存4个G
blob: 存储二进制数据,最多存4个G
*真正开发时,存储图像一般不会将其存入数据库,而是存储于本地磁盘
(2)修改表
增加字段语法:
alter table 表名 add (字段1 类型(长度), 字段2 类型(长度))
修改字段语法:
alter table 表名 modify(字段1 类型(长度), 字段2 类型(长度))
修改字段名语法:
alter table 表名 rename column 原字段名 to 新字段名
删除字段语法:
删除一个字段:
alter table 表名 drop column 列名
删除多个字段:
alter table 表名 drop (字段1,字段2...)
删除表:
drop tabel 表名
6.数据增删改:
增:insert into 表名 (字段1,字段2...) values (值1,值2...)
删:update 表名 set 字段 = 值 where 修改条件
改:(1)delete from 表名 where 删除条件
(2)truncate table 表名
注意:执行delete语句时一定要执行commit提交事物
原因:mysql有自动提交功能,oracle没有,需手动提交
truncate删除与delete删除的区别:
1.delete删除数据可以rollback
2.delete删除可能产生碎片,并且不释放空间
3.truncate是先摧毁表结构再重构表结构
7.jdbc连接oracle
jdbc连接MySQL思路结构相同,不同点在于驱动和连接的配置
jdbc连接MySQL和oracle配置对比:
MySQL:
加载驱动:com.mysql.jdbc.Driver
连接字符串:jdbc:mysql://虚拟机的IP:端口号/数据库名
oracle:
加载驱动:oracle.jdbc.driver.OracleDriver
连接字符串(瘦连接):jdbc:oracle:thin:@虚拟机的IP:orcl
8.oracle数据库导入导出
(1)整库
导出: 导出数据库,执行命令会生成一个expdat.dmp备份文件
exp 用户名/密码 full=y ----添加full=y就是整库导出
exp 用户名/密码 full=y file=备份文件名 ----添加file参数即可指定备份文件名称导出
指定备份文件名称导出: 添加file参数即可,不指定file参数值则默认expdat.dmp备份文件
导入:
imp 用户名/密码 full=y
imp 用户名/密码 full=y file=备份文件名 ---指定备份文件导入,file默认值为expdat.dmp备份文件
(2)按用户名
导出
exp 用户名/密码 owner=表名 file=备份文件名
导入
imp 用户名/密码 fromuser=表名 file=备份文件名
(3)按表
导出:
exp 用户名/密码 file=备份文件名 tables=表名1,表名2
*用 tables 参数指定需要导出的表,如果有多个表用逗号分割即可
导入:
imp 用户名/密码 file=备份文件名 tables=表名1,表名2
9.oracle语句查询
聚合统计: ORACLE的聚合统计是通过分组函数来实现的,与MYSQL一致
(1)聚合函数:
求和: sum()
select sum(字段) from 表名 where 条件
求平均: avg()
select avg(字段) from 表名 where 条件
求最大: max()
select max(字段) from 表名 where 条件
求最小: min()
select min(字段) from 表名 where 条件
统计记录个数: count()
select count(*) from 表名 where 条件
分组聚合: group by
select 字段1 from 表名 group by 字段2 ----按字段2分组查询表中的字段1
分组后的条件查询: having
select 字段1 from 表名 group by 字段2 having 条件
* group by 后面不能使用where条件查询 并且having只能用于group by后面的条件
(2)连接查询:
内连接: select * 字段 from 表1,表2,表三 where 关联条件(多个关联条件使用and连接)
左外连接: SQL1999标准语法: select 字段 from 表1 left join 表2 on 关联条件
oracle特有语法: select 字段 from 表1, 表2 where 表1关联字段(+) = 表2关联字段
* 这里意为表2为左表,特点:想要将谁用作左表则在另一个表的关联字段后面加上'(+)'即可作为实现表的左连接
右外链接: 道理和左外相同,不同点在于表的位置不同,这里记住左外即可,如果想使用右外,将两个表调换位置即可
分页查询:
简单分页:
查询前十条:select rownum,t.* from T_ACCOUNT t where rownum<=10
查询第11条到第20条的记录:select * from (select rownum r,t.* from T_ACCOUNT t where rownum<=20) where r>10
注意:rownum是在查询语句扫描每条记录时产生的,所以不能使用“大于”符号,只能使用“小于”或“小于等于” ,只用“等于”也不行
基于排序的分页:
排序查询前十条:select * from (select rownum r,t.* from T_ACCOUNT t where rownum<=20 order by usenum desc) where r>10
排序查询第11条到第20条:select * from (select rownum r,t.* from (select * from T_ACCOUNT order by usenum desc) t where rownum<=20 ) where r>10
注意:ROWNUM 伪列的产生是在表记录扫描是产生的,而排序是后进行的,排序时R已经产生了,所以排序后R是乱的因此需要先使用子句查询排列在使用rownum排序
10.单行函数:
常用函数:
dual:伪表
字符函数:
(1)求字符长度: leng()
select length('ABCD') from dual; ---结果显示:4
(2)求字符串的子串: substr()
select substr('ABCD',2,2) from dual; ---结果显示:BC
(3)字符串拼接: concat()
select concat('ABC','D') from dual; ---结果显示:ABCD
select 'ABC'||'D' from dual; ---结果显示:ABCD
数值函数:
(1)四舍五入函数: round()
select round(100.567) from dual ---结果显示:101
select round(100.567,2) from dual ---结果显示:100.57
(2)截取函数 trunc()
select trunc(100.567) from dual ---结果显示:100
select trunc(100.567,2) from dual ---结果显示:100.56
(3)取模 mod()
select mod(10,3) from dual ---结果显示:1
日期函数:
(1)加月函数: add_months()
select add_months(sysdate,2) from dual
(2)求所在月最后一天函数: last_day()
select last_day(sysdate) from dual
(3)日期截取: trunc()
select TRUNC(sysdate) from dual
select TRUNC(sysdate,'yyyy') from dual ----截取到年,月和日都为1
select TRUNC(sysdate,'mm') from dual ----截取到月,日为1
转换函数:
(1)数字转字符串: to_char()
select TO_CHAR(1024) from dual ----'1024'
(2)日期转字符串: to_char()
select TO_CHAR(sysdate,'yyyy-mm-dd') from dual ----'2018-6-15'
(3)字符转日期: to_char()
select TO_DATE('2018-6-15','yyyy-mm-dd') from dual ----2018-6-15
(4)字符串转数字: to_number()
select to_number('100') from dual
其他函数:
(1)空值函数: nvl()
用法:nvl(检测的值,如果为null的值)
select NVL(NULL,0) from dual
(2)空值函数: nvl2()
用法:nvl2(检测的值,如果不为null的值,如果为null的值);
select PRICE,MINNUM,NVL2(MAXNUM,to_char(MAXNUM) , '不限') from T_PRICETABLE where OWNERTYPEID=1
(3)条件取值: decode()
语法: decode(条件,值 1,翻译值 1,值 2,翻译值 2,...值 n,翻译值 n,缺省值)
方式一: select name,decode( ownertypeid,1,'居民',2,'行政事业单位 ',3,'商业') as 类型 from T_OWNERS
方式二: select name ,(case ownertypeid when 1 then '居民' when 2 then '行政事业单位' when 3 then '商业' else '其它' end ) from T_OWNERS
方式三: select name,(case when ownertypeid= 1 then '居民' when ownertypeid= 2 then '行政事业' when ownertypeid= 3 then '商业' end ) from T_OWNERS
11.集合运算
集合运算,集合运算就是将两个或者多个结果集组合成为一个结果集。集合运算包括:
union all(并集),返回各个查询的所有记录,包括重复记录。
union(并集),返回各个查询的所有记录,不包括重复记录。
intersect(交集),返回两个查询共有的记录。
minus(差集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩余的记录.
12.sql优化
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.
备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。
不要以为 NULL 不需要空间,比如:char(100) 型,在字段建立时,空间就固定了, 不管是否插入值(NULL也包含在内),都是占用 100个字符的空间的,如果是varchar这样的变长字段, null 不占用空间。
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num = 0
3.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or Name = 'admin'
可以这样查询:
select id from t where num = 10
union all
select id from t where Name = 'admin'
5.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)
6.下面的查询也将导致全表扫描:
select id from t where name like ‘%abc%’
若要提高效率,可以考虑全文检索。
7.Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
8.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。
9.select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。
10.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。
11.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
12.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
13.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
14.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
15.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
16.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
17.尽量避免大事务操作,提高系统并发能力。