【发布时间】: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