数据库分区扩容,实现更高效的数据存储 (数据库分区扩容)

随着互联网和大数据时代的到来,企业数据量越来越大,对数据库的存储和管理提出了更高的要求。传统单机数据库存储已经无法满足当前的需求,一种新的数据库存储方案——分区扩容应运而生。它利用多个小型数据库服务横向扩展来提高数据存储的效率和可扩展性。本文将从定义、实现原理、使用场景及优劣势等方面来详细介绍数据库分区扩容的相关知识。

1.分区扩容的定义与原理

分区扩容技术是将一个大型数据库拆分成多个小分区分别存储,并由多个数据库服务器来管理这些分区。其中,每个分区可以简单理解为一个独立的数据库实例,拥有自己的数据表、索引和存储引擎等。必要时,还可以根据数据特性和操作频率等因素动态地添加或删除分区。

分区扩容的实现原理为将大型数据库按照某种规则(如按日期、按地域等)分割成多个小型数据库,同时将这些小型数据库部署在多个独立的服务器上。每个小型数据库就是一个独立的分区,负责管理自己的数据和索引,同时通过分布式的方式将这些小型数据库整合成一个整体。

2.使用场景

2.1 网络流量大、用户多的应用场景

在互联网应用中,容易出现大量用户同时对同一数据表进行操作,由于单台服务器的处理能力有限,容易造成系统性能瓶颈。采用数据库分区扩容技术,将表数据分布在多个数据库之间,可以更大化地提高系统的并发处理能力,有效缓解服务器压力。

2.2 数据增长快、存储需求高的应用场景

随着数据的不断增长和业务的不断发展,单台服务器存储能力逐渐达到瓶颈。采用分区扩容技术,可以将大型数据库分割成多个小型数据库,分别存储,有效提高总的数据存储能力,同时保证数据的可用性和可靠性。

2.3 海量数据查询分析领域

在大数据分析领域,数据表通常非常大,查询操作也极其复杂,单台服务器的性能无法满足要求。采用分区扩容技术,可以通过分布式架构的方式,将庞大的数据表拆分成多个小型的数据表,利用多台服务器并行查询来提高系统的查询效率。

3. 分区扩容的优劣势分析

3.1 优势

(1)性能优化:通过分区存储、分区索引,提高数据查询和更新的速度。

(2)可扩展性:由于分区数据相互独立,可以方便地分布式扩展,增加服务器数量,提高系统的处理能力。

(3)减轻服务器压力:分区扩容使得多个服务器同时处理数据,分担了单台服务器的负荷,提高了系统的稳定性。

3.2 劣势

(1)成本高:采用分区扩容技术需要多个服务器来支持,需要更多的硬件设备和人力资源。

(2)数据分布不均:分区扩容需要分析数据特点,根据特点尽可能平均地分配数据,否则可能会导致某些服务器过于繁忙,而导致系统性能下降。

4.

综上所述,数据库分区扩容技术是一种有效的大型数据库存储方案,它可以实现数据的分布式存储、并行查询等功能,不仅提高了数据库处理的速度,还可以方便地进行系统扩展和维护。随着互联网和大数据技术的发展,分区扩容技术在实际应用中也得到了广泛的应用,为企业带来了更高效、更可靠的数据处理服务。

相关问题拓展阅读:

Oracle数据库分区表操作方法

