构建一个MySQL数据库,该数据库可以占用无限多的字段



我正在构建一个MySQL驱动的网站,该网站将分析各种客户分发的客户调查。一般来说,这些调查的结构相当一致,我们客户的大多数数据都可以简化为相同的标准化数据库结构。

然而,每个客户最终都不可避免地会为他们的客户提出与我们其他客户无关的高度具体的人口统计问题。例如,尽管我们所有的客户都会询问客户满意度,但只有我们的汽车客户会询问客户是否知道如何驾驶手动变速器。

到目前为止,我一直在为所有一般人口统计信息的respondents表添加列,其中混合了许多default null。然而,随着我们添加更多的客户端,很明显,这将导致大量列几乎总是空的。

有没有办法始终如一地做到这一点?我宁愿在respondents表中保留尽可能多的标准化数据,因为我们的导入脚本已经为该表编写好了。我的一个想法是构建一个respondent_supplemental_demographic_info表,该表包含response_id、population_field、population_value列(因此手动变速器示例可能变为:"ID999"、"can_drive_manual_indicator",true)。这可能包含无限多的人口学字段,但从处理和编程的角度来看,这将是令人难以置信的痛苦。有什么想法吗?

这个问题的解决方案称为实体属性值(EAV)。这将"取消平移"列,使它们成为表中的行,然后将它们绑定到一个视图中。

EAV结构在学习如何处理时有点棘手。它们需要更多的联接或聚合才能获得单个视图。此外,价值观的类型也变得具有挑战性。通常有一个值列,所以所有内容都存储为字符串。当然,您可以使用不同类型的类型列。

它们也占用了更多的空间,因为实体id在每一行上都重复(我认为在您的情况下是response_id)。

虽然不是所有情况下都有想法,但它们在你描述的情况下是合适的。您正在无限期地添加属性。您将快速超过单个表中允许的最大列数(根据数据库的不同,通常在1000到4000之间)。您还可以分别跟踪每列中的每个值——例如,如果它们在不同的时间添加,您可以在它们进入时保留一个时间戳

另一种选择是为每个客户端维护一个单独的表,然后使用其他一些过程将数据组合成一个通用的数据结构。

不要选择具有键值对(字段id、字段值)的表,因为这是低效的。

在你的情况下,我会为每个客户创建一个表格。以及描述这些表的元数据表(在一个单独的DB中)。有了这些元数据,您可以生成SQL等。这绝对比拥有许多空列要好。或者复制、改编剧本。它需要一些编程,其中应用程序使用元数据生成SQL、收集数据(没有特定于客户的语义知识)和生成报告。

最新更新