sql - 具有变体数据类型的 SQL 数据库设计
问题描述
我正在开始一个新项目,但在为数据库找到正确的设计时遇到了一些麻烦。
数据库域有许多彼此相似但有几个不同字段的实体。这个字段可以随着时间的推移而改变,其中许多是枚举。目标是设计数据库,使其可以通过管理仪表板控制字段及其可能的值。
我的想法是有一个实体Super entity
,它存储所有实体之间的所有公共字段,有一个EntityCharacteristics
将带有外键的实体特征存储到一个Characteristic
表中,该表将存储有关特征的信息,这将使创建一个带有此信息的表单字段成为可能,想象一下
CharacteristicName: Age
Placeholder: Enter your age...
InputType: text
CharacteristicType: Integer
需要可以为选择框的 InputType 存储可能的值,例如,这将是一个类似枚举的类型。还有SuperEntity
一个 entity_type 字段,该字段将连接到一个EntityType
表,并且该表将连接到一个PossibleEntityCharacteristics
将可能的特征存储到某个实体类型的表。
我的问题是我应该如何存储这些值,EntityCharacteristics
因为它们可以是不同的类型、布尔值、文本、整数、枚举等。以及如何使用 Json 将可能的值存储在枚举类型中?或者与某个特征的另一个可能值表一起使用?我如何确定插入的值EntityCharacteristics
是正确的类型并包含枚举的可能值?
也许这是一个糟糕的设计,我不应该这样想,而只是将数据存储在具有许多字段的普通表中。但是我想提供一个解决方案,可以随时轻松更改不同相似实体的现有字段和字段值,并且不得不更改表模式似乎不是一个好主意。我计划用支持 Json 的 PostgreSQL 来实现这个,它可能适合这里的某个地方,但是由于我从未在 Sql 中使用过这种数据类型,我不知道这是否是个好主意。
我想知道您对此的看法,在此先感谢您。
注意:我正在考虑的数据库模型类似于https://stackoverflow.com/a/7423459但有点复杂并且没有嵌套。
解决方案
这有点基于意见,但无论如何:
我会选择一个表,其中包含所有类型的对象共有的所有属性的列。然后有一个额外的JSONB
列来存储可能在不同类型之间变化的各个属性。
您可以更进一步,并在第二个表中创建一个“类型描述”,该表定义了一个类型的允许属性。然后可以通过管理 UI,您还可以使用它来验证放入基表的“动态”属性中的数据。
像这样的东西:
create table object_type
(
id integer primary key,
name text not null,
allowed_attributes jsonb not null
);
create table objects
(
id integer primary key,
name text not null,
object_type_id integer not null references object_type,
attributes jsonb
);
insert into object_type (id, name, allowed_attributes)
values
(1, 'spaceship', '{"seats": "integer", "color": "text"}'::jsonb),
(2, 'book', '{"number_of_pages": "integer", "color": "text"}'::jsonb);
insert into objects (id, name, object_type_id, attributes)
values
(1, 'Heart Of Gold', 1, '{"seats": 4, "color": "white"}'),
(2, 'H2G2', 2, '{"number_of_pages": 42, "color": "black", "published_in": 1979}');
现在在上面的示例中,published_in
是一个基于object_type
. 这些行可以用例如以下查询来识别:
select *
from (
select *,
attributes - (select array_agg(t.k)
from object_type ot, jsonb_object_keys(ot.allowed_attributes) as t(k)
where ot.id = o.object_type_id) as invalid_attributes
from objects o
) t
where invalid_attributes <> '{}';
您甚至可以构建一个触发器,在插入或更新对象时进行这种检查。
使用该json_typeof()
函数,您还可以验证提供的键值是否与定义的数据类型匹配object_type
推荐阅读
- java - 是否可以从父类型调用子静态方法?
- scala - org.apache.spark.SparkException:任务不可序列化原因:java.io.NotSerializableException
- flutter - 小部件停用后如何在 ChangeNotifier 中捕获错误?
- javascript - 在 JavaScript (Node.js) 中启动/停止后台工作者
- python - 将字典传递给 python 程序
- sparql - 通过连接两个资源来查询数据
- python - 如何在Python中删除从字符串到特定字符的所有内容
- python - 导入包时找不到模块。它肯定安装在计算机上。我已经尝试了很多东西,但没有一个奏效
- ios - React 本机曲目播放器无法将歌曲添加到播放列表
- python - 运行 Cython 安装会生成不需要的文件