PostgreSQL技术大讲堂 - 第24讲:TOAST技术

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: PostgreSQL从小白到专家,技术大讲堂 - 第24讲:TOAST技术

PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUG PG技术大讲堂。

第24讲:TOAST技术

内容1 : Toast简介

内容2 : Toast的存储方式

内容3 : Toast4种压缩策略

内容4 : Toast表的计算方式

内容5 : Toast表的优点与缺点

内容6 : 与Oracle大对象存储方式对比


Toast简介

· Toast技术产生背景

元组不允许跨页面存储

· TOST技术特点

Toast是超长字段在PG的一个存储方式

全称The OverSized Attribute Storage Technique(超尺寸字段存储技术)

它会将大字段值压缩或者分散为多个物理行来存储

对于用户来说不用关注这一技术实现,完全是透明的


Toast的存储方式

· PG的部分类型数据支持toast,因为有些字段类型是不会产生大字段数据(比如date,time,boolean等)

· 支持Toast的数据类型应当是可变长度的(variable-length)

· 表中任何一个字段有Toast,这个表都会有这一个相关联的Toast表,OID被存储在pg_class.reltoastrelid里

· 超出的的数值将会被分割成chunks,并且最多toast_max_chunk_size 个byte(缺省是2KB)

· 当存储的列长度超过toast_tuple_threshold值(通常是2KB),就会触发toast存储

· toast将会压缩或者移动字段值直到超出部分比toast_tuple_targer值小(这个值通常也是2KB)。


建表时自动创建Toast表

--创建表

create table toast_t(id int,vname varchar(48),remark text);

--其中remak数据类型是text,列值长度超过2KB则就会自动产生toast表来存储。


更改表的存储方式为Toast

语法:

ALTER TABLE toast_t ALTER COLUMN vname

SET STORAGE {PLAIN | EXTENDED | MAIN | EXTERNAL};

示例:

create table toast_t1(dd character varying);

alter table toast_t1 alter column dd set storage main;


/d+ toast_1

Column | Type | Storage |

--------+-----+---------+-

dd | character varying | main |

Access method: heap


查看Toast表的名字

--查看tost表的oid

testdb=# select relname,relfilenode,reltoastrelid from pg_class where relname='toast_t1';

relname | relfilenode | reltoastrelid

----------+-------------+---------------

toast_t1 | 16385 | 16389

--根据tost表oid查看其名字

testdb=# select relname from pg_class where oid = '16389';

relname

----------------

pg_toast_16385


Toast4种策略

策略:PLAIN

说明:避免压缩和行外存储。

只有那些不需要 TOAST 策略就能存放的数据类型允许选择(例如 int 类型),而对于 text 这类要求存储长度超过页大小的类型,是不允许采用此策略的。

策略:MAIN

说明:允许压缩,但不许行外存储。

不过实际上,为了保证过大数据的存储,行外存储在其它方式(例如压缩)都无法满足需求的情况下,作为最后手段还是会被启动。因此理解为尽量不使用行外存储更贴切。

策略:EXTENDED

说明:允许行外存储和压缩。

一般会先压缩,如果还是太大,就会行外存储

策略:EXTERNA

说明:允许行外存储,但不许压缩。

类似字符串这种会对数据的一部分进行操作的字段,采用此策略可能获得更高的性能,因为不需要读取出整行数据再解压。


Toast表额外的三个字段

字段名:chunk_id

属性:标识TOAST表的OID字段

字段名:chunk_seq

属性:chunk的序列号,与chunk_id的组合唯一索引可以加速访问

字段名:chunk_data

属性:存储TOAST表的实际数据

--查看tost表oid

testdb=# select relname,oid,rreltoastrelid from pg_class where relname='toast_t1';

relname | relfilenode | reltoastrelid

----------+-------------+---------------

toast_t1 | 16385 | 16389

--查看tost表结构,tost表属于pg_tost模式

testdb=# \d+ pg_toast.pg_toast_16385

Column | Type | Storage

------------+---------+---------

chunk_id | oid | plain

chunk_seq | integer | plain

chunk_data | bytea | plain


Toast表的计算

计算一个表的大小时要注意统计Toast的大小,因为对超长字段存储时,在基础表上可能只存了20%,另外的数据都存到了Toast里面去了,计算大小时要结合起来看

