存储数据的理想方式可能是 PostgreSQL 中的几种可能性之一?

Ideal way to store data that can be one of a few possibilities in PostgreSQL?

我不太确定这种数据是否有专门的术语,但这个概念类似于 C++ std::variant(但也许在 PostgreSQL 中使用类变体结构)。

例如,假设我有一个 table purchases,它有一些列:

CREATE TABLE purchases (
    purchaseid bigserial,
    buyerid bigint,
    name text,
    ...
);

每次购买都将通过少数几种可能性之一进行支付,例如支票或比特币。每种可能性都有需要保存的不同关联字段。

支票付款需要保存支票号码和银行名称,比特币付款需要保存发件人的比特币地址和 return 比特币地址。

由于字段不同,将支票支付和比特币支付放在不同的 table 中似乎是明智的(我对 PostgreSQL 知之甚少)。

如果我知道每次购买只能由[支付],那么存储此类数据(并将它们与 purchases 中的每一行相关联)的理想方式是什么? =26=]或者检查比特币,但不检查两者?

我在这种情况下采取的方法确实如您所建议的那样:您需要一个不同的 table 来获取支票详细信息、比特币详细信息等。这些 tables 必须包括购买 ID 和购买table 必须有付款类型 ID。 然后当希望查看购买和详细信息时,您需要进行左连接。这里的技巧是在视图中有一个 case 语句,这样根据 paymenttypeid,您 select 从当前左侧加入 table。在执行此操作时,您需要确保 select 来自详细信息 table 的列数相同,并对类型进行适当调整。

所以你得到类似的东西:

SELECT p.purchasedate, 
       p.otherfields,
       pt.description,
       case p.paymenttype 
           WHEN 1
               THEN bd.DetailField1 -- cast if necessary
           WHEN 2
               THEN cd.DetailField1 -- cast if necessary
           END AS Detail1,
       case p.paymenttype 
           WHEN 1
               THEN bd.DetailField2 -- cast if necessary
           WHEN 2
               THEN cd.DetailField2 -- cast if necessary
           END AS Detail2
       FROM purchases p
       inner join paymenttypes pt 
           on p.paymenttypeid = pt.id
       left join bitcoindetails bd 
           on bd.purchaseid = p.id
       left join chequedetails cd 
           on cd.purchaseid = p.id

虽然这是基于左连接,但我们知道在实践中它总是会成功,因为 case 语句是基于 paymenttypeid 的。这意味着我们总是 select 从正确的细节 table 开始。详细信息必须出现在记录 selected 的详细信息 table 中,因为它与付款类型 ID 匹配。