我目前正试图修改一个与postgres数据库交互的现有API.长话短说,它本质上是存储描述符/元数据,以确定实际"assets资源 "(通常是某种文件)存储在服务器硬盘上的位置.

目前,可以使用any number of undefined个键值对(即uploadedBy、addedOn、assetType等)对这些"assets资源 "进行"标记".这些标记存储在一个单独的表中,其 struct 类似于以下内容:

+---------------+----------------+-------------+
|assetid (text) | tagid(integer) | value(text) |
|---------------+----------------+-------------|
|someStringValue| 1234           | someValue   |
|---------------+----------------+-------------|
|aDiffStringKey | 1235           | a username  |
|---------------+----------------+-------------|
|aDiffStrKey    | 1236           | Nov 5, 1605 |
+---------------+----------------+-------------+

assetid和tagid是来自其他表的外键.假设assetid代表一个文件,tagid/值对是描述符的映射.

现在,API(Java)将所有这些键值对创建为映射对象.这包括时间戳/日期之类的内容.我们想要做的是能够以某种方式为键值对中的值存储不同类型的数据.或者至少,在数据库中以不同的方式存储它,这样,如果需要,我们可以在这些标记上运行查询,判断日期范围等.然而,如果它们作为文本项存储在数据库中,那么我们必须a.)知道这实际上是一个日期/时间/时间戳项,b.)转换成我们可以实际运行此类查询的内容.

到目前为止,我只想到一个 idea ,不需要对db的布局做太多的改变.

这是为了扩展assettag表(如上所示),为各种类型(数字、文本、时间戳)提供额外的列,允许它们为空,然后在插入时判断相应的"键",以确定它实际上是什么类型的数据.然而,我可以看到这种实现存在很多问题.

有没有PostgreSQL忍者能就如何解决这个问题提供建议?我最近才回到数据库交互的最深处,所以我承认我有点生疏了.

推荐答案

你基本上有两个 Select :

选项1:稀疏表

每个数据类型有一列,但只使用与要存储的数据类型匹配的列.当然,这会导致大多数列为null——这是一种浪费空间的行为,但纯粹主义者喜欢它,因为它的类型很强.必须判断每一列是否为null,以确定应用哪种数据类型,这有点笨拙.另外,如果你真的想存储一个空值,那就太糟糕了——你必须 Select 一个"意味着空值"的特定值——更笨重.

选项2:两列——一列内容,一列类型

所有内容都可以表示为文本,因此有一个文本列作为值,另一个列(int或text)作为类型,这样应用程序代码就可以在正确的类型对象中恢复正确的值.好的方面是,您没有太多的空值,但重要的是,您可以轻松地将类型扩展到SQL数据类型之外的应用程序类,方法是将它们的值存储为json,将它们的类型存储为类名.

在我的职业生涯中,我曾多次使用选项2,它总是非常成功.

Postgresql相关问答推荐

在Go中,如何在没有数据库包的情况下运行PostgreSQL查询?

处理Ruust-DIESEL中的Jsonb PostgreSQL列

在 Windows 上使用 rsync 进行 Postgresql 副本升级

正在加载 pgAdmin 4 v7.4...同时打开 pgAdmin

如何在 sequelize 使用 db postgres 中通过外键更新记录和更新包含许多记录关系

推送到 Heroku 时出现带有 Postgres 的 Rails 迁移错误

Flask-SQLAlchemy db.session.query(Model) 与 Model.query

org.postgresql.util.PSQLException:错误:relation "app_user" does not exist

MAC OS X 上的 Postgres 权限被拒绝

查询仅属于特定部门的用户

错误:must be owner of language plpgsql

如何在数据库表中查找重复条目?

在 PostgreSQL 中的表上禁用 DELETE?

在 PostgreSQL 中跳过每 n 个结果行

错误:prepared statement "S_1" already exists

Postgres 中有多少表分区太多了?

升级到 Yosemite 10.10 后无法连接到 postgresql 数据库

如何更改 PostgreSQL 中的 REFERENCES?

PostgreSQL - 如何在不同时区呈现日期?

如何为 adminpack 解决 PostgreSQL pgAdmin 错误Server instrumentation not installed?