索引也是一样,对于表里有extended或者EXTERNA 类型的会创建Toast表,两者的关联是通过pg_class里的OID去关联的


· Toast表的计算案例(一)

testdb=# create table toast_t(id int,vname varchar(48),remark text);

CREATE TABLE

testdb=# select relname,oid from pg_class where relname = 'toast_t';

relname | oid

---------+-------

toast_t | 16392

testdb=# select relname,reltoastrelid from pg_class where relname = 'toast_t';

relname | reltoastrelid

---------+---------------

toast_t | 16395

testdb=# select relname from pg_class where oid = '16395';

relname

----------------

pg_toast_16392


· Toast表的计算案例(二)

--插入数据,此时remark列值长度小于2KB,所以不会触发tost存储:

insert into toast_t

select generate_series(1,4),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',2000);

--查看表中列值大小:

testdb=# select pg_column_size(id),pg_column_size(vname),pg_column_size(remark) from toast_t limit 10;

pg_column_size | pg_column_size | pg_column_size

----------------+----------------+----------------

4 | 29 | 851

4 | 29 | 851

4 | 29 | 851

4 | 29 | 851


· Toast表的计算案例(三)

--查看基础表和 Toast 的大小

testdb=# select pg_size_pretty(pg_relation_size('toast_t'));

pg_size_pretty

----------------

8192 bytes

--查看tost表尺寸

testdb=# select pg_size_pretty(pg_relation_size('16395'));

pg_size_pretty

----------------

0 bytes

此时remark列值长度小于2KB,所以不会触发tost存储。


· Toast表的计算案例(四)

--remark列值超过 2kb 左右时触发了tost存储方式

insert into toast_t select generate_series(3,4),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',5500);

testdb=# select pg_size_pretty(pg_relation_size('16395'));

pg_size_pretty

----------------

8192 bytes


· Toast表的计算案例(五)

--查看各列的数据变化,说明在列尺寸超过2k的时候就会把数据存放到toast表中:

testdb=# select pg_column_size(id),pg_column_size(vname),pg_column_size(remark) from toast_t;

pg_column_size | pg_column_size | pg_column_size

----------------+----------------+----------------

4 | 29 | 851

4 | 29 | 851

4 | 29 | 851

4 | 29 | 851

4 | 29 | 1651

4 | 29 | 1651

4 | 29 | 2247

4 | 29 | 2247


· Toast表的计算案例(六)

--继续插入更多的数据:

insert into toast_t select generate_series(1,2),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',10000);

--查看toast表大小:

testdb=# select pg_size_pretty(pg_relation_size('16395'));

pg_size_pretty

----------------

16 kB

--继续插入更多的数据,20000

可以看到后插入的数据随着字段内容的增多,toast 段一直在变大。基础表的大小没有变化。这个和 Oracle 存储的大字段内容比较像,Oracle 存储 Blob和clob 类的数据时也是指定另外的 segment 来存储,而不是在原表中存储,当然可以设置 enable storage in row 来指定表中存储


Toast表的优点

1.可以存储超长超大字段,避免之前不能直接存储的限制

2.物理上与普通表是分离的,检索查询时不检索到该字段会极大地加快速度

3.更新普通表时,该表的Toast数据没有被更新时,不用去更新Toast表


Toast表的缺点

1.对大字段的索引创建是一个问题,有可能会失败,通常不建议在大字段上创建,全文检索是一个解决方案

2.大字段的更新会有点慢,其它DB也存在相同问题


Oracle大对象段存储特点

11g版本中推出了针对 LOB字段处理的新技术:SecureFiles

该技术在性能、可管理性、易用性等方面,具有如下具体特点和优势:

· 提供数据去重、压缩和透明加密功能

· SecureFiles不仅可以有效降低LOB字段存储空间消耗,提高了访问效率,而且提高了LOB字段的数据安全性。


以上述某系统为例,我们将其中一个100GB的LOB字段转换为SecureFiles,并采用压缩技术之后,最终只消耗30GB空间,大大压缩了存储空间。

·新的网络协议

SecureFiles提供一种新的Client/Server方式的内部读写机制,有效提高了大量数据传输的效率。

· 简化物理属性设计和管理

SecureFiles提供了大量自动化的物理属性机制,免去了大量物理属性设计和管理工作。例如:CHUNK属性为可变长,最大能支持到64M;Oracle能自动进行碎片整理;

