查看Orcale数据里的表是否有变化

  由于我们公司一个数据库两个应用在使用,导致一个应用修改了数据库,另一个应用用的缓存而不知道有更新还是原来的结果。原来的处理方式是采用session缓存的方式,用户登出了就清空缓存,这样只需要重新登录一次就得到最新的快照放在缓存中了,但现在新的要求是不登出就要实时刷新改了的内容。其实这种方式最好的处理办法是一个应用改了数据库通知另一个应用去刷新缓存,但是线下应用用vb写的成熟的产品,都是一帮老员工很难让他们去改点东西来适合新应用,都是新应用去套他们的。领导本来说直接不用缓存了,每次去读数据库,我觉得这样解决问题太粗暴了,之前的努力都白费了,就想通过一种查询数据库表是否改变了的方式进行折中处理,在应用里记录一个版本号或者最后修改时间,每次先去数据库读一次看看有没有变化,如果有变化就刷新缓存,如果没有变化就用缓存里的。

  我最先想到的是触发器,的确是可以这样实现,但最好不要这样做,因为数据库是另一个项目主要在用,我们不能去过多的改变数据库。我们项目支持的是oracle数据库,user_objects表里有个LAST_DDL_TIME字段,但这个不是我想要的,我想要表DML操作的记录。9i以上可以在user_tab_modifications视图里查找到想要的信息,user_tab_modifications收集自采集信息以来被改变表的dml操作量数据,一个表只有数据量被改变10%以上才会被定期采集信息,也可以执行过程

DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO进行实时采集。

  These views are populated only for tables with
the MONITORING attribute.
They are intended for statistics collection over a long period of time. For
performance reasons, the Oracle Database does not populate these views
immediately when the actual modifications occur. Run
the FLUSH_DATABASE_MONITORING_INFO procedure
in
the DBMS_STATS PL/SQL
package to populate these views with the latest information.
The ANALYZE_ANY system
privilege is required to run this procedure.

  所以用这种方式是不行的,为了时实还得不断地去执行exec
dbms_stats.FLUSH_DATABASE_MONITORING_INFO这个命令,这种方式对数据库操作太多了。

于是有了下面这种方式:ora_rowscn

  oracle 10G开始提供的一个伪列ORA_ROWSCN,它又分为两种模式一种是基于block这是默认的模式(块级跟踪);还有一种是基于row上,这种模式只能在建里表时指定ROWDEPENDENCIES(行级跟踪),不可以通过后期的alter  table语句来将表修改为ROWDEPENDENCIES。我只需要判断这个表有没有被DML语句操作所以只需要用第一种模式就可以了,不需要精确到row上,所以简单用第一种就可以了。

  我们知道,每个Block在头部是记录了该block最近事务的SCN(SystemChangeNumber)的,所以默认情况下,只需要从block头部直接获取这个值就可以了,不需要其他任何的开销,Oracle就能做到这一点。但是这明显是不精确的,一个block中会有很多行记录,每次事务不可能影响到整个block中所有的行,所以这是一个非常不精准的估算值,同一个block的所有记录的ORA_ROWSCN都会是相同的,基本上没有多大的使用价值。

  如果在建表的时候开启行级跟踪选项,Oracle则可以为每一行记录精确的SCN,那么显然不能再直接从block头部获取。要获得足够的信息,肯定要付出一定的代价,Oracle必须为每一行存储这个实际的SCN。所以这个行级跟踪的选项,只能在建表的时候指定,而不能通过alter
table来修改现有的表,否则需要修改每一行记录的物理存储格式,代价是可想而知的。

  在10g之前,很多系统要实现增量数据抽取,要么通过解析日志,要么加触发器,要么就在表上加一个时间截字段。ORA_ROWSCN其实就是第三种方式,只是这个字段由Oracle来维护,这样可以避免一些应用绕过时间截去更新其他字段带来的问题。

第一种方式(块级跟踪):

select ora_rowscn,
       dbms_rowid.ROWID_BLOCK_NUMBER(rowid)
blockid,
       scn_to_timestamp(ora_rowscn)
  from hs_futures.fuentrust
t
 order by scn_to_timestamp(ora_rowscn);

dbms_rowid.ROWID_BLOCK_NUMBER(rowid):是为获取数据所在块的ID

scn_to_timestamp(ora_rowscn):获取数据最所修改的时间

数据发现变化后通过上面SQL语句可以查看到数据最后修改的时间,注意因为是同一个块上,所以这个块上只要有DML操作那么所有数据的scn都更新了,所以凡是跟这条记录在同一个块上数据获取到的ora_rowscn和scn_to_timestamp(ora_rowscn)两个值都发生了相应的变化。

第二种方式(行级跟踪):

