mysql 的insert语句会锁表吗 数据库insert会锁表吗_oracle insert会锁表吗

郝秉睿

青岛科技研发中心

相信对于分区技术,大家一定都有所了解。但是你知道Oracle一共有多少种分区技术么?它们的适用范围和规范是怎样?今天让我们一起来看一看Oracle分区技术的魅力。

在大型的数据库应用中,需要处理的数据量可以达到几十到几百GB,甚至达到TB级。为了提高对这些巨型数据库的读写和查询速度,Oracle提供了一种分区技术,用户可以在创建表时应用分区技术,将数据以分区形式保存。

01

分区概述

分区是指将巨型的表或索引分隔成相对较小的、可独立管理的部分。分区后的表与未分区的表在执行DML语句时没有任何区别。实际上,对表进行分区后,还可以对每个单独的分区使用CREATE或ALTER等语句进行操作。因此,对巨型表或者索引分区后,可以简化它们的管理与维护操作。

在对表进行分区时,每个分区都具有相同的逻辑属性,例如都具有相同的字段名、数据类型和约束等。不过各个分区的物理属性可以不同,它们可以位于不同的表空间中。

对表进行分区时,必须为表中的每一条记录指定所属分区。一条记录属于哪一个分区是由分区表对该记录的匹配字段决定的。分区字段可以是表中表中一个字段或多个字段的组合,在创建分区表时确定。当用户对分区表进行插入、更新或删除等操作时,Oracle会自动根据分区字段的值来选择存储的分区。

对表进行分区,有如下优点。

增强可用性。表的某个分区出现故障,不影响其他分区的数据使用。

维护方便。如果表的某个分区出现故障,修复该分区即可。

均衡I/O。可以将不同的分区映射到磁盘以平衡I/O,从而改善整个系统性能。

改善查询性能。可以仅搜索某一个分区,从而提高查询性能。

02

创建分区表

Oracle数据库提供了9种对表或索引的分区方法:范围分区、散列分区、列表分区、虚拟列分区、系统分区、间隔分区、参考分区、组合范围散列分区和组合范围列表分区。

1. 范围分区

范围分区就是对数据表中某个值的范围进行分区,例如根据值的大小进行分区。创建范围分区,需要使用PARTITION BY RANGE子句。

例如,有一个学生成绩表ACHIEVEMENT,该表中有一列是学生分数列SCODE。现在创建表ACHIEVEMENT,并根据SCODE列的值的大小进行分区,如下: 



mysql 的insert语句会锁表吗 数据库insert会锁表吗_表分区_02

上面在创建表ACHIEVEMENT时,使用PARTITION BY RANGE子句指定按SCORE列进行范围分区,并按照值的大小将表分为3个区,分别为part1、part2和part3。如果不指定分区名,Oracle将自动对分区进行命名。

其中,VALUES LESS THAN子句用来指定分区的上限(不包含该上限);MAXVALUE关键字用来表示分区中可能的最大值,一般用于设置最后一个分区的上限。

Oracle认为NULL值大于非NULL值,所以如果分区字段的值可以为NULL,则需要为最后一个分区使用MAXVALUE关键字。

例如,使用如下语句向表ACHIEVEMENT中添加3条记录:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_mysql 的insert语句会锁表吗_03

查询表ACHIEVEMENT中的所有数据,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_mysql 的insert语句会锁表吗_04

只查询最后一个分区的数据,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_分区表_05

从查询结果中可以发现,80这个值并没有被包含到第二个分区中去。这说明分区的取值范围中,不包括VALUES LESS THAN子句所指定的上限值。

2. 散列分区

散列分区是通过HASH算法均匀分布数据的一种分区类型。通过在I/O设备上进行散列分区,可以使得分区的大小一致。创建散列分区需要使用PARTITION BY HASH子句。散列分区的主要目的是实现分区平衡。

例如,创建一个散列分区表ACHIEVEMENT,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_数据_06

上面使用PARTITION BY HASH子句,指定按表ACHIEVEMENT中的ID列进行散列分区。

3. 列表分区

列表分区适用于分区列的值为非数字或日期数据类型,并且分区列的取值范围较少时使用。例如,成绩表中的科目列取值较少,就可以应用列表分区。创建列表分区需要使用PARTITION BY LIST子句。

进行列表分区时,需要为每个分区指定一个取值列表,分区列的取值处于同一个列表中的行将被存储到同一个分区中。

例如,创建一个列表分区表ACHIEVEMENT,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_数据_07

上面使用PARTITION BY LIST子句,指定按表ACHIEVEMENT中的SUBJECT列进行列表分区。

