zoukankan      html  css  js  c++  java
  • oracle05

    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. Deletetruncate区别

    delete逐条删除,truncate先摧毁表,再重建

    最根本的区别是:deleteDML(可以回滚,还能闪回),truncateDDL(不可以回滚,后面的所事务会讲回滚)

    Delete不会释放空间,truncate(当确定一张表的数据不再使用,应该使用truncate

    delete会产生碎片,truncate不会。

    1.3.2. Hwm-高水位   

    高水位线英文全称为high water mark,简称HWM,那什么是高水位呢

    Oracle数据的存储中,可以把存储空间想象为一个水库,数据想象为水库中的水。水库中的水的位置有一条线叫做水位线,在Oracle中,这条线被称为高水位线(High-warter mark, HWM。在数据库表刚建立的时候,由于没有任何数据,所以这个时候水位线是空的,也就是说HWM为最低值。当插入了数据以后,高水位线就会上涨,但是这里也有一个特性,就是如果你采用delete语句删除数据的话,数据虽然被删除了,但是高水位线却没有降低,还是你刚才删除数据以前那么高的水位。也就是说,这条高水位线在日常的增删操作中只会上涨,不会下跌。

    【高水位对Oracle的应用有什么影响呢?】

    高水位对查询有巨大的影响。而且还浪费空间。

    【解读OracleSelect语句的特性】

    极端例子:数据库有10w条数据,删掉了前面的99999个,我select查询的时候,还是需要扫描10w次,虽然表中只有一条数据。效率还是非常的低!!!!!

    如何解决高水位带来的查询效率问题呢?

    1. 将表数据备份出来,摧毁表再重建(truncate table),然后再将数据导回来。

    2. 收缩表,整理碎片,可使用变更表的语句:alter table 表名 move

    【示例】查看、测试、消除高水位 — 了解

    --之前查看rowid
    SELECT 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';
    
    --之后查看rowid
    SELECT 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,直到手动COMMITROLLBACK结束事务为止。

    那么,Oracle的事务是如何开启的?

    Oracle的事务默认是手动管理事务,事务是自动开启(不需要显式的开启,隐式开启),但一般需要手动提交关闭。

    Oracle事务的开始和结束的触发条件:

    事务的开始:以第一个DML语句(insert update delete)的执行作为开始,即是自动开启的事务。

    事务的结束(以下条件之一):

      显式结束:commitrollback(还是隐式commit

      隐式结束(自动提交):DDLcreate 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 删除一个列

    修改对象的名称:

    作用:

    执行RENAME语句改变表, 视图, 序列, 或同义词的名称。

    l 要求必须是对象的拥有者

    【示例】

    RENAME t_dept TO t_dept_new;
    Table renamed.

    1.4.2. 通过工具来修改表

    操作方式:

    1.5. 删除表DROP TABLE

    1.5.1. 基本语法

    注意:

    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 多个表同时使用同一个序列。

    这个序列是公用的对象。如果你很在意的话,就一个表用一个序列,但大多数情况下,这个主键值(代理主键)没有什么意义的话,可以多个表公用一个序列。

  • 相关阅读:
    计算机是如何启动的
    比特币
    区块链技术
    哈夫曼树与哈夫曼编码
    Prim Algoritm(最小生成树)
    机器学习概述总览
    线性查找算法(BFPRT)
    DFS(深度优先搜索)
    BFS(广度优先搜索)
    (Dijkstra)迪杰斯特拉算法-最短路径算法
  • 原文地址:https://www.cnblogs.com/dongfangshenhua/p/7087648.html
Copyright © 2011-2022 走看看