在大型的企业应用或企业级的数据库应用中 要处理的数据量通常可以达到几十到几百GB 有的甚至可以到TB级 虽然存储介质和数据处理技术的发展也很快 但是仍然不能满足用户的需求 为了使用户的大量的数据在读写操作和查询中速度更快 Oracle提供了对表和索引进行分区的技术 以改善大型应用系统的性能

  使用分区的优点

  ·增强可用性 如果表的某个分区出现故障 表在其他分区的数据仍然可用

  ·维护方便 如果表的某个分区出现故障 需要修复数据 只修复该分区即可

  ·均衡I/O 可以把不同的分区映射到磁盘以平衡I/O 改善整个系统性能

  ·改善查询性能 对分区对象的查询可以仅搜索自己关心的分区 提高检索速度

  Oracle数据库提供对表或索引的分区方法有三种

  ·范围分区

  ·Hash分区(散列分区)

  ·复合分区

  下面将以实例的方式分别对这三种分区方法来说明分区表的使用 为了测试方便 我们先建三个表空间

  以下为引用的内容

  create tablespace dinya_space

  datafile /test/demo/oracle/demodata/dinya dnf size M

  create tablespace dinya_space

  datafile /test/demo/oracle/demodata/dinya dnf size M

  create tablespace dinya_space

  datafile /test/demo/oracle/demodata/dinya dnf size M

   分区表的创建

   范围分区

  范围分区就是对数据表中的某个值的范围进行分区 根据某个值的范围 决定将该数据存储在哪个分区上 如根据序号分区 根据业务记录的创建日期进行分区等

  需求描述 有一个物料交易表 表名 material_transactions 该表将来可能有千万级的数据记录数 要求在建该表的时候使用分区表 这时候我们可以使用序号分区三个区 每个区中预计存储三千万的数据 也可以使用日期分区 如每五年的数据存储在一个分区上

  根据交易记录的序号分区建表 以下为引用的内容

  SQL> create table dinya_test

   (

   transaction_id number primary key

   item_id number( ) not null

   item_description varchar ( )

   transaction_date date not null

   )

   partition by range (transaction_id)

   (

   partition part_ values less than( ) tablespace dinya_space

   partition part_ values less than( ) tablespace dinya_space

   partition part_ values less than(maxvalue) tablespace dinya_space

   );

  Table created

  建表成功 根据交易的序号 交易ID在三千万以下的记录将存储在之一个表空间dinya_space 中 分区名为:par_ 在三千万到六千万之间的记录存储在第二个表空间

  dinya_space 中 分区名为 par_ 而交易ID在六千万以上的记录存储在第三个表空间dinya_space 中 分区名为par_

  根据交易日期分区建表

  以下为引用的内容

  SQL> create table dinya_test

   (

   transaction_id number primary key

   item_id number( ) not null

   item_description varchar ( )

   transaction_date date not null

   )

   partition by range (transaction_date)

   (

   partition part_ values less than(to_date( yyyy mm dd ))

  tablespace dinya_space

   partition part_ values less than(to_date( yyyy mm dd ))

  tablespace dinya_space

   partition part_ values less than(maxvalue) tablespace dinya_space

   );

  Table created

  这样我们就分别建了以交易序号和交易日期来分区的分区表 每次插入数据的时候 系统将根据指定的字段的值来自动将记录存储到制定的分区(表空间)中

  当然 我们还可以根据需求 使用两个字段的范围分布来分区 如partition

  by range ( transaction_id transaction_date)

  分区条件中的值也做相应的改变 请读者自行测试

   Hash分区(散列分区)

  散列分区为通过指定分区编号来均匀分布数据的一种分区类型 因为通过在I/O设备上进行散列分区 使得这些分区大小一致 如将物料交易表的数据根据交易ID散列地存放在指定的三个表空间中

  以下为引用的内容

  SQL> create table dinya_test

   (

   transaction_id number primary key

   item_id number( ) not null

   item_description varchar ( )

   transaction_date date

   )

   partition by hash(transaction_id)

   (

   partition part_ tablespace dinya_space

   partition part_ tablespace dinya_space

   partition part_ tablespace dinya_space

   );

  Table created

  建表成功 此时插入数据 系统将按transaction_id将记录散列地插入三个分区中 这里也就是三个不同的表空间中

   复合分区

  有时候我们需要根据范围分区后 每个分区内的数据再散列地分布在几个表空间中 这样我们就要使用复合分区 复合分区是先使用范围分区 然后在每个分区内再使用散列分区的一种分区方法 如将物料交易的记录按时间分区 然后每个分区中的数据分三个子分区 将数据散列地存储在三个指定的表空间中

  以下为引用的内容

  SQL> create table dinya_test

   (

   transaction_id number primary key

   item_id number( ) not null

   item_description varchar ( )

   transaction_date date

   )

   partition by range(transaction_date)subpartition by hash(transaction_id)

   subpartitions store in (dinya_space dinya_space dinya_space )

   (

   partition part_ values less than(to_date( yyyy mm dd ))

   partition part_ values less than(to_date( yyyy mm dd ))

   partition part_ values less than(maxvalue)

   );

  Table created

  该例中 先是根据交易日期进行范围分区 然后根据交易的ID将记录散列地存储在三个表空间中

   分区表操作

  以上了解了三种分区表的建表方法 下面将使用实际的数据并针对按日期的范围分区来测试分区表的数据记录的操作

   插入记录

  以下为引用的内容

  SQL> insert into dinya_test values( BOOKS sysdate);

   row created

  SQL> insert into dinya_test values( BOOKS sysdate+ );

   row created

  SQL> insert into dinya_test values( BOOKS to_date( yyyy mm dd ));

   row created

  SQL> insert into dinya_test values( BOOKS to_date( yyyy mm dd ));

   row created

  SQL> insert into dinya_test values( BOOKS to_date( yyyy mm dd ));

   row created

  SQL> insert into dinya_test values( BOOKS to_date( yyyy mm dd ));

   row created

  SQL> mit;

  Commit plete

  SQL>

  按上面的建表结果 年前的数据将存储在之一个分区part_ 上 而 年到 年的交易数据将存储在第二个分区part_ 上 年以后的记录存储在第三个分区part_ 上

   查询分区表记录 以下为引用的内容

  SQL> select * from dinya_test partition(part_ );

  TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

  

   BOOKS : :

   BOOKS : :

  SQL>

  SQL> select * from dinya_test partition(part_ );

  TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

  

   BOOKS

   BOOKS

  SQL>

  SQL> select * from dinya_test partition(part_ );

  TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

  

   BOOKS

   BOOKS

  SQL>

  从查询的结果可以看出 插入的数据已经根据交易时间范围存储在不同的分区中 这里是指定了分区的查询 当然也可以不指定分区 直接执行select * from dinya_test查询全部记录

  在也检索的数据量很大的时候 指定分区会大大提高检索速度

   更新分区表的记录

  以下为引用的内容

  SQL> update dinya_test partition(part_ ) t set em_description= DESK where

  t transaction_id= ;

   row updated

  SQL> mit;

  Commit plete

  SQL>

  这里将之一个分区中的交易ID= 的记录中的item_description字段更新为 DESK 可以看到已经成功更新了一条记录 但是当更新的时候指定了分区 而根据查询的记录不在该分区中时 将不会更新数据 请看下面的例子 以下为引用的内容

  SQL> update dinya_test partition(part_ ) t set em_description= DESK where

  t transaction_id= ;

   rows updated

  SQL> mit;

  Commit plete

  SQL>

  指定了在之一个分区中更新记录 但是条件中限制交易ID为 而查询全表 交易ID为 的记录在第三个分区中 这样该条语句将不会更新记录

   删除分区表记录

  以下为引用的内容

  SQL> delete from dinya_test partition(part_ ) t where t transaction_id= ;

   row deleted

  SQL> mit;

  Commit plete

  SQL>

  上面例子删除了第二个分区part_ 中的交易记录ID为 的一条记录 和更新数据相同 如果指定了分区 而条件中的数据又不在该分区中时 将不会删除任何数据

   分区表索引的使用

  分区表和一般表一样可以建立索引 分区表可以创建局部索引和全局索引 当分区中出现许多事务并且要保证所有分区中的数据记录的唯一性时采用全局索引

   局部索引分区的建立

  以下为引用的内容

  SQL> create index dinya_idx_t on dinya_test(item_id)

   local

   (

   partition idx_ tablespace dinya_space

   partition idx_ tablespace dinya_space

   partition idx_ tablespace dinya_space

   );

  Index created

  SQL>

  看查询的执行计划 从下面的执行计划可以看出 系统已经使用了索引

  以下为引用的内容

  SQL> select * from dinya_test partition(part_ ) t where em_id= ;

  Execution Plan

  

   SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes= )

   TABLE ACCESS (BY LOCAL INDEX ROWID) OF DINYA_TEST (Cost=

   Card= Bytes= )

   INDEX (RANGE SCAN) OF DINYA_IDX_T (NON UNIQUE) (Cost=

  Card= )

  Statistics

  

   recursive calls

   db block gets

   consistent gets

   physical reads

   redo size

   bytes sent via SQL*Net to client

   bytes received via SQL*Net from client

   SQL*Net roundtrips to/from client

   sorts (memory)

   sorts (disk)

   rows processed

  SQL>

   全局索引分区的建立

  全局索引建立时global 子句允许指定索引的范围值 这个范围值为索引字段的范围值

  以下为引用的内容

  SQL> create index dinya_idx_t on dinya_test(item_id)

   global partition by range(item_id)

   (

   partition idx_ values less than ( ) tablespace dinya_space

   partition idx_ values less than ( ) tablespace dinya_space

   partition idx_ values less than (maxvalue) tablespace dinya_space

   );

  Index created

  SQL>

  本例中对表的item_id字段建立索引分区 当然也可以不指定索引分区名直接对整个表建立索引 如

  以下为引用的内容

  SQL> create index dinya_idx_t on dinya_test(item_id);

  Index created

  SQL>

  同样的 对全局索引根据执行计划可以看出索引已经可以使用

  以下为引用的内容

  SQL> select * from dinya_test t where em_id= ;

  Execution Plan

  

   SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes= )

   TABLE ACCESS (BY GLOBAL INDEX ROWID) OF DINYA_TEST (Cost

  = Card= Bytes= )

   INDEX (RANGE SCAN) OF DINYA_IDX_T (NON UNIQUE) (Cost=

  Card= )

  Statistics

  

   recursive calls

   db block gets

   consistent gets

   physical reads

   redo size

   bytes sent via SQL*Net to client

   bytes received via SQL*Net from client

   SQL*Net roundtrips to/from client

   sorts (memory)

   sorts (disk)

   rows processed

  SQL>

   分区表的维护

  了解了分区表的建立 索引的建立 表和索引的使用后 在应用的还要经常对分区进行维护和管理 日常维护和管理的内容包括 增加一个分区 合并一个分区及删除分区等等 下面以范围分区为例说明增加 合并 删除分区的一般操作

   增加一个分区:

  以下为引用的内容

  SQL> alter table dinya_test

   add partition part_ values less than(to_date( yyyy mm dd ))

  tablespace dinya_spa

  ce ;

  Table altered

  SQL>

  增加一个分区的时候 增加的分区的条件必须大于现有分区的更大值 否则系统将提示ORA partition bound must collate higher than that of the last partition 错误

   合并一个分区

  以下为引用的内容

  SQL> alter table dinya_test merge partitions part_ part_ into partition part_ ;

  Table altered

  SQL>

  在本例中将原有的表的part_ 分区和part_ 分区进行了合并 合并后的分区为part_ 如果在合并的时候把合并后的分区定为part_ 的时候 系统将提示ORA cannot reuse lower bound partition as resulting partition 错误

   删除分区

  以下为引用的内容

  SQL> alter table dinya_test drop partition part_ ;

  Table altered

  SQL>

  删除分区表的一个分区后 查询该表的数据时显示 该分区中的数据已全部丢失 所以执行删除分区动作时要慎重 确保先备份数据后再执行 或将分区合并

   总结

