1:1 关系。我应该为单个可选值创建一个新的 table 吗?

1:1 relationship. should I create a new table for a single optional value?

假设我有购买。 这些购买可以选择退款。

我想知道购买的商品是否已退款以及退款发生的日期。

我是否应该有一个用于购买的 table 和一个名为 "refunded_date" 的列,默认情况下为 null 并且包含退款日期?

或者我应该创建一个名为 refunds 的新 table,其中我有 purchase_idrefund_date

从关系模型的角度来看,我了解到我应该为它创建一个新的 table,但它肯定会占用更多磁盘 space 并且会使查询复杂化(必须使用 LEFT JOIN),甚至可能使它们变慢。

示例一:

Purchases
============
id | product | purchase_date | email | license | refund_date
-------------------------------------------------------------
1  |    X    |        X      |    X  |    X    |     NULL
2  |    X    |        X      |    X  |    X    |  2020-02-12

案例二:

Purchases
============
id | product | purchase_date | email | license
---------------------------------------------- 
1  |    X    |        X      |    X  |    X   
2  |    X    |        X      |    X  |    X    


Refunds
============
id | product_id | date
---------------------------------------------- 
30  |    2      |  2020-02-12    

I learned I should be creating a new table for it, but it will definitely take more disk space and will complicate queries

你学到的是不正确的。实际答案取决于许多因素。但在大多数数据库中,NULL 日期和 NULL 数字仍然会在数据页中占据 space。因此,您正在扩展 purchases table 中的每个 行,即使那些没有 returns 的行也是如此。这个额外的 space 会减慢 table.

上的所有处理速度

相比之下,returns table 的值只有 returns。假设这些很少而且相差很远,它可能比替代解决方案小很多。主键有重复,但对于稀疏数据,这将是少量 space.

至于联接的性能。两个 tables 大概有相同的主键。 JOINs 应该相当快——尽管与仅读取一行数据相比有一些开销。

此外,更新购买行比"merely"向任一table插入新行产生更多开销。此类更新会减慢 table.

上的查询速度

一般来说,最好设计出真正代表数据的数据模型。当您对数据的使用方式有了更好的了解时,再担心性能。

我倾向于将其添加为单独的 table。

这是因为虽然您当前的需求只是存储退款日期,但您的应用程序的未来版本可能希望使用其他信息对此进行扩展,例如 - 退款原因、退款金额、PDF 收据等

如果确实有进一步的要求,那么现有的代码可能会崩溃并且必须重新编写。

正如您所说,目前它可能会使查询稍微复杂一些,但对我来说,这是值得为以后避免痛苦而付出的代价。正如戈登所说,如果您创建额外的 table,您也不必为每个未退款的购买存储 NULL - 每次退款只需存储一行。

如果查询被正确索引并以优化的方式编写,您应该会发现性能差异不大

(通常注意事项:数据大小和 YMMV 适用)