索引组织表的存储组织是主B树的变体。与数据存储为无序集合(堆)的普通(堆组织)表不同,索引组织表的数据以主键排序的方式存储在B树索引结构中。索引结构中的每个叶块都存储键列和非键列。
索引组织表的结构具有以下优点:
-
对主键进行快速随机访问,因为仅索引扫描就足够了。并且,由于没有单独的表存储区域,对表数据的更改(例如添加新行、更新行或删除行)只会导致更新索引结构。
-
对主键的快速范围访问,因为行按主键顺序聚集。
-
由于避免了主键的重复,因此降低了存储要求。它们不像堆组织表那样存储在索引和基础表中。
索引组织的表具有完整的表功能。它们支持约束、触发器、LOB 和对象列、分区、并行操作、在线重组和复制等功能。而且,它们提供以下附加功能:
-
前缀压缩
-
溢出存储区域和特定列放置
-
二级索引,包括位图索引。
索引组织表非常适合需要快速主键访问和高可用性的 OLTP 应用程序。例如,在电子订单处理中使用的订单表的查询和 DML 主要基于主键访问,大量并发 DML 会导致行链接和索引空间使用效率低下,导致频繁需要重组。因为索引组织的表可以在线重组,而不会使其二级索引失效,因此大大减少或消除了不可用窗口。
索引组织表适用于对特定于应用程序的索引结构进行建模。例如,包含文本、图像和音频数据的基于内容的信息检索应用程序需要可以使用索引组织表有效建模的倒排索引。互联网搜索引擎的一个基本组件是倒排索引,可以使用索引组织表进行建模。
这些只是索引组织表的一些应用程序。
创建索引组织表
您使用该CREATE TABLE
语句来创建索引组织的表。
创建索引组织表时,但必须提供其他信息:
-
ORGANIZATION INDEX限定符,表示这是一个索引组织的表
-
主键,通过列约束子句(对于单列主键)或表约束子句(针对多列主键)指定。
或者,您可以指定以下内容:
-
一个
OVERFLOW
子句,通过启用将一些非键列存储在单独的溢出数据段中来保留 B 树索引的密集集群。 -
一个
PCTTHRESHOLD
值,当使用溢出段时,该值定义存储在索引块中的行部分的最大大小,以块大小的百分比表示。将导致行大小超过此最大值的行列存储在溢出段中。该行在列边界处被分成两部分,头部分和尾部分。头块符合指定的阈值,并与索引叶块中的键一起存储。尾段作为一个或多个行段存储在溢出区域中。因此,索引条目包含键值、符合指定阈值的非键列值以及指向行其余部分的指针。 -
一个
INCLUDING
子句,可用于指定要与主键一起存储在索引块中的非键列。
创建索引组织表
一个示例说明了如何创建索引组织表。
以下语句创建一个索引组织表:
CREATE TABLE admin_docindex( token char(20), doc_id NUMBER, token_frequency NUMBER, token_offsets VARCHAR2(2000), CONSTRAINT pk_admin_docindex PRIMARY KEY (token, doc_id)) ORGANIZATION INDEX TABLESPACE admin_tbs PCTTHRESHOLD 20 OVERFLOW TABLESPACE admin_tbs2;
本例创建一个名为admin_docindex的索引组织表,主键由列标记和doc_id组成。OVERFLOW和PCTTHRESHOLD子句指定,如果一行的长度超过索引块大小的20%,那么超过该阈值的列和所有列将被移动到溢出段。溢出段存储在admin_tbs2表空间中。
索引组织表的限制
创建索引组织表时有几个限制。
以下是创建索引组织表的限制。
-
最大列数为 1000。
-
行的索引部分中的最大列数为 255,包括键列和非键列。如果需要超过 255 列,则必须使用溢出段。
-
您可以在主键中包含的最大列数为 32。
-
PCTTHRESHOLD
必须在 1-50 的范围内。默认值为 50。 -
所有键列必须符合指定的阈值。
-
如果行的最大大小超过索引块大小的 50% 并且您没有指定溢出段,则
CREATE
TABLE
语句将失败。 -
索引组织的表不能有虚拟列。
-
当表具有外键并且外键的父表是索引组织表时,当另一个会话更新父表中的非键列时,更新包含外键的行的会话可能会挂起。
例如,考虑一个
departments
表是索引组织表的场景,并且department_id
是它的主键。有一个employees
表,其department_id
列是表的外键departments
。假设一个会话正在更新 is的表department_name
中的一行,而另一个会话正在更新 is 的表中的一行。在这种情况下,更新表的会话可能会挂起,直到更新表的会话提交或回滚。departments
department_id
20
employees
department_id
20
employees
departments
- 包含一个或多个 LOB 列的索引组织表不能并行移动。
创建包含对象类型的索引组织表
索引组织的表可以存储对象类型。
以下示例创建 object type admin_typ
,然后创建一个包含 object type 列的索引组织表admin_typ
:
CREATE OR REPLACE TYPE admin_typ AS OBJECT (col1 NUMBER, col2 VARCHAR2(6)); CREATE TABLE admin_iot (c1 NUMBER primary key, c2 admin_typ) ORGANIZATION INDEX;
还可以创建对象类型的索引组织表。例如:
CREATE TABLE admin_iot2 OF admin_typ (col1 PRIMARY KEY) ORGANIZATION INDEX;
下面的另一个示例显示,索引组织的表有效地存储了嵌套表。对于嵌套表列,数据库在内部创建一个存储表来保存所有嵌套表行。
CREATE TYPE project_t AS OBJECT(pno NUMBER, pname VARCHAR2(80)); / CREATE TYPE project_set AS TABLE OF project_t; / CREATE TABLE proj_tab (eno NUMBER, projects PROJECT_SET) NESTED TABLE projects STORE AS emp_project_tab ((PRIMARY KEY(nested_table_id, pno)) ORGANIZATION INDEX) RETURN AS LOCATOR;
属于单个嵌套表实例的行由nested_table_id列标识。如果使用普通表存储嵌套表列,则嵌套表行通常会去聚集。但是,当使用索引组织的表时,可以基于nested_table_id列对嵌套的表行进行聚类。
选择和监控阈值
选择一个可以容纳您的关键列以及前几个非关键列(如果它们经常被访问)的阈值。
选择阈值后,您可以监视表以验证您指定的值是否合适。您可以使用ANALYZE
TABLE
...LIST
CHAINED
ROWS
语句来确定超过阈值的行数和标识。
使用INCLUDING子句Using the INCLUDING Clause
除了指定PCTTHRESHOLD之外,还可以使用INCLUDING子句控制哪些非键列与键列一起存储在索引组织的表中。
数据库容纳索引叶块中including子句中指定的列之前(包括该列)的所有非键列,前提是它不超过指定的阈值。INCLUDING子句中指定列以外的所有非键列都存储在溢出段中。如果INCLUDING和PCTTHRESHOLD子句冲突,则以PCTTHRESHOLD为准。
注意:Oracle数据库将索引组织表的所有主键列移动到表的开头(按键顺序),以提供高效的基于主键的访问。例如:
CREATE TABLE admin_iot4(a INT, b INT, c INT, d INT, primary key(c,b)) ORGANIZATION INDEX;
存储的列顺序是:c b a d(而不是:a b c d)。根据存储的列顺序,最后一个主键列是b。INCLUDING列可以是最后一个主键列(本例中为b),也可以是任何非键列(即存储列顺序中b之后的任何列)。
以下CREATE TABLE语句与前面“示例:创建索引组织表”中显示的语句类似,但经过修改后创建了索引组织表,其中token_offsets列值始终存储在溢出区域中:
CREATE TABLE admin_docindex2( token CHAR(20), doc_id NUMBER, token_frequency NUMBER, token_offsets VARCHAR2(2000), CONSTRAINT pk_admin_docindex2 PRIMARY KEY (token, doc_id)) ORGANIZATION INDEX TABLESPACE admin_tbs PCTTHRESHOLD 20 INCLUDING token_frequency OVERFLOW TABLESPACE admin_tbs2;
这里,只有token_offset之前的非键列(在本例中仅为单个列)与键列值一起存储在索引叶块中。
并行化索引组织表创建
CREATE TABLE…AS SELECT语句允许您创建一个索引组织的表,并将现有表中的数据加载到该表中。通过包含PARALLEL子句,可以并行完成加载。
以下语句通过从常规表hr.jobs中选择行来并行创建索引组织的表:
CREATE TABLE admin_iot3(i PRIMARY KEY, j, k, l) ORGANIZATION INDEX PARALLEL AS SELECT * FROM hr.jobs;
此语句提供了使用SQL*Loader进行并行批量加载的替代方法。
待续。。。。。。
https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-tables.html#GUID-F3965F25-01CD-464C-B065-025442A6C43F
标签:存储,admin,组织,索引,TABLE,主键 From: https://www.cnblogs.com/wonchaofan/p/16753909.html