Wetts's blog

Stay Hungry, Stay Foolish.

0%

数据文件和日志文件是数据库中最重要的文件。它们是数据存储的地方。每个数据库至少有一个与之相关的数据文件,通常情况下不只一个,有很多。数据在数据文件中是如何组织的?要了解这些内容我们首先必须理解什么是表空间(tablespace)、段(segment)、区(extent)、块(block),这些都是oracle数据库在数据文件中组织数据的基本单元。现在我们来理解这些概念。

块是数据存储的物理单位,也是数据文件中最基础的单位,数据直接存储在块上。是oracle空间分配的最小单位。oracle中的块大小常见的有三种,2KB、4KB、8KB。块的大小在数据库创建时就已经固定下来,数据库中每个块的大小都是相同的,而且所有的块都有相同的格式,由“块头+表目录+行目录+空闲空间+数据空间”组成。块头包含着块类型(比如是表块、还是索引块)的信息、磁盘上块的位置等信息。表目录(table directory),如果有的话,包含着此块中存储各行的表的信息(如果一个块中存有多个表中的数据)。行目录(row directory)包含着数据行的描述信息,它是一个指针数组,指示了每一行在数据块中的物理位置。块头、表目录、行目录统称为块开销(block overhead),是oracle原来统计、管理块本身的。剩下的两部分很简单,已经存有数据的就是数据空间,暂时没存的就是空闲空间。

区又叫盘区,是数据文件中一个连续的分配空间,它比块要大,由块组成。有些对象分配空间时可能至少需要两个盘区,比如回滚段,而这两个盘区不一定要求相连。区的大小从一个块到2GB不等

段是oracle数据库中的分配单位,对象如表、索引等都是以段为单位进行分配。当创建一个表时将创建一个表段,创建一个索引时就创建一个索引段。每一个消耗存储空间的对象最终被存储到一个单一的段中。有回滚段、临时段、聚簇段、索引段等。
表空间是一个逻辑容器,它和数据文件关联起来,一个表空间至少有一个数据文件与之关联。一个表空间可以有多个段,一个段只能属于一个表空间。

方案(schema)

方案(schema)又叫模式,是比表空间小一级的逻辑概念,它也是一个逻辑容器。多个用户可能共用一个表空间,那如何区分开每一个用户?那么在表空间中对每个用户都有一个对应的方案,用于保存单个用户的信息。


oracle中存储的层次结构总结如下:

  1. 数据库由一个或多个表空间组成
  2. 表空间由一个或多个数据文件组成,一个表空间包含多个段
  3. 段由一个或多个区组成
  4. 区是数据文件中一个连续的分配空间,由一个或多个块组成
  5. 块是数据库中最小、最基本的单位,是数据库使用的最小的 I/O 单元
  6. 每个用户都有一个对应的方案

“我们可以把 Database 看作是一个大仓库,仓库分了很多很多的房间,Schema 就是其中的房间,一个 Schema 代表一个房间,Table 可以看作是每个 Schema 中的床,Table(床)被放入每个房间中,不能放置在房间之外,那岂不是晚上睡觉无家可归了,然后床上可以放置很多物品,就好比 Table 上可以放置很多列和行一样,数据库中存储数据的基本单元是 Table,现实中每个仓库放置物品的基本单位就是床,User 就是每个 Schema 的主人,(所以 Schema 包含的是 Object,而不是 User),user 和 schema 是一一对应的,每个 user 在没有特别指定下只能使用自己 schema(房间)的东西,如果一个 user 想使用其他 schema(房间)的东西,那就要看那个 schema(房间)的 user(主人)有没有给你这个权限了,或者看这个仓库的老大(DBA)有没有给你这个权限了。换句话说,如果你是某个仓库的主人,那么这个仓库的使用权和仓库中的所有东西都是你的(包括房间),你有完全的操作权,可以扔掉不用的东西从每个房间,也可以放置一些有用的东西到某一个房间,你还可以给每个 User 分配具体的权限,也就是他到某一个房间能做些什么,是只能看(Read-Only),还是可以像主人一样有所有的控制权(R/W),这个就要看这个 User 所对应的角色 Role 了。”

  • 系统权限:是针对 oracle 系统操作而言,例如登陆 create session,创建表:create table 等;
  • 对象权限:是针对对象操作的,例如:查询 select,更新 update 等;
  • 角色权限:角色其实是特定系统权限和对象权限的组合,是一组权限的组合,便于对用户授权,Oracle 内置了一些角色,如经常使用的 connnet、reseource 和 dba 等。

