在 Kubernetes 上针对小数据量数据库的 PostgreSQL 与 TimescaleDB 存储比较

发布: (2026年3月2日 GMT+8 18:09)
4 分钟阅读
原文: Dev.to

Source: Dev.to

目的

在 Kubernetes 上进行 两个独立的部署(vanilla PostgreSQL + TimescaleDB),使用小数据集比较存储使用情况。

注意: TimescaleDB 本身运行在 PostgreSQL 上。这里所说的 “TimescaleDB 部署” 指的是包含 PostgreSQL + Timescale 扩展的独立部署。我们也会部署 “vanilla PostgreSQL”,以便结果更清晰。

前置条件

  • 正在运行的 Kubernetes 集群以及 kubectl 访问权限
  • Helm
  • 安装在单节点集群上,且 StorageClasslocal‑path

1. 阶段 – 安装

1.1 Namespace

kubectl create namespace database

1.2 Helm 仓库

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add timescaledb https://charts.timescale.com
helm repo update

第2阶段 – Vanilla PostgreSQL(Bitnami)安装

创建 postgres-values.yaml

# postgres-values.yaml içeriği burada tanımlanacak

注意: 我们连接到两个独立的 pod。我们将在两个不同的数据库安装中执行相同的操作。

第5阶段 – 使用小数据集进行测试

我们将在两个环境中执行以下SQL:

  • 在 PostgreSQL 中,sensor_pg 将是普通表。
  • 在 TimescaleDB 中,sensor_ts 将是 hypertable。

为了让数据量少,生成 1 天 的数据。

5.1 PostgreSQL

psql 中:

CREATE TABLE sensor_pg (
  time        TIMESTAMPTZ NOT NULL,
  device_id  INT,
  temperature FLOAT
);

CREATE INDEX sensor_pg_time_idx ON sensor_pg(time);

INSERT INTO sensor_pg
SELECT
  generate_series(NOW() - INTERVAL '1 day', NOW(), INTERVAL '1 minute'),
  (random() * 10)::int,
  random() * 100;

SELECT count(*) FROM sensor_pg;

5.2 TimescaleDB

psql 中:

CREATE EXTENSION IF NOT EXISTS timescaledb;

CREATE TABLE sensor_ts (
  time        TIMESTAMPTZ NOT NULL,
  device_id  INT,
  temperature FLOAT
);

SELECT create_hypertable('sensor_ts', 'time');

CREATE INDEX sensor_ts_time_idx ON sensor_ts(time);

INSERT INTO sensor_ts
SELECT
  generate_series(NOW() - INTERVAL '1 day', NOW(), INTERVAL '1 minute'),
  (random() * 10)::int,
  random() * 100;

SELECT count(*) FROM sensor_ts;

Not: 在 TimescaleDB 中,hypertable 看起来像普通表,但在后台会被划分为 chunk。即使是少量数据的测试,也会至少生成一个 chunk。

第6阶段 – 存储测量

通过在两个层面进行测量,我们可以获得更具体的结果:

  1. Relation size(使用SQL) – 表 + 索引 大小
  2. Data directory(使用文件系统) – 实际磁盘使用情况

6.1 PostgreSQL – 使用SQL获取表大小

SELECT
  pg_size_pretty(pg_table_size('sensor_pg'))        AS table_only,
  pg_size_pretty(pg_indexes_size('sensor_pg'))      AS indexes,
  pg_size_pretty(pg_total_relation_size('sensor_pg')) AS total;

6.2 TimescaleDB – 使用SQL获取 hypertable(按 chunk)大小

SELECT
  pg_size_pretty(SUM(pg_table_size(chunk.id::regclass)))   AS table_only,
  pg_size_pretty(SUM(pg_indexes_size(chunk.id::regclass))) AS indexes,
  pg_size_pretty(SUM(pg_total_relation_size(chunk.id::regclass))) AS total
FROM show_chunks('sensor_ts') AS chunk(id);

说明: Hypertable 实际上由 chunk 表组成;因此真实的数据 + 索引大小等于所有 chunk 的总和。

7. 我的环境输出

PostgreSQL

postgres=# SELECT count(*) FROM sensor_pg;
 count 
-------
 1441
(1 row)

TimescaleDB

postgres=# SELECT count(*) FROM sensor_ts;
 count 
-------
 1441
(1 row)

(持续的测量结果和比较可以在此添加。)

7.1 SQL(关系)大小

表和索引在 PostgreSQL 中占用的空间。

PostgreSQL (sensor_pg)

 table_only | indexes | total  
------------+---------+--------
 112 kB     | 48 kB   | 160 kB
(1 row)

TimescaleDB (sensor_ts)

 table_only | indexes | total  
------------+---------+--------
 112 kB     | 72 kB   | 184 kB
(1 row)

table_only 在两侧相同,而 indexes 部分在 Timescale 侧更多。

8. 为什么 Timescale 在小数据上可能显示更大?

  • 在 TimescaleDB 中,hypertable 实际上由 chunk 表 组成。每个 chunk 都拥有自己的表/索引结构。
  • 在小数据集下,这种结构的 “overhead” 更加明显。

结论: 在数据量不大的表场景中,由于 Timescale hypertable 的 chunk/索引开销,PostgreSQL 看起来会更小一些。

0 浏览
Back to Blog

相关文章

阅读更多 »

当工作成为心理健康风险时

markdown !Ravi Mishrahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fu...