Mysql一对一vs null vs json

Mysql一对一vs null vs json,mysql,json,database,Mysql,Json,Database,我正在设计一个系统来存储关于某些订单的信息,这些订单具有多个可选属性,我想知道在数据库中存储信息的最佳方式是什么 我见过很多次这样的问题被问到,但没有具体的答案,所以我说: 我有很多可选参数的订单表,我想知道什么样的设计能给我提供最佳实践和最佳性能: 到目前为止,我提出了3种解决方案: 第一种也是最简单的方法是忽略可选参数的事实,并在不需要输入项时存储空值。结果如下: Table: |Id|Column1|Column2|Column3|Column4|Column5|Column6|Colum

我正在设计一个系统来存储关于某些订单的信息,这些订单具有多个可选属性,我想知道在数据库中存储信息的最佳方式是什么

我见过很多次这样的问题被问到,但没有具体的答案,所以我说:

我有很多可选参数的订单表,我想知道什么样的设计能给我提供最佳实践和最佳性能:

到目前为止,我提出了3种解决方案:

第一种也是最简单的方法是忽略可选参数的事实,并在不需要输入项时存储空值。结果如下:

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   |
等等。。。这个例子很简单,您可以看到我在表中使用了这么多空值

第二种解决方案是使用具有一对多关系的元数据表,如果存在类似wordpress存储的posts元数据的参数,则该表将存储参数,例如,它的外观这是上面表的前两行的示例:

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  |
等等。。。这会完全删除空值,但我看到这种设计的问题是,表的大小会随着每个新记录呈指数增长,我认为以后查询这样的表的性能会让我精神崩溃,但如果我使用联接,这可能不会有问题

第三种解决方案是将可选数据序列化为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处理


那么,哪种解决方案是最佳实践和性能的结合,或者可能还有其他方法,我想不出来。请注意,我没有提到一对一属性表解决方案,因为我认为从不同的表中查询每个参数会降低性能,因为我会有这么多表。

实际上,这取决于您试图存储的参数本身的易变性以及需要的不同值的数量

如果有许多参数经常改变,并且以后需要添加许多参数,我倾向于使用JSON解决方案:它更易于维护,因为添加参数不需要数据库更改,也不需要删除参数。JSON结构的一致性维护可以用getter和setter封装到特定的对象中


如果只有少数几个不同的参数可以在未来42年内保持稳定,那么从我的角度来看,像2这样的关系规范化结构是最好的。

要得到一个非常集中的答案,缺少的一点信息是,你以后需要如何检索数据

既然是订单,我想你在查看订单时会想要所有可用的信息。但你只想按日期订购吗?或者您是否需要对数据进行一些筛选,如按国家或订单类型处理装运

您的第一个解决方案似乎是最直接、最容易处理的,并且不需要大量的MySQL技能来执行复杂的查询,因为您只需要处理一个表。我可以预见的一些问题是,如果你有上千个可能的参数,那么如果按照正常顺序只填充一打,那么拥有上千行就显得有些过分了。但如果大部分田地都被填满了,那就没事了。您还可以从键入列中获益。如果需要一个新列,在一个大表上,该过程可能需要很长时间,并且在该过程中该表将被锁定以进行写入

您的第二个解决方案是我喜欢在有大量易变信息时使用的解决方案。当我事先不知道数据和数据本身的名称时。以一个MySQL表为例,该表记录致命错误并转储当前范围的所有变量。这是非常有用的,但是当需要根据保存在订单中的数据搜索订单时,速度可能会变慢。最糟糕的是,您将无法根据数据键入列,因为它将存储任何内容

您的第三个解决方案将在以后给您带来一些问题。假设您想要搜索一个条件,则需要一个硬regexp,并且可能返回误报。如果需要对行进行更新,则需要使用PHP或其他脚本语言。一些信息,比如订单日期,应该放在不同的列中,这样你至少可以使用它来订购


综上所述,我将使用第一个解决方案,使用一个大表。这将使您的查询和服务器更加方便。但是,如果需要的数据列太多,并且大多数数据列并不总是被填充,那么选择选项一和选项二的混合。在订单表中保留订单所需的所有字段,并使用一个额外的表将额外的内容放入第二个解决方案中。通过这种方式,您可以混合两种解决方案的优点。

第二种方法也称为EAV Entity Attr
ibute价值建模,但我认为它在这里并不适用;也就是说,其中一些列可能可以组合在一起,即2NF,因此您可能需要引入多个表。我已经尽了最大努力回答了,但您要求的是非常具体的答案,而没有给出太多具体的细节。我们能了解一下存储数据的细节吗?还有,会有很多更新还是根本没有?您最初期望有多少个可选参数?查看列表时是否需要强大的高级过滤选项。。。好的,更多信息:数据存储应该是只读的,一旦写入就应该设置为stone,永远不会更新,关于读取重要信息,每个参数(如果存在)都应该读取并显示给用户,因此我们可以说每个参数都是重要的,但我明白你在atm机上的观点,我实际上已经实现了第二个解决方案,正如你所说,通过选择两个最佳方案,因为有一个静态属性一直存在,因此我将它们存储在主表中,所有其他可选的我都存储在另一个表中。但我预计表中会有数十万条记录,因为系统订单的设计是由其他系统生成的,而且大多数时候它们都没有被使用,尽管如此,我仍然需要存储关于它们的信息,所以一天内我可以预期有200条新订单记录,我担心过一段时间后,查询第二个表会很痛苦,因为它可能包含数百万条记录,因为每个新记录可以向第二个选项卡添加10-15行新行。如果您相应地设置索引,那么在显示数据时使用第二个表不会导致性能问题。如果要在WHERE语句中使用它的一列进行筛选,则只会导致一点降级。例如,在文本列上选择要比int慢得多,在第二种解决方案中,因为我们为所有数据提供了一种类型,所以您肯定需要使用text,这将强制在每次选择时都使用临时表副本。但是,如果您选择了文本列,也会发生这种情况。。。