1. 数据处理
说完了所有的查询,下面说说增、删、改。
1.1. Update
在plsql Developer工具中,加上rowid可以更改数据。
使用工具进行更新数据的操作
在工具中更新数据方式一:
在工具中更新数据方式二:
提示:是否能使用工具修改,主要看语句有没有rowid。
1.2. Insert
1.2.1. 批量插入
语法:
INSERT INTO table VALUES -- 单条插入语法INSERT INTO table SELECT 查询语句 -- 批量插入语法(主要用于将一张表中的数据批量插入到另外一张表中)
--需求:将dept表中部门"名称"不为空的数据都插入到test表中INSERT INTO TEST(ID,NAME) SELECT deptno,dname FROM dept;--select的结果必须能插入到目标表中。(注意:字段个数要对应、字段类型要对应)INSERT INTO TEST SELECT deptno,dname FROM dept;--必须前后字段对应--非法使用批量插入INSERT INTO TEST SELECT deptno,dname,loc FROM dept ;
1.3. Delete
1.3.1. Delete和truncate区别
delete逐条删除,truncate先摧毁表,再重建。
最根本的区别是:delete是DML(可以回滚,还能闪回),truncate是DDL(不可以回滚,后面的所事务会讲回滚)
Delete不会释放空间,truncate会(当确定一张表的数据不再使用,应该使用truncate)
delete会产生碎片,truncate不会。
1.3.2. Hwm-高水位
高水位线英文全称为high water mark,简称HWM,那什么是高水位呢?
在Oracle数据的存储中,可以把存储空间想象为一个水库,数据想象为水库中的水。水库中的水的位置有一条线叫做水位线,在Oracle中,这条线被称为高水位线(High-warter mark, HWM)。在数据库表刚建立的时候,由于没有任何数据,所以这个时候水位线是空的,也就是说HWM为最低值。当插入了数据以后,高水位线就会上涨,但是这里也有一个特性,就是如果你采用delete语句删除数据的话,数据虽然被删除了,但是高水位线却没有降低,还是你刚才删除数据以前那么高的水位。也就是说,这条高水位线在日常的增删操作中只会上涨,不会下跌。
【高水位对Oracle的应用有什么影响呢?】
高水位对查询有巨大的影响。而且还浪费空间。
【解读Oracle中Select语句的特性】
极端例子:数据库有10w条数据,删掉了前面的99999个,我select查询的时候,还是需要扫描10w次,虽然表中只有一条数据。效率还是非常的低!!!!!
如何解决高水位带来的查询效率问题呢?
1. 将表数据备份出来,摧毁表再重建(truncate table),然后再将数据导回来。
2. 收缩表,整理碎片,可使用变更表的语句:alter table 表名 move
【示例】查看、测试、消除高水位 — 了解
--之前查看rowidSELECT t.*,ROWID FROM TEST t; --对表进行分析,收集统计信息(执行了收集信息的动作,user_tables表的块字段才有数据)analyze table TEST compute statistics; --查询表数据的块信息,其中blocks是高水位,empty_blocks是预申请的块空间。select table_name,blocks,empty_blocks from user_tables where table_name='TEST';--收缩表(整理碎片),降低高水位,消除行移植和行链接,不释放申请的空间ALTER TABLE TEST MOVE;--对表进行分析,收集统计信息(执行了收集信息的动作,user_tables表的块字段才有数据)analyze table TEST compute statistics; --查询表数据的块信息,其中blocks是高水位,empty_blocks是预申请的块空间。select table_name,blocks,empty_blocks from user_tables where table_name='TEST';--之后查看rowidSELECT t.*,ROWID FROM TEST t;
结论:
收缩表之后,高水位线下降了。
收缩表之后,rowid发生了变化。
注意:
move最好是在空闲时做,记得move的是会产生锁的(如果你move的时候需要很长事件,那么别人是不能操作这张表的。排他锁)
move以后记得重建index(后续讲到索引,你会知道索引存放的其实就是数据的地址信息。当数据的地址变动了,索引也会失效。)
语法:ALTER INDEX 索引名字 REBUILD;
1. 数据库事务
1.1. 什么是数据库事务?
事务是保持数据的一致性,它由相关的DDL或者DML语句做为载体,这组语句执行的结果要么一起成功,要么一起失败。
1.2. 事务的特性
SQL92标准定义了数据库事务的四个特点(ACID):
原子性 (Atomicity) :一个事务里面所有包含的SQL语句是一个执行整体,不可分割,要么都做,要么都不做
一致性 (Consistency) :事务开始时,数据库中的数据是一致的,事务结束时,数据库的数据也应该是一致的
隔离性 (Isolation): 多个事务并发的独立运行,而不能互相干扰,一个事务修改,新增,删除数据在根据当前事务的事务隔离级别基础上,其余事务能看到相应的结果(这里为什么这么说,下面我会给我具体的例子进行分析)
持久性 (Durability) : 事务被提交后,数据会被永久保存
1.3. 事务的开始和结束
Oracle的默认事务开启和结束是跟mysql不一样的。
回顾:mysql的事务是如何开启的?
MySQL默认采用autocommit模式运行。这意味着,当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中,不需要手动提交。
如果需要手动管理事务,需要显式的关闭自动事务:Set autocommit false,然后显式的手动开启事务:START TRANSACTION,直到手动COMMIT或ROLLBACK结束事务为止。
那么,Oracle的事务是如何开启的?
Oracle的事务默认是手动管理事务,事务是自动开启(不需要显式的开启,隐式开启),但一般需要手动提交关闭。
Oracle事务的开始和结束的触发条件:
事务的开始:以第一个DML语句(insert update delete)的执行作为开始,即是自动开启的事务。
事务的结束(以下条件之一):
显式结束:commit, rollback(还是隐式commit)
隐式结束(自动提交):DDL(create table…)和DCL(所以不能回滚),exit(事务正常退出)
隐式回滚(系统异常终止):关闭窗口,死机,掉电。
工具上的事务按钮:
隐式提交:
提示:一般情况下,我们尽量使用手动提交事务。
1.4. 控制事务-保留点SAVEPOINT—了解
事务过程中是可以控制的,通过SAVEPOINT语句。
SAVEPOINT的作用:
使用 SAVEPOINT 语句在当前事务中创建保存点,语法:SAVEPOINT 保留点名称。
使用 ROLLBACK 语句回滚到创建的保存点。语法:ROLLBACK TO 保留点名称。
SELECT * FROM TEST;INSERT INTO TEST VALUES(85,NULL);SELECT * FROM TEST;SAVEPOINT aa;--保留点INSERT INTO TEST VALUES(86,NULL);--后悔了,不插入了SELECT * FROM TEST;--回滚ROLLBACK TO aa;SELECT * FROM TEST;INSERT INTO TEST VALUES(87,NULL);SELECT * FROM TEST;--提交COMMIT;SELECT * FROM TEST;
注:当前事务提交后,事务中所有的保存点将被释放。
JAVA中也有关于保留点的API
具体调用采用Connection对象来操作它,相关方法如下:
1. 数据库对象-表(TABLE)
1.1. 什么是数据库对象?
数据库对象,是数据库的组成部分,有表(Table )、索引(Index)、视图(View)、用户(User)、触发器(Trigger)、存储过程(Stored Procedure)、图表(Diagram)、缺省值(Default)、规则(Rule)等。
1.2. 表的命名规则和命名规范
表名和列名的基本规范如下:
【扩展】
另外,每个公司都有自己特有的命名规范,比如,要求所有的数据库对象都要加上一个前缀,用于快速识别对象的类别。
比如表的命名:
t_person :存放个人信息的表。
t_crm_person:存放客服子系统模块的人员信息表。
视图的命名:
v_person:用来查询人员信息的视图。
命名规范的作用:
良好的命名规范便于识别和管理,对于系统开发和维护都有很大的帮助。
使用工具的提示功能也更容易快速定位到所需要的对象。
1.3. 创建表CREATE TABLE
1.3.1. 基本语法
创建表的要求条件:
必须具备CREATE TABLE权限、存储空间。
必须指定表名、列名、数据类型、数据类型的大小
1.3.2. 复制表
语法:
Create table 新表 as select from 旧表 条件(如果条件不成立,则只复制结构,如果条件成立,复制结构和值)
使用子查询创建表,而且还可以将创建表和插入数据结合起来。
【示例】
--复制一张和原来一模一样的新表,包含数据
--复制一张和原来一模一样的新表,包含数据CREATE TABLE t_dept AS SELECT * FROM dept;SELECT * FROM t_dept--复制一张和原来一模一样的新表,不要数据,只要结构CREATE TABLE t_dept_empty AS SELECT * FROM dept WHERE 1<>1;SELECT * FROM t_dept_empty;---t_dept,在现网(正式环境)确实要 测试一下数据.一般我们可以在建立一张和这个一模一样的表.c--能不能只复制部分字段建立新表?可以!--复制表的部分字段CREATE TABLE t_dept_part AS SELECT deptno,dname FROM dept;SELECT * FROM t_dept_part;
提示:
复制表有没有数据的区别,是select子句结果有没有数据。如果子句结果没有数据,则仅创建表,如果有数据,则创建表的同时也插入符合条件的数据。
注意:
指定的列和子查询中的列要一一对应
通过列名和默认值定义列
关于where 1=1的写法,一般我们用来拼凑条件的。
1<>1是为了营造一个永远不成立的条件。
1.3.3. Oracle的数据类型
1.4. 修改表ALTER TABLE
1.4.1. 基本语法
修改表的列:
修改表的列的能力:
l 追加新的列
l 修改现有的列
l 删除一个列
修改对象的名称:
作用:
l 执行RENAME语句改变表, 视图, 序列, 或同义词的名称。
l 要求必须是对象的拥有者
【示例】
RENAME t_dept TO t_dept_new;Table renamed.
1.4.2. 通过工具来修改表
操作方式:
1.5. 删除表DROP TABLE
1.5.1. 基本语法
注意:
l 数据和结构都被删除。
l 所有正在运行的相关事物被提交。(ddl语句)
l 所有相关索引被删除。(表附属对象会被删除)
l DROP TABLE 语句不能回滚,但是可以闪回。
完整的oracle数据库的版本的情况下,普通用户删除的表,会自动放入回收站
你可以从回收站还原(闪回)。
友情提示:
日常操作中,删除操作一定要小心,一旦删除了且没有放入回收站,则意味着数据的丢失!
记住一句话:数据无价!!!
1. 约束
1.1. 约束的概念作用
l 约束是可以更好的保证数据库数据的完整性和一致性的一套机制。
l 约束可以限制加入表的数据的类型。
l 如果存在依赖关系,约束可以防止错误的删除数据,也可以级联删除数据。
数据库的约束可以认为是对表的数据的一种规则。
1.2. 约束创建的时机
l 创建表的时候,同时创建约束。
l 表结构创建完成后,可以再添加约束。
l 不建议表内添加数据之后再添加约束,约束可能会和数据起冲突;
1.3. 常见的约束类型
l NOT NULL
l UNIQUE
l PRIMARY KEY
l FOREIGN KEY
l DEFAULT
l CHECK—用来检查一个字段的值是否符合某表达式,表达式的结果必须是布尔值。
其中:check约束是Oracle特有的约束。
1.4. 通过工具快速添加约束
通过工具快速得到SQL的代码:
插入数据测试Check约束
1.5. 约束的应用选择
在应用开发中,主键约束一般要设置,其他如非空、唯一、默认值、检查等约束,可以根据实际情况来添加。
而外键约束是否要设置,是存在一点争议的。(争议在性能上)
一般建议:
l 在大型系统中(安全要求高,性能要求不高),可以使用外键;在大型系统中(性能要求高,安全自己控制),不用外键;小系统随便。
l 不用外键的话,可以用程序控制数据一致性和完整性,可以在代码的数据层通过代码来保证一致性和完整性。
l 用外键要适当,不能过分追求。
从JAVA开发的角度上说,一般不建议使用外键,除了性能外,使用程序控制业务更灵活。
比如客户和订单,这两个之间的关联虽然可以建立外键关系,实现级联效果(如级联删除)。
l 如果有外键约束,则删除客户的时候,必须先删除客户下的订单,否则,不允许删除。
l 从数据完整一致性的角度上说,如果客户被删除了,订单也无意义了,这是合理的。
l 但从业务角度上说,客户被删除了,是否意味这订单也必须删除呢?单纯保留订单的行为也是合理的。
1. 序列-sequence
需求:
Mysql中主键有自增长的特性.
Oracle中,主键没有自增长这个特性.那么如何解决这个问题.使用序列可以解决.
1.1. 概念和作用
序列:可供多个用户来产生唯一数值的数据库对象
. 自动提供唯一的数值
. 共享对象
. 主要用于提供主键值
. 将序列值装入内存可以提高访问效率
这个是Oracle特色的。Mysql是没有的。
简单的说,他可以用来高效的生成主键值。
其实,mysql中的自增长和oracle中的序列效果是一样的
1.2. 语法
将序列提前装入内存,可以提高效率。
1.3. 创建序列
【示例】
创建一个简单的序列
CREATE SEQUENCE seq_test;
1.4. 序列的使用
在ORACLE中为序列提供了两个伪列:
1, NEXTVAL 获取序列对象的下一个值(指针向前移动一个,并且获取到当前的值。)
2, CURRVAL 获取序列对象当前的值
【示例】
查询当前序列---失败
为什么?
原因是:序列初始化之后指针在第一个数之前。必须先向前移动才可以查询的到。
数组的指针默认在1之前,并没有指向第一个值,要想使用必须向前移动一下。(指针只能向前不能向后)
将指针向前移动一位,获取下一个序列数据。
显示当前序列数据,即上面所说的下一个序列数据
1.5. 序列的应用
Oracle建表的时候是否能像mysql那样设定一个自增长的列吗?
不行!
那如何解决呢?使用序列!
【示例】在插入数据的时候插入序列主键.
--在插入数据的时候插入序列主键.INSERT INTO TEST VALUES(seq_test.nextval,'Jack');
问题:为什么这个值不是从1开始?
原因: 共享对象 序列是个独立对象.谁都能用,谁都能共享它.
1.6. 序列的裂缝
1, 序列是一个共有对象,多个表都可以调用。但实际开发中,可以避免多个表用一个序列(创建多个序列)。
序列是独立的对象。任意表都可以使用,但是编号就不能保证有序。
2,当插入记录时报错,序列对象值也被使用,下一次再使用时,序列的值就会+1
【示例】序列的裂缝
INSERT INTO T_TESTSEQ VALUES(seq_test.nextval,'张三1');ROLLBACK;INSERT INTO T_TESTSEQ VALUES(seq_test.nextval,'张三2');COMMIT;SELECT * FROM T_TESTSEQ;
也就是说,用序列插入数据库的值不一定是连续的。
补充:
Mysql的自增长列也可以是不连续的.
序列出现裂缝的条件:
l 事务回滚。
l 系统异常。
l 多个表同时使用同一个序列。
这个序列是公用的对象。如果你很在意的话,就一个表用一个序列,但大多数情况下,这个主键值(代理主键)没有什么意义的话,可以多个表公用一个序列。