查看 oracle 的角色拥有的哪些权限的 sql

前提是当前用户有查看 dba_sys_privs 的权限,我用的用户有 dba 的角色权限,select grantee,privilege from dba_sys_privs where grantee='RESOURCE' order by privilege;。无 dba 的角色权限时提示表或试图不存在!select grantee,privilege from dba_sys_privs where grantee='CONNECT' order by privilege;

查看用户拥有的角色,拥有的系统权限的 sql

1
2
3
4
select * from user_role_privs;--用户所拥有的oracle角色
select * from user_sys_privs; --用户所用户的系统权限
select * from table_privilege_map;
select * from session_privs;

查看对表 table1 有访问权限的用户

具有一定权限的用户(我测试时是 DBA)使用 select * from dba_tab_privs a where a.table_name='TABLE1' 查看,否则在无权限时提示“表或视图不存在”


用户 user1 和 user2,使用用户 user1 创建表 table1(下面的是本人按照顺序依次执行测试的):

  1. 当 user2 拥有 dba 角色时,执行 sql:select * from user2.teble1; 不会出错,而且可以修改表数据,可以修改表结构等操作;
  2. 当去掉 user2 的 dba 角色时,设置很低的权限,执行上述的 sql,提示“ORA-01031 权限不足”;
  3. 当 user1 登录 oracle,使用 sql:grant select on taleb1 to user2 后,user2 执行上述的查询语句 ok;不能修改,修改后提交时提示“权限不足!”;
  4. 当 user1 执行 sql:revoke select on table1 from user2 后,user2 执行 table1 查询的 sql 时报错,提示“权限不足”。
  5. 当 user1 使用 revoke 或者 grant 语句为自己授权时,提示“ORA-01749 用户不能为自己 revoke/grant 权限”
  6. 当 sys 用户使用 revoke select on user1.table1 from user1 时,oracle 系统提示“ORA-无法REVOKE您未授权的权限”,此时再用 user1 执行把表 table1 的任何权限(也就是 select、insert、update、delete、references、alter、index)授予 sys 或者用用 dba 角色的用户,再使用 sys 执行:revoke select on use1.table1 from user1 时,仍是提示“ORA-无法REVOKE您未授权的权限”.

结论:user1 创建的对象(如表),user1 永久对此表拥有权限,不可删除。

Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术。Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索。使用 XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序。
 
不过,由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。如果能控制数 据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误。

理解同源策略限制

同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。
 
克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。尽管该技术获得了普遍使用,但它是不可伸缩的。另一种方式是使用框架要素在当前 Web 页面中创建新区域,并且使用 GET 请求获取任何第三方资源。不过,获取资源后,框架中的内容会受到同源策略的限制。
 
克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。幸运的是,通过添加 JavaScript Object Notation (JSON) 可以改进该技术。

什么是JSONP?

要了解JSONP,不得不提一下JSON,那么什么是JSON ?

JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.

JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。  

JSONP有什么用?

由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。  

如何使用JSONP?

下边这一DEMO实际上是JSONP的简单表现形式,在客户端声明回调函数之后,客户端通过script标签向服务器跨域请求数据,然后服务端返回相应的数据并动态执行回调函数。
 
HTML代码 (任一 ):

1
2
3
4
5
6
7
8
9
10
11
12
13
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />  
<script type="text/javascript">  
    function jsonpCallback(result) {  
        //alert(result);  
        for(var i in result) {  
            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.  
        }  
    }  
    var JSONP=document.createElement("script");  
    JSONP.type="text/javascript";  
    JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";  
    document.getElementsByTagName("head")[0].appendChild(JSONP);  
</script>  

或者

1
2
3
4
5
6
7
8
9
10
11
12
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />  
<script type="text/javascript">  
    function jsonpCallback(result) {  
        alert(result.a);  
        alert(result.b);  
        alert(result.c);  
        for(var i in result) {  
            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.  
        }  
    }  
</script>  
<script type="text/javascript" src="http://crossdomain.com/services.php?callback=jsonpCallback"></script>  

JavaScript的链接,必须在function的下面。
 
