oracle的表
一、与表相关的几个概念
-
高水位线(High Water Mark):是指表中已经被使用的空间的最高位置。当表中的数据被删除或更新时,高水位线不会立即下降,导致表中有一些空间被浪费。可以通过重新组织表或者压缩表来降低高水位线。
oracle中高水位线永远不会下降,除非使用rebuild、truncated或shrunk这个对象高水位线是一个很有趣的概念,但是也是一个非常重要的概念。 顾名思义,高水位线有点 类型于水文监测站里测水深度的标杆一样,当水涨的时候,水位线随之上升,并在标杆留 下一个水印痕,这个水印痕就是高水位线。
-
PCTFREE:是表中每个数据块保留的空闲空间的百分比。例如,如果PCTFREE设置为20%,那么每个数据块将保留20%的空闲空间,以便在将来插入新数据时可以直接使用而不需要重新分配空间。(表示当数据块的可用空间低于20%后,就不可以被insert了,只能被用于update)
-
PCTUSED:是表中每个数据块被使用的最小百分比。例如,如果PCTUSED设置为40%,那么每个数据块至少要被40%的数据填充才会被认为是"已使用"。
二、表的几种类型包括:
-
普通表:普通表是最基本的表,它存储数据的方式是行模式,数据存储在磁盘上。
-
分区表:分区表是将表按照一定的规则分成多个子表,每个子表称为一个分区,可以提高查询效率和维护性能。
-
索引组织表IOT:索引组织表是一种特殊的表,它的数据存储方式是按照索引的结构来组织的,数据和索引存储在一起,可以提高查询效率。
-
簇表:簇表是将具有相同或者相近的列值存储在一起的表,可以提高查询效率。
-
临时表:临时表是用于存储临时数据的表,它的生命周期只在当前会话或者事务中,当会话或者事务结束时,临时表的数据就会被清空。
-
嵌套表、对象表:嵌套表和对象表是Oracle中的一种高级数据类型,它们允许在表中存储复杂的数据结构,比如嵌套表可以存储数组,对象表可以存储对象。这些数据类型可以提高数据的表达能力和灵活性。
需要创建簇表来提高访问速度的情况包括:
- 当需要频繁地进行范围查询时,例如按照日期范围或者数字范围进行查询。
- 当需要频繁地进行连接操作时,例如将两个表按照某个列进行连接查询。
- 当需要频繁地进行排序操作时,例如对某个列进行排序查询。
三、对表的一些基本操作
在Oracle 11g中,可以使用SQL语句来创建、分配空间、移动、收缩、截断、删除表以及删除列。下面是对每个操作的代码示例:
-
创建表:
sqlCREATE TABLE employees ( employee_id NUMBER(6), first_name VARCHAR2(50), last_name VARCHAR2(50), email VARCHAR2(100), hire_date DATE, salary NUMBER(8,2) );
-
给表分配空间:
sqlALTER TABLE employees STORAGE (INITIAL 1M NEXT 1M);
-
移动表:
Oracle 11g中的MOVE TABLE命令可以将一个表或分区移动到另一个表空间中。它的作用可以是为了优化表的存储,例如将一个大表移动到一个更大的表空间中,或者将一个频繁访问的表移动到更快的磁盘上,以提高查询性能。MOVE TABLE命令也可以用于重建表,例如将表从一个表空间中移动到另一个表空间中,并在此过程中重新组织表的数据、索引等。
MOVE TABLE命令的优点包括: 1. 优化存储:可以将表或分区移动到更适合它的表空间中,从而提高存储效率。 2. 重建表:可以在移动表的同时重建表的结构,例如重新组织数据、索引等,以提高查询性能。 3. 数据迁移:可以将数据从一个表空间中迁移到另一个表空间中,以便在不同的存储介质上存储数据。 MOVE TABLE命令的缺点包括: 1. 需要大量的系统资源:移动大表或分区需要大量的系统资源,包括CPU、内存和磁盘空间等。 2. 可能会导致表的不可用:在移动表的过程中,表可能会暂时不可用,从而影响系统的正常运行。
下面是一个简单的示例,演示如何使用MOVE TABLE命令将一个表移动到另一个表空间中:
sql-- 创建一个表 CREATE TABLE mytable ( id NUMBER, name VARCHAR2(50) ) TABLESPACE users; -- 插入数据 INSERT INTO mytable (id, name) VALUES (1, 'John'); -- 移动表到新的表空间中 ALTER TABLE mytable MOVE TABLESPACE new_users; -- 查询数据 SELECT * FROM mytable;
在这个示例中,我们创建了一个名为mytable
的表,并将其存储在users
表空间中。然后,我们使用MOVE TABLE命令将表移动到new_users
表空间中。在移动表的过程中,Oracle会将表的数据和索引重新组织,以便更好地适应新的存储环境。
-
收缩表:
sqlALTER TABLE employees ENABLE ROW MOVEMENT; ALTER TABLE employees SHRINK SPACE;
-
截断表:
sqlTRUNCATE TABLE employees;
-
删除表:
sqlDROP TABLE employees;
-
删除列:
sqlALTER TABLE employees DROP COLUMN email;
-
对于簇表的创建,可以使用以下示例代码:
sqlCREATE CLUSTER emp_cluster (employee_id NUMBER(6)) SIZE 1024 SINGLE TABLE HASHKEYS 20; CREATE TABLE employees (employee_id NUMBER(6), first_name VARCHAR2(50), last_name VARCHAR2(50)) CLUSTER emp_cluster(employee_id);
需要注意的是,在实际使用中,创建簇表需要根据具体的业务需求和数据访问模式来决定是否使用簇表。
-
索引组织表的创建
索引组织表(Index-Organized Table,IOT)是Oracle数据库中的一种特殊表,它的数据存储方式是按照索引的结构来组织的。与普通表不同,索引组织表的数据和索引存储在一起,而不是分开存储。这种存储方式可以提高查询效率,特别是对于范围查询和覆盖索引查询。
在创建索引组织表时,需要定义一个主键,并且主键的列会被用作索引的键。索引组织表的数据行按照主键的值顺序存储在索引中,这样相邻的数据行会存储在相邻的索引页中,这样可以提高范围查询的性能。此外,由于数据和索引存储在一起,因此在进行覆盖索引查询时,不需要额外的IO操作,也可以提高查询效率。
下面是一个简单的示例,演示如何创建一个索引组织表:
sql-- 创建索引组织表 CREATE TABLE employees_iot ( employee_id NUMBER(6) PRIMARY KEY, first_name VARCHAR2(50), last_name VARCHAR2(50), email VARCHAR2(100), hire_date DATE, salary NUMBER(8,2) ) ORGANIZATION INDEX; -- 插入数据 INSERT INTO employees_iot (employee_id, first_name, last_name, email, hire_date, salary) VALUES (1, 'John', 'Doe', 'john@example.com', '01-JAN-2020', 5000); -- 查询数据 SELECT * FROM employees_iot;
在这个示例中,我们创建了一个名为employees_iot
的索引组织表,定义了employee_id
作为主键。在插入数据和查询数据时,可以发现索引组织表的使用方式与普通表略有不同,但由于数据存储在索引中,因此可以提供更高效的访问性能。
-
分区表的创建
在Oracle 11g中,分区表是一种特殊的表结构,它将表数据分割成多个部分,每个部分称为一个分区。分区表可以根据特定的分区键(例如日期、范围、列表等)将数据存储到不同的物理存储结构中,从而提高查询性能、管理数据和维护数据的效率。
分区表的主要优点包括: 1. 查询性能优化:可以只查询特定分区的数据,而不需要扫描整个表,从而提高查询效率。 2. 管理数据:可以更方便地管理大量数据,例如可以定期删除旧数据或者将历史数据归档到不同的存储介质中。 3. 提高维护效率:可以针对特定分区执行维护操作,例如重建索引或者进行数据压缩。
下面是一个简单的示例,演示如何创建一个基于日期范围的分区表:
sql-- 创建分区表 CREATE TABLE sales ( sales_id NUMBER, sales_date DATE, amount NUMBER ) PARTITION BY RANGE (sales_date) ( PARTITION sales_q1 VALUES LESS THAN (TO_DATE('01-APR-2022', 'DD-MON-YYYY')), PARTITION sales_q2 VALUES LESS THAN (TO_DATE('01-JUL-2022', 'DD-MON-YYYY')), PARTITION sales_q3 VALUES LESS THAN (TO_DATE('01-OCT-2022', 'DD-MON-YYYY')), PARTITION sales_q4 VALUES LESS THAN (MAXVALUE) ); -- 插入数据 INSERT INTO sales (sales_id, sales_date, amount) VALUES (1, TO_DATE('15-JAN-2022', 'DD-MON-YYYY'), 1000); -- 查询数据 SELECT * FROM sales;
在这个示例中,我们创建了一个名为sales
的分区表,根据sales_date
字段进行范围分区。表被分为四个分区,分别对应四个季度。在插入数据和查询数据时,可以根据特定的分区键进行操作,从而提高查询性能和管理数据的效率。