Table Cluster (P50-P55)
1. Table Cluster定义
Table Cluster 是指一组 table 在一个相同的 block 里共享相同的列并存储相关的内容。当一个table被 cluster 后,一个block将包含不同table中的row。例如,一个block包含的row 同时在employees 和departments中,而不仅仅在某一单独表中。
Cluster Key 是指被Cluster的表的列,例如employees和 departments所共享的列department_id,可以在创建Cluster时或将新的 table 添加到 Cluster时指定 Cluster Key。
Cluster Key Value 指的是被指定为 Cluster Key 的列的指定的行集的值。所有包含相同Cluster Key value 的数据,其物理存储都是在一起的。无论有多少个表的行集包含该值,每个cluster Key Value 在 cluster 或 cluster index 中只存储一次。
如果有好几个表被经常用于查询(特别是多表查询或join查询)查询,那就应该考虑使用 cluster table,因为Table Cluster将不同表中的相关行存储在相同的block里,适当的使用 cluster table可以带来以下好处:
1)减少clustered tables 之间进行join查询的磁盘 I/O
2)减少 clustered tables之间进行join查询的读取时间
3)更少的存储空间,因为 cluster key value 只会存储一次
Cluster table 在以下情况时不应被使用:
1)表的多数访问都是单独查询
2)表经常被 update
3)表经常需要 full table scan
4)表需要 truncating
2. Indexed Cluster 定义
Indexed Cluster 是一个使用index来定位数据的table cluster,是一个建立在Cluster Key 上的B-tree Index。Cluster Index必须在 table cluster 填入数据前建立。
如下例,以department_id 为cluster key来建立名为 employees_departments_cluster的cluster, 由于定义的时候未声明为 HASHKEYS cluster, 所以这个cluster是一个indexted cluster;接下来,我们在这个cluster key上建一个名字为idx_emp_dept_cluster的index。
例:
CRATE CLUSTER employees_departments_cluster (department_id NUMBER(4)) SIZE 512; CREATE INDEX idx_emp_dept_cluster ON CLUSTER employees_departments_cluster;
接下来在cluster上建立employees和departments两个表,同时声明departnemt_id列为cluster key
例:
CREATE TABLE employees(…) CLUSTER employees_departments_cluster(department_id); CREATE TABLE departments(…) CLUSTER employees_departments_cluster(department_id);
最后,在你往employees和departments里添加数据时,数据库会将employees和departments两个表中的每个department对应的所有行存储在相同的data block里。这些行被存储在heap里并以index来进行定位。
下图展示了employees_departments_cluster的存储结构,数据库将department为20和110的employee存储到一起.
B-tree Cluster Index 是以存储数据的block的物理地址来关联cluster key value.例如,以下地址:
20,AADAAAA9d
代表了存储department 20中的employee的block的地址.
Cluster Index 是被单独管理的,与nonclustered table上建立的index一样,并可以与table cluster存在于不同表空间之中.
如果employees和departments两个表没有定义为table cluster,那么数据库将不能保证这
相关联的行会被存储到一起.如下图所示:
3.Hash Clusters定义
Hash Cluster与indexed cluster类似,只不过index key被hash function所替换,没有单独存在的cluster index.在一个hash cluster中,数据就是index.
Hash cluster的key与indexted cluster的key一样,都是一个单一列或组合关键字段.oracle database根据特定的cluster key values,使用一个hash function来产生一系列被称为hash key 的整数.数据库将cluster key hash到一个data block的物理地址.数据库将有相同key value的行存储到一起.
在一个indexed table或index cluster中,oracle使用存放在一个独立index中的key value来定位数据库中的行.在indexed table或indexed cluster中查找或存储一行,最少需要经过两次I/O:
1) 至少一次I/O来在index中查找key value或在index中存储key value
2) 一次I/O来读或写table或cluster中的行
为了在hash cluster中查找或存储一行数据,oracle为每行的cluster key value提供了hash function. Oracle数据库 Hash function的计算结果对应到cluster中的data block, 并对其进行读写.
Hashing是在存储数据时用于提高数据检索速度的一种方法,当以下条件满足时,可以考虑使用hash cluster:
1) 一个表被用于query多于modify
2) hash key所在列经常被使用等于关系进行查询,如 WHERE department_id=20. 对于这个查询,如果 cluster key value已经hash,那么hash key value将直接指向存储相应行的block.
3) 一个表中的行数是可以被合理的计算出来的(用于定义 hash function)
4. Hash cluster creation
建立一个hash cluster时,除了使用 CREATE CLUSTER来创建indexed cluster外,还需要添加HASHKEY关键字,如下例:
CREATE CLUSTER employees_departments_cluster
(department_id NUMBER(4))
SIZE 8192 HASHKEYS 100;
以上, department_id被定义为hash key,在这个例子中HASHKEY声明了department有可能的数目(一般部门数都是可以计算出来的,也就是说表中的行数是可以计算出来的,满足上面的第3个条件).
在这个方案中,用户经常执行的查询如下所示,通过输入不同的p_id来查询不同的department ID
例:
SELECT * FROM employees WHERE department_id = :pid SELECT * FROM departments WHERE department_id = :pid SELECT * FROM departments d, employees e WHERE e.department_id=d.department_id AND d.department_id = :pid
假设用户经常以department_id为20来执行第一个查询, oracle数据库使用20来当成hash function的输入参数,并定位到存储所有在编号为20的department中的employee的block.
上图将一个hash cluster segment以一行blocks的形式展示出来,由此可见,每次数据检索都只需要一次I/O.
Hash Cluster的局限在于:
1) 其不适用于在nonindexed cluster key上进行range scan(区间搜索)
例:
CREATE CLUSTER employees_departments_cluster (department_id NUMBER(4)) SIZE 8192 HASHKEYS 100;
如果以上代码创建的hash cluster上不存在独立的index,那么查询位于20至100的department_id将不能使用hash算法,因为他不能对20至100之间的每一个可能值进行hash.
因为不存在index,则数据库需要进行full scan.
5. Hash Cluster Variations
Single-table hash cluster是一个优化过的,仅支持一个table的hash cluster.在这里,从hash key 到行的映射是一一对应的,当用户需要对单表通过主键进行快速访问时,使用sing-table hash cluster是合适的.例如,用户经常会在employees表里通过employee_id查找employee相关记录.
Sorted hash cluster是hash cluster的一个变种,其内的所有与hash结果相一致的行都已根据指定的列进行升序排序. Sorted hash cluster 允许应用程序对数据进行快速检索,因为数据在插入时已经排好序.例如,一个包含orders表的hash cluster 可以根据 order_date 进行排序.
6. Hash Cluster Storage
Oracle Database对hash cluster的空间分配与index cluster是不一样的.database根据创建cluster的语句里的SIZE和HASHKEYS的乘积得出一个结果.并以字节为单位预分配与此结果一致的空间.
例:
CREATE CLUSTER employees_departments_cluster (department_id NUMBER(4)) SIZE 8192 HASHKEYS 100;
在上例中
,HASHKEYS声明了有可能存在的department数,SIZE声明了每个department所有数据所占的空间大小.
在一个hash cluster中,HASHKEYS的值是固定的.Oracle database并不会根据HASHKEYS来限制在table中可以插入的值,但如果插入的数据远大玩HASHKEYS的值,,对hash cluster的检索效率就会下降,这时应该使用新的HASHKEYS来重建hash cluster.