Postgres JSONB 的一个很好的用例?

gre*_*fox 4 nosql postgresql database-design eav postgresql-9.4

我希望创建一个资产管理系统来跟踪资产(笔记本电脑/台式机、显示器、键盘、鼠标、包、软件键等),基本上是可以分配给员工的任何东西。我的问题是,每种类型都需要跟踪不同的属性。我们会跟踪计算机的一组不同的属性/属性,而不是监视器。我读过 EAV 模式(或大多数人所说的反模式),似乎瘟疫应该避免这种情况。创建包含所有列的单个表似乎很荒谬,并且为出现的每个新类型创建一个新表似乎不是最佳选择。我最近在 Postgres 9.4 中读到了 JSONB。存储可由应用程序处理的 JSON 对象似乎是一个不错的妥协。

这是 JSONB 的好用例吗?或者EAV有意义吗?或者制作一张巨大的桌子,或者为每种类型创建一张桌子?

Cra*_*ger 5

这确实是存储类对象或键/值数据的合理情况,并且jsonb在 PostgreSQL 的字段中将其表示为 JSON是一种合理的方法。

一般来说,当您开始查看应用程序动态添加列的 EAV 或宽表等替代方案时,是时候考虑hstorexmljsonb等了。jsonb基本上是新的hstore,具有更标准的数据表示方式和嵌套功能,因此在大多数情况下更可取。

用于不同类型事物的静态表,以及用于更一般事物类别的父表,如果被跟踪的事物 (a) 相当静态且不是用户定义的,并且 (b) 数量不多,则仍然有意义。这听起来不像这里的情况。

我仍然建议将属性保留为常规列,其中:

  • 它们构成参照关系的一部分(is-a、has-a、contains、is-contained-by、owns、is-owned-by等);
  • 它们是UNIQUE约束有意义的自然键;
  • 它们在大多数查询中被过滤或以其他方式查询

可以在查询 json 字段的表达式上定义唯一约束 - 或者更确切地说,唯一索引。将它们分开通常会更干净。类似地,表达式索引可以帮助处理您希望保留 json 对象一部分的经常查询的字段。这确实是最重要的第一点,因为 RI 约束不能引用 json 对象键的值。