【问题标题】:How do I map tables with n columns to a database?如何将具有 n 列的表映射到数据库?
【发布时间】:2019-07-24 05:36:42
【问题描述】:

我们目前正在使用 PostgreSQL,现在必须在数据库中保存一些表。表一旦创建就永远不会更新,但可能会被过滤。

表格本质上是动态的,因为可能有 n 列,

所以一张桌子应该是:

|------|--------|--------|
| NAME | DATA 1 | DATA 2 |
|------|--------|--------|

另一个表是:

|------|--------|--------|--------|--------|--------|
| NAME | DATA 1 | DATA 2 | DATA 3 | DATA 4 | DATA 5 |
|------|--------|--------|--------|--------|--------|

数据未规范化,因为在处理 n 行时会很痛苦,因为所有行都是一次读取的。

这些是我想出的解决方案,

  1. 将表保存为 JSON 类型或 HStore 对中的 JSON。
  2. 将表格另存为文本字段中的 CSV 数据

存储上述数据的替代方法是什么? NoSQL 数据库可以处理这些数据吗?

【问题讨论】:

  • 当您说可以过滤表时,您的意思是您针对多个表或其中一个表运行查询?你有什么性能要求?顺序扫描可以吗?我们所说的表格/表格中的列数/表格中的行数是多少,数千/百万?
  • 查询将在每个表上完成,而不是针对多个表。列数可以是n,其中n < 12 最多,行数可能是数千,不超过十万。
  • 您对无模式表功能有疑问吗?我的意思是你想在同一个表中存储具有不同列数的行还是每个表都应该有静态列数?

标签: postgresql database-design cassandra nosql data-modeling


【解决方案1】:

动态列意味着 schema less 是我们应该寻找的选项。首选 MongoDB。我们存储为 JSON 吗?如果是这样,Mongo 将帮助处理数据/提取/报告将使生活更轻松。

如果您不熟悉 NOSQL 。 MSSQL 2016 及更高版本的列中 JSON 存储支持为 varchar(MAX)。 SQL Server 提供了处理 JSON 数据的功能。即使默认情况下它是基于文本的索引 nvarchar 。 SQL 支持基于计算列的索引,这将有助于处理 JSON 中的元素外观。允许使用任意数量的非聚集索引计算列,这将简化索引以处理 JSON 数据。 SQL 2019 对 JSON 有更多支持

【讨论】:

  • Postgres 对 JSON 的支持比 SQL Server 更好。 Postgres 获得了原生 json 类型,而 SQL Server 将其作为 VARCHAR,因此索引很糟糕。我的想法是任何其他可以满足要求的 nosql sb。感谢您的意见。
  • SQL Server - 计算列索引将有助于删除文本索引。如果您不使用 MongoDB,Couchbase 是另一个 NOSQL 选项。
  • 表创建后如何查询?为什么不在需要时发出 DDL 来创建它们?
  • @Deena "Postgres 获得了原生 json 类型,而 SQL Server 将其作为 VARCHAR,因此索引很烂" 有什么具体的例子吗?将 JSON 存储为 VARCHAR 并没有错。公平地说Oracle uses similar approach.
  • @LukaszSzozda 如果没有索引,SQL Server 每次查询数据时都必须执行全表扫描,这就是 JSON 中 varchar 类型的糟糕之处。
【解决方案2】:

根据您的描述,这听起来像是 jsonb 的工作。假设name 在某个表中是唯一的,我可以这样想象:

create table test (
  tableId integer,
  name text,
  data jsonb,
  constraint pk primary key(tableId, name)
);
insert into test values (1, 'movie1', '{"rating": 10, "name": "test"}');
insert into test values (1, 'movie2', '{"rating": 9, "name": "test2"}');
insert into test values (2, 'book1', '{"rank": 100, "name": "test", "price": 10}');
insert into test values (2, 'book2', '{"rank": 10, "name": "test", "price": 12}');

基本上这个想法是使用tableId来识别每个子表并将子表的行存储在这个db表中。

这开启了一些可能性:

  • 创建一个单独的表来存储有关每个子表的元数据。例如,可以将子表的架构存储在这里以进行应用层验证。
  • 大/热子表的部分索引:create index test_1_movie_name on test ((data->>'name')) where tableid = 1

【讨论】:

    【解决方案3】:

    我在您的问题中没有看到任何内容可以阻止您使用具有相应数量数据列的普通表。这是目前为止最有效的存储形式。最小的存储空间,最快的查询。

    “一旦创建就不会更新,但可能会被过滤”的表几乎不是“动态的”。除非你隐瞒重要的细节。

    除非有超过 100 列。见:

    (但你后来评论最多12条,完全没问题。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-25
      • 2019-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多