服务端PHP代码 (services.php):

1
2
3
4
5
6
7
8
9
10
<?php  
  
//服务端返回JSON数据  
$arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);  
$result=json_encode($arr);  
//echo $_GET['callback'].'("Hello,World!")';  
//echo $_GET['callback']."($result)";  
//动态执行回调函数  
$callback=$_GET['callback'];  
echo $callback."($result)";  

如果将上述JS客户端代码用jQuery的方法来实现,也非常简单。

1
2
3
$.getJSON

$.ajax

$.get

客户端JS代码在jQuery中的实现方式1:

1
2
3
4
5
6
7
8
9
<script type="text/javascript" src="jquery.js"></script>  
<script type="text/javascript">  
    $.getJSON("http://crossdomain.com/services.php?callback=?",  
    function(result) {  
        for(var i in result) {  
            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.  
        }  
    });  
</script>  

客户端JS代码在jQuery中的实现方式2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript" src="jquery.js"></script>  
<script type="text/javascript">  
    $.ajax({  
        url:"http://crossdomain.com/services.php",  
        dataType:'jsonp',  
        data:'',  
        jsonp:'callback',  
        success:function(result) {  
            for(var i in result) {  
                alert(i+":"+result[i]);//循环输出a:1,b:2,etc.  
            }  
        },  
        timeout:3000  
    });  
</script>  

客户端JS代码在jQuery中的实现方式3:

1
2
3
4
<script type="text/javascript" src="jquery.js"></script>  
<script type="text/javascript">  
    $.get('http://crossdomain.com/services.php?callback=?', {name: encodeURIComponent('tester')}, function (json) { for(var i in json) alert(i+":"+json[i]); }, 'jsonp');  
</script>  

其中 jsonCallback 是客户端注册的,获取 跨域服务器 上的json数据 后,回调的函数。
http://crossdomain.com/services.php?callback=jsonpCallback
这个 url 是跨域服务 器取 json 数据的接口,参数为回调函数的名字,返回的格式为jsonpCallback({msg:'this is json data'})   

Jsonp原理:


首先在客户端注册一个callback, 然后把callback的名字传给服务器。



此时,服务器先生成 json 数据。


然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.



最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。



客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

Ajax由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。

解决方法:

  1. 在你的web中使用后端的语言,比如php、java去请求api接口拿到数据,然后给你web项目
  2. header("Access-Control-Allow-Origin:*");
阅读全文 »

在Tomcat的conf文件夹里有个server.xml文件,修改里面的<Connector port=”80”

Runtime 类的 gc() 和 runFinalization() 方法


gc()

gc()是垃圾回收器,它在回收废弃对象时,会调用将要回收对象的 finalize() 方法

-

runFinalization()

runFinalization() 方法,只是运行 finalize() 方法

Annotation

-

要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法。

-

元注解:

阅读全文 »

加载Spring配置文件时,如果Spring配置文件中所定义的Bean类实现了ApplicationContextAware 接口,那么在加载Spring配置文件时,会自动调用ApplicationContextAware 接口中的

public void setApplicationContext(ApplicationContext context) throws BeansException

阅读全文 »

1
2
3
4
5
6
7
<select id="getTotalBabyAttendCountByKid" resultType="map">
SELECT sum(babysum) babyTotal, sum(brecordsum) babyAttendTotal
FROM attend_babyrecord
WHERE kindergarten_id = #{kid,jdbcType=INTEGER}
AND class_id > 0
AND attend_date = #{attendDate,jdbcType=VARCHAR}
</select>
阅读全文 »

Document

Document 是用来描述文档的,这里的文档可以指一个 HTML 页面,一封电子邮件,或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录的一个字段。

Field

Field 对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。

Analyzer

在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类,它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。

IndexWriter

IndexWriter 是 Lucene 用来创建索引的一个核心的类,他的作用是把一个个的 Document 对象加到索引中来。

Directory

这个类代表了 Lucene 的索引的存储的位置,这是一个抽象类,它目前有两个实现,第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。

Query

这是一个抽象类,他有多个实现,比如 TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成 Lucene 能够识别的 Query。

IndexSearcher

IndexSearcher 是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引,所以可以有多个 IndexSearcher 的实例在一个索引上进行操作。

Hits

Hits 是用来保存搜索结果的。