替换 EAV 时 JSON(B) 中的数据完整性

Posted

技术标签:

【中文标题】替换 EAV 时 JSON(B) 中的数据完整性【英文标题】:Data integrity in JSON(B) when replacing EAV 【发布时间】:2020-02-03 05:34:44 【问题描述】:

我正在为一个新应用程序实现一个数据库,我正在考虑使用JSON 字段而不是传统的EAV 方法。一切似乎都还好,但有一个大问题我不知道如何解决。

例如;在传统的EAV 模型中,我们将有三个表格;

保存属性的第一个表 保存值的第二个表 将这两者联系在一起的第三张桌子。

第三张表中的标识符始终是其他两个表之一的主键,而不是值本身。如果我更改属性的名称,它的主键保持不变,因此不会影响 第三张表中的数据完整性。

现在输入JSON。据我了解,用JSON 替换EAV 的全部意义在于将所有值存储在字段本身中。所以我们的记录可能是这样的。


   "color": "Blue",
   "size": "Large"

而不是通过主键存储值。

所以我的问题是,如果我在路上,将颜色的标题从Blue 更改为Purple,我该如何处理数据完整性?因为在经典的EAV 模型中主键不会改变。

我正在使用Postgresql 数据库和Django

【问题讨论】:

【参考方案1】:

使用 Django ORM,操作 JSON 字段值的唯一方法是 迭代模型。但您可以查询/过滤个别字段:

假设你有这个模型:

from django.contrib.postgres.fields import JSONField
from django.db import models

class Thing(models.Model):
    attributes = JSONField()

你应该可以查询蓝色的东西(见Querying JSONField):

blue_things = Thing.objects.filter(attributes__color='Blue')

现在您可以遍历这些模型实例并更新值:

for thing in blue_things:
    thing.attributes['color'] = 'Purple'
    thing.save()

您可能希望在事务中执行此操作。

PostgreSQL 允许您直接操作 JSONB 字段:

UPDATE appname_thing SET attributes = attributes || '"color": "Purple"' WHERE attributes->>'color' = 'Blue';

据我所知,Django 目前不支持此功能,因此您必须perform a raw query。

【讨论】:

【参考方案2】:

我个人不熟悉 Django,但如果您想利用 PostgreSQL 的 JSON 功能,我可能会依赖与您更随意的 JSON 分开的主键列。比如:

CREATE TABLE stuff (
    id SERIAL NOT NULL PRIMARY KEY,
    data JSON NOT NULL
);

这样您就可以将您的id 列作为可靠的参考,并且可以对 JSON 进行任何您喜欢的操作。如果您对 JSON 有一个已知/可预测的结构,您可以create indices 在查询 JSON 数据时帮助提高性能。

原答案:

我不清楚您将使用哪种数据库产品,但熟悉 MongoDB,一个面向 JSON 文档的数据库,我可以告诉您它是如何工作的。当您插入一个文档时,如果您不提供它,则会添加一个 _id 字段,MongoDB 称之为 ObjectId。所以,如果你插入你的示例 JSON,你会得到类似的东西:


   "_id": ObjectId("5d97d46a54198e0797d86457"),
   "color": "Blue",
   "size": "Large"

如果您只想更新该文档,可以在“where 子句”中使用 _id,例如:

db.collection.updateOne(
   _id: ObjectId("5d97d46a54198e0797d86457")
, 
    $set: 
        color: "Red",
        size: "Medium"
    
);

同样,不知道您使用的是什么数据库,这可能是离谱的。如果你在 PostgreSQL 之类的东西中处理 JSONB,那么你通常会包含一个 serial 或类似的列来维护一个固定的主保留,就像你提到的那样。

【讨论】:

我已经编辑了原始问题,感谢您的回答。

以上是关于替换 EAV 时 JSON(B) 中的数据完整性的主要内容,如果未能解决你的问题,请参考以下文章

在保持 JSON 文件完整的同时替换 Javascript 中的字符串

EAV 是“坏的”,但类表继承的可维护性如何?

用 JSON 字符串中的 hex 替换所有 r、g、b 值 [重复]

在javascript中遍历嵌套的json文件时替换值

如何解析html中的json数据和输出?

java中的lis数组转为json数据