lishixinzhi/Article/program/Oracle/202311/17329

开源数据库Sharding技术[1]

从 Shard 到 Sharding

   Shard 这个词英文的意思是 碎片 而作为数据库相关的技术用语 似乎最早见于大型多人在线角色扮演游戏(MMORPG)中的 Sharding 姑且称之为 分片

  Sharding 不是一门新技术 而是一个相对简朴的软件理念 如您所知 MySQL 之后才有了数据表分区功能 那么在此之前 很多 MySQL 的潜在用户源顷都对 MySQL 的扩展性有所顾虑 而是否具备分区功能就成了衡量一个数据库可扩展性与否的一个关键指标(当然不是唯一指标) 数据库扩展性是一个永恒的话题 MySQL 的推广者经常会被问到 如在单一数据库上处带裂哪理应用数据捉襟见肘而需要进行分区化之类的处理 是如何办到的呢? 答案是 Sharding

  Sharding 不是一个某个特定数据库软件附属的功能 而是在具体技术细节之上的抽象处理 是水平扩展(Scale Out 亦或横向扩展 向外扩展)的解决方案 其主要目的是为突破单节点数据库服务器的 I/O 能力限制 解决数据库扩展性问题

  

事关数据库扩展性

  说起数据库扩展性 这是个非常大的话题 目前的商业数据都有自己的扩展性解决方案 在过去相对来说比较成熟 但是随着互联网的高速发展 不可避免的会带来一些计算模式上的演变 这样很多主流商业系统也难免暴露出一些不足之处 比如 Oracle 的 RAC 是采用共享存储机制 对于 I/O 密集型的应用 瓶颈很容易落在存储上 这样的机制决定后续扩容只能是 Scale Up(向上扩展) 类型 对于硬件成本 开发人员的要求 维护成本都相对比较高

  Sharding 基本上是针对开源数据库的扩展性解决方案 很少有听说商业数据库进行 Sharding 的 目前业界的趋势基本上是拥抱 Scale Out 逐渐从 Scale Up 中解放出来

  

