绘制这种寻找性能和|或磁盘空间节省的“关系”的最佳方法是什么?

Rey*_*rPM 3 mysql mariadb performance database-design query-performance

我正在处理一个数据库图表,我有一个名为cm_identifier_type. 该表的每条记录都可以有或没有可下载的文件(保存了文件路径)。我已经确定了两种可能的方法来实现这一目标。

  • 将列放置download_fileVARCHAR(250)NULL默认设置为(这是因为并非所有记录都与下载相关)

在此处输入图片说明

  • cm_identifier_type和 新表之间创建关系cm_download_file

在此处输入图片说明

现在,关于性能、磁盘空间节省、查询节省等,您会怎么做?您对这种边缘情况有什么建议?

注意:目前我使用的是 MariaDB 10.1.x 但这将在 MySQL 实例中,可能是 5.x 左右我完全不确定,因为我还没有得到这些细节

Joe*_*own 5

如果您有很多关于可选列为空的频率以及需要读取非空列的频率(与核心、强制列相反)的特定统计信息,那么您可以计算空间节省(或不节省)和至少你可以得出一些性能实验来测试每种方法。

对于将可选列分隔到单独的表中是否“更好”,没有经验法则。

“更好”是一个主观术语。什么是有价值的?磁盘空间、CPU 周期、查询响应时间、代码简单性?如果不首先考虑要优化的是什么,就不能考虑一种方法相对于另一种方法的相对优点。

您可能希望将可选列移动到单独的 1:1 相关子表的原因有很多。有关这些原因的更多讨论,请参阅我对这个问题的回答。

在您的情况下,由于您担心空间,因此您需要记住有关数据物理存储方式的一些事项:

  • 如果它们是空的,可变大小的字符串不会占用太多空间。
  • 每个可为空的列都需要一个位来指示它是否为空。
  • 带有可选列的单独表需要再次存储主表的主键(作为外键),并且该列上也可能有单独的索引。

有很多相互竞争的影响,哪个占用更少的空间,哪个性能更好。你需要考虑:

  • 可选数据多久丢失一次?如果它真的很少见,那么也许您可以通过将其隔离来节省空间。
  • 您需要多久读取一次可选数据?如果您每次都阅读它(无论是否存在),那么可能一直加入它的效率会降低。
  • 另一方面,如果它不经常出现并且您几乎从未阅读过它,即使它有,那么读取仅包含强制性列的较短记录可能更有效?

另一件需要考虑的事情,甚至可能是最重要的事情,是您是否通过尝试预先优化来过度考虑这个问题。磁盘很便宜。CPU很便宜。程序员很贵。除非您需要关注大规模,否则最好的答案是让您拥有最简单(错误最少,最容易维护)的代码。