· SecureFiles还自动进行redo和undo的管理,避免大量不必要的redo和 undo信息的产生。


以上就是【PostgreSQL从小白到专家】第24讲 - TOAST技术  的内容,欢迎一起探讨交流钉钉交流群:35,82,24,60,往期视频及文档内容联系CUUG

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
监控 关系型数据库 MySQL
10亿数据如何最快速插入MySQL:技术干货分享
【8月更文挑战第2天】在大数据时代,处理并快速插入数十亿条数据到MySQL数据库是许多企业面临的关键挑战。本文将深入分享一系列高效的技术策略和实战经验,帮助读者优化这一过程,确保数据能够快速、准确地进入数据库系统。
190 1
|
7天前
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
27 3
|
1月前
|
XML 关系型数据库 MySQL
MySQL 导出某些数据的技术详解
MySQL 导出某些数据的技术详解
127 2
|
2月前
|
存储 关系型数据库 MySQL
技术解析:MySQL中取最新一条重复数据的方法
以上提供的两种方法都可以有效地从MySQL数据库中提取每个类别最新的重复数据。选择哪种方法取决于具体的使用场景和MySQL版本。子查询加分组的方法兼容性更好,适用于所有版本的MySQL;而窗口函数方法代码更简洁,执行效率可能更高,但需要MySQL 8.0及以上版本。在实际应用中,应根据数据量大小、查询性能需求以及MySQL版本等因素综合考虑,选择最合适的实现方案。
360 6
|
1月前
|
关系型数据库 MySQL 数据库
MySQL技术深度解析:每次最大插入条数探秘
MySQL技术深度解析:每次最大插入条数探秘
49 0
|
1月前
|
关系型数据库 MySQL 数据库管理
MySQL技术指南:如何更改数据字段的前几位数字
MySQL技术指南:如何更改数据字段的前几位数字
54 0
|
1月前
|
消息中间件 监控 关系型数据库
MySQL数据实时同步到Elasticsearch:技术深度解析与实践分享
在当今的数据驱动时代,实时数据同步成为许多应用系统的核心需求之一。MySQL作为关系型数据库的代表,以其强大的事务处理能力和数据完整性保障,广泛应用于各种业务场景中。然而,随着数据量的增长和查询复杂度的提升,单一依赖MySQL进行高效的数据检索和分析变得日益困难。这时,Elasticsearch(简称ES)以其卓越的搜索性能、灵活的数据模式以及强大的可扩展性,成为处理复杂查询需求的理想选择。本文将深入探讨MySQL数据实时同步到Elasticsearch的技术实现与最佳实践。
85 0
|
2月前
|
SQL 关系型数据库 MySQL
MySQL技术安装配置、数据库与表的设计、数据操作解析
MySQL,作为最流行的关系型数据库管理系统之一,在WEB应用领域中占据着举足轻重的地位。本文将从MySQL的基本概念、安装配置、数据库与表的设计、数据操作解析,并通过具体的代码示例展示如何在实际项目中应用MySQL。
89 0
|
3月前
|
SQL 存储 关系型数据库
mysql加索引真的会锁表吗?揭秘背后的技术细节与规避策略
【8月更文挑战第16天】在数据库管理中,添加索引能大幅提升查询效率。MySQL执行此操作时的锁定行为常引起关注。文章详细解析MySQL中索引添加时的锁定机制及其原理。不同存储引擎及SQL语句影响锁定策略:MyISAM需全表锁定;InnoDB提供更灵活选项,如使用`ALTER TABLE... LOCK=NONE`可在加索引时允许读写访问,尽管可能延长索引构建时间。自MySQL 5.6起,在线DDL技术可进一步减少锁定时间,通过`ALGORITHM=INPLACE`和`LOCK=NONE`实现近乎无锁的表结构变更。合理配置这些选项有助于最小化对业务的影响并保持数据库高效运行。
411 4
|
3月前
|
前端开发 数据挖掘 关系型数据库
基于Python的哔哩哔哩数据分析系统设计实现过程,技术使用flask、MySQL、echarts,前端使用Layui
本文介绍了一个基于Python的哔哩哔哩数据分析系统,该系统使用Flask框架、MySQL数据库、echarts数据可视化技术和Layui前端框架,旨在提取和分析哔哩哔哩用户行为数据,为平台运营和内容生产提供科学依据。
229 9