数据库太大-存储为行还是序列化数据?

时间:2019-05-27 11:58:20

标签: mysql database laravel performance eloquent

我有一个测验应用程序,它构成了许多包含问题的模块。每个问题都有许多类别(多对多)。每次测验完成时,用户的分数就会发送到“分数表”。 (为清楚起见,我附上了实体关系图。)

我一直在考虑按类别细分用户分数(即,用户完成测验时将获得总体测验分数以及每个类别的分数)。

但是,如果每个测验至少包含30个问题,则每个测验可能包含15-20个类别。因此,如果一个用户完成测验,那么它将在分数表中至少创建15-20行。在有多个用户的情况下,“分数”表将很快变得非常大。

我认为这会影响从“分数”表中检索数据的性能。例如,如果我想计算特定类别用户的平均分数。

有人对我仍然可以基于类别存储分数有更好的建议吗?

我考虑过序列化JSON数据,但是当然,这有其局限性。

Database ERD

2 个答案:

答案 0 :(得分:1)

数据库应该能够处理数百万行,并且您的设计没有内在的错误。我会建议一些事情:

  • 在以下(或以下的)用户ID,考试ID(我假设您称之为可计分ID),考试类型(可计分类型?)和创建日期中进行索引。

  • 随着表的增长,对其进行分区。潜在的候选人可能是创建日期时段(按年或年/月可能会很好地工作),或者如果学生是特定班级的学生,您可能会拥有课程时段

  • 随着表的增长,您可以将分区移动到不同的磁盘上(如何对数据进行分区在这里将变得更加关键,因为如果数据必须通过太多的分区,则可能最终会损害性能)而不是帮助)

除此以外,还有一个建议是将分数表分为两个score和scoreDetail。得分表将包含诸如用户ID,考试ID,总得分等顶级信息。而子表将包含按类别(哲学等)的得分。我敢打赌80%的时间人们只会在乎最高分。这样,您仅在某人希望获得特定考试分数的详细信息时才可以伸手去拿更大的桌子。

最后,您可能希望按类别而不是按列来获得评分,以使其更易于进行分析和汇总,但这不一定能提高性能,并且实际上取决于您打算如何使用数据。 / p>

最后,最佳的优化实际上取决于您打算如何使用数据。我建议仅创建一个随机数据集,以表示几年的数据并加以利用。

答案 1 :(得分:0)

我怀疑序列化会给您带来重大好处。 我什至敢说您这样做会限制数据库的功能。

关系数据库旨在在表中存储很多行,并且它们通常也使用自己的压缩算法,所以应该没事。

此外,您每次想从表中读取时都需要反序列化。那将消除使用SQL语句进行排序,过滤,JOINing等的可能性。

因此,最终,与直接存储行相比,序列化可能会给自己造成更多麻烦。