例如,使用如下语句向表ACHIEVEMENT中添加4条记录:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_mysql 的insert语句会锁表吗_08

只查询part1分区的表记录,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_分区表_09

4. 虚拟列分区

虚拟列分区就是将其他列引导为虚拟的一列,并在该列上进行分区。Oracle只会保存被引导列中的源数据,不单独保存虚拟列中的数据,整个虚拟列不占内存存储空间。

可将虚拟列分区看作是范围分区、散列分区等的一种特殊形式,只不过其分区列为引导出的虚拟列。

例如,创建一个虚拟列分区表ACHIEVEMENT,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_oracle insert会锁表吗_10

上面在列ACHIEVEMENT.SUBJECT上虚拟出列ACHIEVEMENT.P_SUB,截取列ACHIEVEMENT.SUBJECT中的第一位的值,并在该列上进行列表分区。

5. 系统分区

Oracle 11g开始支持系统分区,与之前的范围分区、散列分区和列表分区不同,系统分区不用指定分区列,也没有算法机制。它通过分区的基表把依赖表的数据平均分布,适用于不能按照范围分区、散列分区和列表分区进行分区,又想把数据均分在不同的分区中,可采用此种方式。创建系统分区需要使用PARTITION BY SYSTEM子句。需要注意的是,系统分区不能进行split拆分。

系统分区与传统分区有如下区别和联系:

传统分区表根据列值进行分区,按照一定的算法(range、hash、list)来决定分区;系统分区表不指定分区列,完全根据系统本身控制数据存储的分区。

传统分区的方式是确定了数据再进行分区;系统分区则分区是分区,数据是数据,两者没有对应关系。数据可以存放在任何一个分区里,存储分区不是由数据本身决定的,而是应用程序在插入数据时决定的。

系统分区的查询方式和传统分区一样,优先查询每个分区,尽量不进行全表扫描。

系统分区建立的时候,不能引用“as select … from”子句,因为系统无法区分数据应该放在哪个分区。当对系统分区表进行DML操作时,只有insert语句需要指明分区,其余的操作不需要。

例如,创建一个系统分区表ACHIEVEMENT,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_数据_11

6. 间隔分区

Oracle 11g推出的间隔分区,是针对范围分区的一种功能拓展。对连续数据类型的范围分区,如果插入的新数据值与当前分区均不匹配,间隔分区可以实现自动的分区创建,省去了DBA的手工增加(add)和拆分(split)操作。

目前的间隔分区支持的范围分区键类型只有NUMBER和DATE两种类型。

创建间隔分区需要使用PARTITION BY RANGE … INTERVAL子句。例如,创建一个分区键类型为NUMBER型的间隔分区表ACHIEVEMENT,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_分区表_12

interval子句用来指出一个分区拓展的规则方案。在上例中,即score列每变化10的时候,进行拓展分区。

使用如下语句向表ACHIEVEMENT中添加4条记录:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_oracle insert会锁表吗_13

 这时会发现,第三条和第四条数据虽然没有建立对应的分区,但是也插入到了表中。此时查看数据字典USER_TAB_PARTITIONS,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_数据_14

接下来,创建一个分区键类型为DATE型的间隔分区表T_INTER,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_mysql 的insert语句会锁表吗_15

7. 参考分区

对于存在外键约束的两张表,如果对主表进行分区,那么通过建立参考分区可以在子表上根据外键约束来对应主表进行分区。通过建立参考分区可以同步存在外键约束的两张表的分区方式。创建参考分区需要使用PARTITION BY REFERENCE子句。

例如,创建两个参考分区表T_PRIMARY和T_FOREIGN,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_oracle insert会锁表吗_16

8. 组合范围散列分区

组合范围散列分区,就是结合范围分区应用与散列分区应用。

例如,创建一个表ACHIEVEMENT,按SCORE列进行进行范围分区,再按ID列进行散列分区,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_mysql 的insert语句会锁表吗_17

上面按SCORE列分为3个分区,然后按ID列分为两个分区。先进行范围分区,再进行散列分区时使用的是SUBPARTITION BY HASH子句。

9. 组合范围列表分区

组合范围列表分区,就是结合范围分区应用与列表分区应用。

例如,创建一个表ACHIEVEMENT,按SCORE列进行范围分区,再按SUBJECT列进行列表分区,如下:



mysql 的insert语句会锁表吗 数据库insert会锁表吗_mysql 的insert语句会锁表吗_18

先进行范围分区,再进行列表分区时使用的是SUBPARTITION BY LIST子句。