Sql 将数组存储为字段值,或将数组值存储为记录,这是一个好主意吗?

Sql 将数组存储为字段值,或将数组值存储为记录,这是一个好主意吗?,sql,database,postgresql,database-design,Sql,Database,Postgresql,Database Design,在我的应用程序中,我有一些“文章”(类似于帖子/推特/文章),它们用描述性的预定义标签进行标记:即“难”、“易”、“红”、“蓝”、“业务”等 这些可用标记存储在一个表中,称之为包含所有可用标记的“标记” 每篇文章都可以使用多个标签进行标记,可通过自定义管理界面进行编辑 简单地将每个实体的标记捆绑到每个标记的ID的字符串化数组中,并将其与我的“articles”表中的文章记录一起存储,这是很有诱惑力的: 尽管出于许多原因,我确信这是一个坏主意,但有没有合理的理由这样做?在我看来,您希望有一个单独的

在我的应用程序中,我有一些“文章”(类似于帖子/推特/文章),它们用描述性的预定义标签进行标记:即“难”、“易”、“红”、“蓝”、“业务”等

这些可用标记存储在一个表中,称之为包含所有可用标记的“标记”

每篇文章都可以使用多个标签进行标记,可通过自定义管理界面进行编辑

简单地将每个实体的标记捆绑到每个标记的ID的字符串化数组中,并将其与我的“articles”表中的文章记录一起存储,这是很有诱惑力的:


尽管出于许多原因,我确信这是一个坏主意,但有没有合理的理由这样做?

在我看来,您希望有一个单独的表来存储标记并保存一个外键,该外键将标记记录与articles表中的父记录联系起来(这称为“规范化”)数据库结构)

现在,按照您的建议将标记塞进一个字段似乎是有意义的,但随着应用程序的大小或数据量的增加,很难维护这些值,并且很难/很耗时地有效地提取这些值


我想说的是,考虑到创建另一个表并设置链接键的关系以保持引用完整性是多么简单,没有什么理由按照您的建议去做。

我认为您应该自己阅读并决定。简言之,虽然你的提案有很多问题,但你可能决定接受它们

最明显的是:

  • 如果在第(1)行中添加了一个附加标记,该怎么办?是否必须首先解析,检查它是否已经存在,然后将行更新为
    tags.append(newTag)
  • 更糟糕的是删除标签?搜索标记,如果存在,请重新创建标记
  • 如果一个标签要更改名称——也许是某种调节过程,该怎么办
  • 更糟糕的是,不同的人用不同的方式指定标签名,这很难合理化
  • 如果要基于标记查询数据,该怎么办?您的查询变得比需要的复杂得多
  • 演示:客户端必须解析标记才能使用它。分隔符字段呢?改变这一点,所有客户都必须改变
  • 简言之,所有这些行动都变得更加困难和繁琐。正常化旨在克服这些问题。依我看,这样做的唯一原因可能是您将数据捕获为一次性数据,并且它只是信息性的——也就是说,对用户来说是有意义的,但对系统本身来说是没有意义的。这有点像是说最好避免这样做(同样,国际海事组织)。

    我完全同意这是个好主意。我强烈主张将标记存储在数据库中,作为单个分隔字符串列表

    但是:我同意的原因是我喜欢使用Azure Search API对这些类型的数据进行索引,因此基于标记进行查找的查询不是通过SQL完成的。(没有必要使用Azure search API服务,但根据我的经验,通过使用数据库之外的搜索索引,您将获得更好的性能和可伸缩性。)

    如果您使用的是SQL(基于关系的查询),则主要查询语言为 然后最好创建一个子表,每个子表都有一行 标记,否则在必须执行查询时,您将获得性能提升 对每个值执行逻辑以将其拆分以进行分析

    标记是我们用来绕过关系数据或层次映射的一个概念,因此为了获得最佳性能,不要尝试使用这些关系概念来查询标记。它通常最好在NoSQL数据存储中实现,因为它们不尝试使用数据库来处理搜索查询

    我鼓励您将数据存储为分隔字符串,并使用外部索引服务提供对数据的搜索和深入了解。这是CRUD数据访问性能尝试管理数据和索引以优化搜索之间的良好折衷。当然,您可以优化数据库和搜索查询,以使其在SQL中工作,但这需要付出努力才能使其正确


    一旦您的用户群访问了大量数据,并且您需要在不影响更新性能的情况下支持多个并发搜索,您就会发现外部索引是一项了不起的投资,可以节省您以后的时间和资源。

    我不知道PostgreSQL,但由于它似乎支持XML,将标记列表存储为XML字符串可能会比简单的分隔列表带来巨大的好处。PostgreSQL中有一系列基于GisT/GIN的索引,可以很好地搜索整型数组或文本标记。整型数组或文本标记。。。哪一个是正确的?我的观点是,无论您选择使用何种格式,如果您的查询语言支持优化的数据访问方式,那么将数据存储在数据库中的单个字段中是完全有效的。因此,在我看来,你似乎真的同意:)我对逗号很满意,因为我选择的索引方法可以比这种单字段格式的其他结构更快地处理逗号分隔的字符串。这不是真正的讨论论坛,但没有未分隔的-存储为适当的结构化类型。将所有内容混合成文本是最后的手段。要点:)在我的无知中,我没有意识到这个问题是专门为PostgreSQL标记的
    id | title | author | tags
    ---+-------+--------+-------------
    1  | title | TG     | "[1,4,7,12]"