【问题标题】:How to store array or multiple values in one column如何在一列中存储数组或多个值
【发布时间】:2011-09-15 16:29:37
【问题描述】:

运行 Postgres 7.4(是的,我们正在升级中)

我需要将 1 到 100 个选定项目存储到数据库的一个字段中。 98% 的情况下只会输入 1 项,而 2% 的情况下(如果那样的话)会输入多项。

这些项目只不过是一个文本描述,(截至目前)不超过 30 个字符长。它们是用户选择的静态值。

想知道用于存储所需数据的最佳列数据类型。我在想 BLOB 但不知道这是否有点矫枉过正。也许是 JSON?

我也确实想到了 ENUM,但由于我们正在运行 Postgres 7.4,所以到目前为止我还不能真正做到这一点

我还希望能够轻松识别输入的项目,因此没有映射或引用表。

【问题讨论】:

  • 您的最后一个要求是不应该存在的。如果您直接在数据库中查找数据并为了“我可以更轻松地阅读它”而违反规范化规则,那么您就错了。

标签: sql arrays postgresql types


【解决方案1】:

您在这里有几个问题,所以我将分别解决:

我需要在数据库的一个字段中存储多个选定的项目

我的一般规则是:不要。这是除了需要第二个表(或第三个)外键的东西。当然,现在看起来似乎更容易了,但是如果用例出现在您需要实际单独查询这些项目的地方怎么办?这也意味着您有更多的延迟实例化选项,并且您可以在多种框架/语言之间获得更一致的体验。此外,您不太可能遇到连接超时问题(30,000 个字符很多)。

您提到您正在考虑使用 ENUM。这些值是固定的吗?你提前认识他们吗?如果是这样,这将是我的结构:

基表(你现在拥有的):

| id primary_key sequence
| -- other columns here.

物品表:

| id primary_key sequence
| descript VARCHAR(30) UNIQUE

地图表:

| base_id  bigint
| items_id bigint

映射表会有外键,因此 base_id 映射到基表,而 items_id 将映射到 items 表。

如果您想要一种从数据库中检索此信息的简单方法,请创建一个执行连接的视图。您甚至可以创建插入和更新规则,以便您实际上只处理一张表。

我应该使用什么格式存储数据?

如果你必须做这样的事情,为什么不只使用一个字符描述的字符串呢?与 CSV、XML 或 JSON 相比,它需要更少的处理能力,而且会更短。

我应该使用什么列类型来存储数据?

就个人而言,我会使用TEXT。根据我的经验,将其设为BLOBTEXT 听起来您不会获得太多收益,如果您使用某种形式的 IDE,则更容易阅读。

【讨论】:

  • OP 可能会发现 array_agg 在查看每个基本行一行和多个 description_fields 的视图中很有用
  • 如果可以的话,与将Base table 的主键作为列直接保存在Items table 中的行上相比,使用Map table 有什么好处?
【解决方案2】:

嗯,在最近的 Postgres 版本中有一个array type(不是 100% 关于 PG 7.4)。您甚至可以使用 GIN 或 GIST 索引对它们进行索引。语法是:

create table foo (
  bar  int[] default '{}'
);

select * from foo where bar && array[1] -- equivalent to bar && '{1}'::int[]

create index on foo using gin (bar); -- allows to use an index in the above query

但正如先前的答案所暗示的,正确标准化会更好。

【讨论】:

    猜你喜欢
    • 2013-11-08
    • 2020-01-22
    • 2011-08-12
    • 2019-05-01
    • 1970-01-01
    • 2013-12-12
    • 2013-12-22
    • 1970-01-01
    • 2021-01-29
    相关资源
    最近更新 更多