json - 替换 EAV 时 JSON(B) 中的数据完整性
问题描述
我正在为一个新应用程序实现一个数据库,我正在考虑使用JSON
字段而不是传统EAV
方法。一切似乎都很好,但是有一个我不知道如何解决的大问题。
例如; 在传统EAV
模型中,我们将有三个表;
- 第一个保存属性的表
- 保存值的第二个表
- 第三张桌子将这两者联系在一起。
第三个表中的标识符始终是其他两个表之一的主键,而不是值本身。如果我更改属性的名称,它的主键保持不变,因此不会影响第三个表中的数据完整性。
现在输入JSON
。据我了解,替换为的全部意义EAV
是JSON
将所有值存储在字段本身中。所以我们的记录可能是这样的。
{
"color": "Blue",
"size": "Large"
}
而不是通过主键存储值。
所以我的问题是,如果我在路上,将颜色的标题从 let's say 更改Blue
为Purple
,我该如何处理数据完整性?由于在经典EAV
模型中主键不会改变。
我正在使用Postgresql
带有Django
.
解决方案
使用 Django ORM,操作 JSON 字段值的唯一方法是迭代模型。但是您可以查询/过滤各个字段:
假设你有这个模型:
from django.contrib.postgres.fields import JSONField
from django.db import models
class Thing(models.Model):
attributes = JSONField()
您应该能够查询蓝色的东西(请参阅查询 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 目前不支持此功能,因此您必须执行原始查询。
推荐阅读
- javascript - display = "show" 是一回事吗?
- c++ - 为 openGL windows 8 Microsoft Visual Studio 2019 64 位安装 GLUT
- spring-el - 我可以遍历 Spinnaker 表达式中的列表吗?
- jquery - 使用 Ajax 过滤器购物并加载更多功能 Laravel
- node.js - 类型文件打字稿错误上不存在属性名称
- visual-studio-code - 如何在 VS-Code 中通过空格水平移动光标?
- powershell - 从Powershell中的下划线和空格划定的文件名中提取单词
- telerik - 使用授权令牌通过 Telerik Fiddler Classic 编写 HTTP(S) 请求
- spring - Payara 5启动时出现Spring MVC Jackson异常
- java - 我需要在 MacOS 上设置 JAVA_HOME 吗?