我正在设计一个系统,用于存储有关某些订单的信息,该系统具有多个可选属性,我想知道在数据库中存储信息的最佳方式是什么。
我多次看到此类问题,但没有具体答案,所以这里是:
我有一个包含许多可选参数的订单表,我想知道什么设计会给我最佳实践和最佳性能:
到目前为止,我想出了这个问题的 3 个解决方案:
第一个也是最简单的方法是忽略可选参数的事实,并存储“NULL”值,当不需要输入时,结果可能如下:
Table:
|Id|Column1|Column2|Column3|Column4|Column5|Column6|Column7|Column8|Column9|Column10|
|1 | Data | NULL | Data | Data | NULL | NULL | NULL | Data | Data | Data |
|2 | Data | Data | Data | NULL | Data | Data | NULL | Data | NULL | Data |
|3 | Data | NULL | NULL | Data | NULL | NULL | NULL | Data | NULL | Data |
|4 | Data | NULL | Data | Data | NULL | Data | NULL | NULL | Data | Data |
等等...这个示例很简单,您可以看到我的意图(表中有很多 NULL 值)。
第二个解决方案是拥有具有一对多关系的元数据表,该表将存储参数(如果存在)(类似于 wordpress 存储帖子的元数据?),例如它的外观(这是前 2 行的示例)上表):
MainTable:
|Id|Column1|Column10|
|1 | Data | Data |
|2 | Data | Data |
MetaDataTable:
|Id|MainTId|AttrKey|AttrValue|
|1 | 1 |Column3| Data |
|2 | 1 |Column4| Data |
|3 | 1 |Column8| Data |
|4 | 1 |Column9| Data |
|5 | 2 |Column2| Data |
|6 | 2 |Column3| Data |
|7 | 2 |Column5| Data |
|8 | 2 |Column6| Data |
|9 | 2 |Column8| Data |
等等...这完全删除了 NULL 值,但我在这种设计中看到的问题是表大小随着每条新记录呈指数增长,并且我认为稍后查询此类表的性能会在精神上杀死我,但是如果我使用联接,也许这不会有问题?。
第三种解决方案是将可选数据序列化为 JSON 字符串,然后保存在数据库中,有点像 mongodb?。看起来是这样的:
Table:
|Id|Column1|Column10| AttrData |
|1 | Data | Data |"{"Column2":null,"Column3":"Data","Column4":"Data","Column5":....|
|2 | Data | Data |"{"Column2":"Data","Column3":"Data","Column4":null,"Column5":....|
如何显示数据的其余逻辑将留给 php。
那么哪种解决方案将最佳实践和性能相结合,或者也许还有其他方法,我无法想到。请注意,我没有提及一对一的属性表解决方案,因为我认为从不同的表查询每个参数会降低性能,因为我会有很多表。
最佳答案
实际上,这取决于您尝试存储的参数本身的 volatile 以及您需要多少个不同的值。
如果许多参数往往会经常更改并且稍后需要添加许多参数,我倾向于选择 JSON 解决方案:它更易于维护,因为添加参数也不需要更改数据库就像删除一个一样。 JSON 结构一致性的维护也可以封装到具有 getter 和 setter 的特定对象中。
如果只有少数几个不同的参数可以在未来 42 年保持稳定,那么从我的角度来看,像 #2 这样的关系(标准化)结构是最好的。
关于Mysql 一对一 vs null vs json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25236911/