
# TOAST表
#### 简介
TOAST（The Oversized-Attribute Storage Technique）是一种特殊的存储机制。只有一些具有变长表现形式的数据才会支持TOAST，比如text类型。TOAST机制的主要目的是为了解决数据库中单个字段过大，无法直接存储在标准数据页中的问题。由于在GaussDB存储方式中，一条数据所有的字段组合在一起称为tuple，多个tuple组成一个page。page是数据在文件存储中的基本单位。GaussDB中的page默认大小为8KB，当某行数据大小超过page的大小时，数据库会启动TOAST，确保这些大字段能够被有效存储并管理。
行外存储是TOAST技术的一部分，该技术将大的字段压缩或切片成多个物理行存到另一张表（TOAST表），而主表只保留对这些大字段值的引用（通常是一个指针）。这样做的好处是，可以避免单行数据过大导致性能问题，同时仍然保持对大字段数据的有效访问。
如果某张表有一张关联的TOAST表，在PG_CLASS表里的reltoastrelid字段记录该TOAST表的OID，如果没有关联的TOAST表，reltoastrelid的值为0。
GaussDB中表的字段支持多种存储策略。有以下四种不同的存储策略：
1. PLAIN：
   - 不允许压缩和行外存储。这种策略通常用于不能使用TOAST机制的数据类型。
   
   - 适用于不需要TOAST就能存放的数据类型，如整数类型、字符类型等。
   
   - 对于存储长度超过page大小的类型（如text），不允许采用此策略。
    
2. EXTENDED：
   - 允许压缩和行外存储。这是大多数可以使用TOAST机制的数据类型的默认存储策略。
   
   - 数据库会首先尝试对数据进行压缩，如果压缩后的数据仍然太大，则进行行外存储。
   
   - EXTENDED是大多数可TOAST的数据类型默认策略，如text、bytea等。
    
3. EXTERNAL：
   - 允许行外存储，但不允许压缩。
   
   - 这种策略可以使text、bytea数据类型的字符串操作更快，因为不需要读取和解压整行数据。
    
4. MAIN：
   - 允许压缩。
   
   - 主要适用于numeric类型的数据。
   
   - 数据库会首先尝试对数据进行压缩，如果压缩后的数据仍然太大，则进行行外存储。
    
 
#### 示例
```
--建表。
gaussdb=# CREATE TABLE tb_t1(id int, info text);
NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'id' as the distribution column by default.
HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
gaussdb=# CREATE TABLE tb_t2(id int, age int);
NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'id' as the distribution column by default.
HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
--查看表tb_t1信息，info字段为text类型，且Storage为extended。
--部分回显内容如下：
gaussdb=# \d+ tb_t1
                         Table "public.tb_t1"
 Column |  Type   | Modifiers | Storage  | Stats target | Description 
--------+---------+-----------+----------+--------------+-------------
 id     | integer |           | plain    |              | 
 info   | text    |           | extended |              | 
--查看表tb_t2信息，所有字段为int类型。
--部分回显内容如下：
gaussdb=# \d+ tb_t2
                                Table "public.tb_t2"
 Column |         Type          | Modifiers | Storage  | Stats target | Description 
--------+-----------------------+-----------+----------+--------------+-------------
 id     | integer               |           | plain    |              | 
 age    | integer               |           | plain    |              | 
--如下查询表示tb_t1有关联的TOAST表，tb_t2表没有关联的TOAST表。
gaussdb=# SELECT oid,relname,reltoastrelid FROM pg_class WHERE relname in ('tb_t1','tb_t2');
  oid  | relname | reltoastrelid 
-------+---------+---------------
 34519 | tb_t1   |         34522
 34524 | tb_t2   |             0
(2 rows)
--查询tb_t1关联的TOAST表信息。
gaussdb=# SELECT relname,oid FROM pg_class WHERE oid = '34522';
    relname     |  oid  
----------------+-------
 pg_toast_34519 | 34522
(1 row)
--删除。
gaussdb=# DROP TABLE tb_t1,tb_t2;
DROP TABLE
```