Sharding 的应用场景

  任何技术都是在合适的场合下能发挥应有的作用 Sharding 也一样 联机游戏 IM BSP 都是比较适合 Sharding 的应用场景 其共性是抽象出来的数据对象之间的关联数据很小 比如IM 每个用户如果抽象成一个数据对象 完全可以独立存储在任何一个地方 数据对象是 Share Nothing 的 再比如 Blog 服务提供商的站点内容 基本为用户生成内容(UGC) 完全可蠢码以把不同的用户隔离到不同的存储 而对用户来说是透明的

  这个 Share Nothing 是从数据库集群中借用的概念 举例来说 有些类型的数据粒度之间就不是 Share Nothing 的 比如类似交易记录的历史表信息 如果一条记录中既包含卖家信息与买家信息 如果随着时间推移 买 卖家会分别与其他用户继续进行交易 这样不可避免的两个买卖家的信息会分布到不同的 Sharding DB 上 而这时如果针对买卖家查询 就会跨越更多的 Sharding 开销就会比较大

  Sharding 并不是数据库扩展方案的银弹 也有其不适合的场景 比如处理事务型的应用就会非常复杂 对于跨不同DB的事务 很难保证完整性 得不偿失 所以 采用什么样的 Sharding 形式 不是生搬硬套的

  

Sharding与数据库分区(Partition)的区别

  有的时候 Sharding 也被近似等同于水平分区(Horizontal Partitioning) 网上很多地方也用 水平分区来指代 Sharding 但我个人认为二者之间实际上还是有区别的 的确 Sharding 的思想是从分区的思想而来 但数据库分区基本上是数据对象级别的处理 比如表和索引的分区 每个子数据集上能够有不同的物理存储属性 还是单个数据库范围内的操作 而 Sharding 是能够跨数据库 甚至跨越物理机器的

lishixinzhi/Article/program/SQL/202311/16326

关于数据库分区扩容的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 数据库分区扩容,实现更高效的数据存储 (数据库分区扩容)