Postgres jsonb 列或标准规范化表?

use*_*167 8 postgresql performance database-design

我正在实施一个带有支付系统的应用程序,我需要记录通过该应用程序进行的交易。此外,我需要使用有关交易的一些信息来呈现一些 KPI。我已经在 Postgres 中有一个实现,其中我的表有两列idtransaction(jsonb)。在我的交易列中,我有一个如下所示的对象:

2018: {
   November: {
      list_of_transactions: [],
      totalAmountEarned: 0,
      numberOfTransactions: 0,
      avarageSpending: 0,
      numberOfCoins: 0,
      numberOfUsers: 0
   }  
}
Run Code Online (Sandbox Code Playgroud)

现在,每当我做一个交易,我检查yearmonth自带的请求存在,否则将它们添加到该对象,并推动事务中list_of_transactions,并相应地更新所有的其他键。

我想知道这是否是解决问题的好方法,或者实际上是一种非常糟糕的方法。创建不同的表并以“SQL 方式”对它们进行规范化是更好的解决方案吗?你有什么建议吗?

其他注意事项

一个附带问题:既然会有很多很多交易,每年创建一个新表是个好主意吗?

涉及的所有数据的结构将完全相同,因此我应该创建多个数据库并进行连接。由于会有很多很多交易:每年创建一个新表是个好主意吗?

dez*_*zso 12

每个关系数据库中的经验法则都是规范化的(通常高达 3NF 甚至 4NF)。随着 JSON 进入关系世界,人们往往倾向于使用 JSON 解决所有问题,因为它可能意味着将应用程序中移动的一些数据导入数据库的一种非常简单的方法。然而,虽然它有自己的位置,但我经常看到的情况是,数据可能大部分或全部标准化。

基本上,只要您看到您的 JSON 共享相同的键(具有相同数据类型的值),您就应该将这些键提取到正确的列中。如果整个结构始终相同,则提取所有内容,根据需要创建表(例如,如果您在 JSON 中有数组,则它可能表明您需要该键的表),并且 - 基本上总是在关系中world - 在它们之间做连接。

除了规范化解决的所有问题外,这也有性能优势。首先,您不会在每笔交易中一次又一次地存储相同的密钥,这可能会节省大量存储空间。其次,在典型情况下,您可以在您的列(或它们的组)上拥有更有效的索引。第三,您可以使用主键和外键以及约束来强制执行数据完整性(嗯,这在规范化部分中有部分内容......)。最后,RDBMS 非常擅长连接表并提出有效的查询计划来检索您需要的数据。

至于为每年保留一个单独的表:这可以通过分区来实现(最近的 PostgreSQL 版本对其进行了重要改进)。如果您需要这样做,很难说 - 这首先取决于数据量,但也取决于其他因素。您可以将transaction表创建为分区表,但只能使用单个默认分区,至少在您选择使用版本 11 或更高版本时如此。在这种情况下,如有必要,您可以决定稍后添加年度分区。