1 :1 关系.我是否应该为单个可选值创建一个新表?



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

我想知道购买是否退款以及退款日期

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

还是应该创建一个名为refunds的新表,其中有purchase_idrefund_date

从关系模型的角度来看,我了解到我应该为它创建一个新表,但它肯定会占用更多的磁盘空间,并且会使查询复杂化(必须使用 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

案例2:

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    

我了解到我应该为它创建一个新表,但它肯定会占用更多磁盘空间并使查询复杂化

你学到的东西是不正确的。 实际答案取决于许多因素。 但在大多数数据库中,NULL日期和NULL号仍将占用数据页中的空间。 因此,您正在展开purchases表中的每一行,即使是那些没有返回的行。 这个额外的空间会减慢表上的所有处理速度。

相比之下,returns表将仅包含返回值。 假设这些很少而且相距甚远,它可能比替代解决方案小得多。 主键存在重复,但对于稀疏数据,这将是少量空间。

至于连接的性能。 两个表大概具有相同的主键。JOIN应该非常快 - 尽管与仅读取一行中的数据相比有一些开销。

此外,更新购买行比"仅"向任一表插入新行会产生更多的开销。 此类更新可能会减慢对表的查询速度。

通常,最好设计实际表示数据的数据模型。 当您更好地了解数据的使用方式时,请担心性能。

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

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

如果进一步的需求确实进一步出现,那么可能会破坏并且必须重写的现有代码就会少得多。

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

如果查询已正确编制索引并以优化的方式编写,则在性能方面应该不会发现差异

(通常的警告:您的数据大小和YMMV适用(

最新更新