【问题标题】:How to represent JSON data with a schema using PostgreSQL in a scalable way?如何以可扩展的方式使用 PostgreSQL 用模式表示 JSON 数据?
【发布时间】:2021-10-12 20:27:14
【问题描述】:

我有一个应用程序需要使用模式存储任意 JSON 数据。我有模式验证/序列化/等,但我对如何将它存储在 PostgreSQL 中有点困惑。我主要关心的是可扩展性:如果我的数据库增长(比如超过 100GB)会发生什么。我当前的架构如下所示:

CREATE TABLE "Schema" (
    "namespace" CHAR(50) NOT NULL,
    "name" CHAR(50) NOT NULL,
    "version" CHAR(50) NOT NULL,
    "schemaObject" JSONB NOT NULL,
    "createdAt" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "deletedAt" TIMESTAMP(6),

    CONSTRAINT "Schema_pkey" PRIMARY KEY ("namespace","name","version")
);

CREATE TABLE "Data" (
    "id" TEXT NOT NULL,
    "data" JSONB NOT NULL,
    "createdAt" TIMESTAMP(6) NOT NULL,
    "updatedAt" TIMESTAMP(6) NOT NULL,
    "deletedAt" TIMESTAMP(6),
    "schemaNamespace" CHAR(50) NOT NULL,
    "schemaName" CHAR(50) NOT NULL,
    "schemaVersion" CHAR(50) NOT NULL,

    CONSTRAINT "Data_pkey" PRIMARY KEY ("id")
);

ALTER TABLE "Data" ADD CONSTRAINT "Data_schemaNamespace_schemaName_schemaVersion_fkey" FOREIGN KEY ("schemaNamespace", "schemaName", "schemaVersion") REFERENCES "Schema"("namespace", "name", "version") ON DELETE RESTRICT ON UPDATE CASCADE;

所以每个 JSON Schema 都存储在 Schema 表中,并由 namespace+name+version 组合唯一标识。然后我有一个Data 表,我可以在其中存储个人记录。我怎样才能改进它以使其具有可扩展性?我对“将所有内容存储在一张表中”的想法感到担忧。是我做错了,还是这是正确的方法?

关于将使用它的应用程序的更多信息:它是一种数据聚合服务,将为外部客户端提供联合查询接口 (GraphQL)。每个Data 对象中都会有一个id,我将根据id 进行查询,但除此之外,我只会查询Schema 的数据列表。这也必须是一个通用的解决方案,我不期望特定的查询模式。我还将使用可能基于高度精细的 createdAt 字段的游标(我不希望写入更频繁地得到 6 的精度支持)。

【问题讨论】:

  • 对我来说似乎或多或少很好,除了两件事:(1)"deletedAt""updatedAt" 不为空是什么意思?如果模式或数据记录没有被删除或更新,它们的值应该是什么? (2) 从表"Data" 中删除"schemaNamespace""schemaName""schemaVersion" 并用schema_id 替换它们可能是个好主意(将添加到"Schema" 表中)。
  • 我修复了deletedAt!我使用了复合键,因为这是唯一代表 id 的东西。向Schema 添加 id 不会代表实际数据。
  • 好吧,也许我不清楚。我建议您将复合键保留在"Schema" 中以供识别,并且仍然添加唯一索引id 以供"Data".schema_key 引用。因此,"Data" 中的复合外键变得多余,并被单个纯整数替换。
  • 有道理,谢谢!

标签: json postgresql jsonschema


【解决方案1】:

您的问题非常广泛。这样的表可以扩展到数百 GB,但是您需要问自己要对该数据运行什么样的操作,以便能够弄清楚您还需要做什么(很可能是一些 JSON 字段等的索引)。

在基于 SQL 的 RDBMS 中使用 JSON 的真正威力在于有机会获得两全其美的机会。这意味着通常最好对数据的至少某些部分使用结构化数据、外键约束等,并将 JSON 类型仅用于需要更大灵活性的那些部分。

【讨论】:

  • 我添加了一些说明!
【解决方案2】:

您添加的信息太少,无法给出明确的答案。例如,这些 JSON 列中将存储什么?这些数据会有多大?这些数据将如何用于查询?

但我怀疑你的设计不好。例如,您说每个 JSON 对象都有一个您想要查询的名为 id 的属性。将该属性存储为常规表列会更好!

尝试提出一个完全避免使用 JSON 的数据模型。仅对无法以其他方式建模的数据方面使用 JSON。或许你可以从my article那里得到一些启发。

【讨论】:

  • 我将存储从具有自己的数据模型(这是一个聚合器服务)的各种系统发送的数据。它们的共同点是 JSON Schema,数据以 JSON 形式传输。如果我只存储 JSON(和模式)而不是为所有数据创建和维护表,这对我来说看起来更简单。我没有说要存储什么,因为我不知道。你可以使用这个服务来集成任何东西,所以我不知道人们会用它来做什么。它必须是通用的。
  • 我阅读了您的文章,除了将 id 存储在 Data 表中之外,这些都不适用于这里,这是个好主意。
  • 我明白了。正如我所说,这个问题非常模糊,不太可能得到令人满意的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多