create table hs_futures.fuentrust_test1 rowdependencies  as
  select * from hs_futures.fuentrust

用以上语句创建一个基于ROWDEPENDENCIES模式的表,然后用第一种方法中的SQL去查询此表数据中的ora_rowscn,scn_to_timestamp(ora_rowscn)两个值,修改其中的某一条记录然后再去查询那个值发现发生变化的只是被修改那条记录的这两个值发生了变化,而在同一个块中没有被修改的其它记录这两个值是不会产生变化的。

注意DDL操作:只要现有表记录中的数据有发生变化那么SCN肯定就会发生更新,如删除有数据的列,但是如果索引删除/修改/增加及增加/者删除没有任何数据的列那么SCN是不会有任何变化。

  

查看Orcale数据里的表是否有变化,布布扣,bubuko.com

时间: 2024-11-05 21:35:46

查看Orcale数据里的表是否有变化的相关文章

快速恢复update了的orcale数据表

在update的时候 没有写条件 将整个表中的数据全部都更新了,这时候怎么办呢? orcale提供了以下的方法产看某一个时间戳, 所执行的sql的语句内容, 同时可以利用该这个时间戳查看当时语句执行显示的结果 查出需要撤销SQL 的执行时间: SELECT last_load_time, sql_text FROM v$sql WHERE last_load_time IS NOT NULL and sql_text like '%你错误执行的sql%' ORDER BY last_load_t

快速查看SQL Server 中各表的数据量以及占用空间大小

快速查看SQL Server 中各表的数据量以及占用空间大小. CREATE TABLE #T (NAME nvarchar(100),ROWS char(20),reserved varchar(18) ,Data varchar(18) ,index_size varchar(18) ,Unused varchar(18) ) GO INSERT #T EXEC SP_MSFOREACHTABLE 'EXEC sp_spaceused "?"' SELECT * FROM #T O

POSTGRESQL 查看数据库 数据表大小

1.查看数据库大小: select pg_database_size('log_analysis'); ***(Single step mode: verify command)******************************************* select pg_database_size('log_analysis'); ***(press return to proceed or enter x and return to cancel)****************

用命令查看Mysql中数据库、表的空间大小

要想知道每个数据库的大小的话,步骤如下: 1.进入information_schema 数据库(存放了其他的数据库的信息) use information_schema; 2.查询所有数据的大小: select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables; 3.查看指定数据库的大小: 比如查看数据库home的大小 select concat(round(sum(data_length/1024/1024

JFinal里得到表结构的方法总结

JFinal里得到表结构的方法总结: 1.得到已经配置的Model类的表结构.(推荐用法).如下,定义一个User的Model类,这样就可以得到Model类的表结构了.具体实现不明白,请高手指导. public void tableMappingTest(){  Table table = TableMapping.me().getTable(User.me.getClass());    renderText(table.getColumnTypeMap().toString());   }

Hive数据导入——数据存储在Hadoop分布式文件系统中,往Hive表里面导入数据只是简单的将数据移动到表所在的目录中!

转自:http://blog.csdn.net/lifuxiangcaohui/article/details/40588929 Hive是基于Hadoop分布式文件系统的,它的数据存储在Hadoop分布式文件系统中.Hive本身是没有专门的数据存储格式,也没有为数据建立索引,只需要在创建表的时候告诉Hive数据中的列分隔符和行分隔符,Hive就可以解析数据.所以往Hive表里面导入数据只是简单的将数据移动到表所在的目录中! Hive的几种常见的数据导入方式这里介绍四种:(1).从本地文件系统中

spool命令、创建一个表,创建并且copy表,查看别的用户下的表,rowid行地址 索引的时候使用,表的增删改查,删除表,oracle的回收站

  1.spool命令 spool "D:\test.txt" spool off SQL> host cls 2.创建一个表 SQL> --条件(1):有创建表的权限,(2):有表空间 SQL> desc t4; 名称                                      是否为空? 类型 ----------------------------------------- -------- ------------------------

vertica从其他表迁移数据到新表(insert into 语句用法实例)

前面一篇开始学习solr的时候,做了个入门的示例http://blog.csdn.net/zjc/article/details/24414271 .虽然可以检索出内容,但总和想象的结果有差异--比如,检索"天龙"两个字,按常规理解,就应该只出来<天龙八部>才对,可是竟然也会把<倚天屠龙记>检出来.后来研究了一下,发现系统是这样处理的:无论是抽索引时还是分析检索词时,都把所有文字按单字拆开.这样,刚好<倚天屠龙记>里包含"天"和&

优雅的将hbase的数据导入hive表

v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} wgx wgx 2 67 2016-04-02T15:15:00Z 2016-04-02T15:15:00Z 1 233 1332 11 3 1562 15.00 Clean Clean false 7.8 磅 0