【问题标题】:Horizontal vs vertical data approach in MySqlMySql 中的水平与垂直数据方法
【发布时间】:2021-03-14 07:26:12
【问题描述】:

我正在我们的“旅游与旅行”应用程序中创建分析模块。

以下是用户在我们的应用程序中必须执行的步骤:

第 1 步: 用户搜索任何城市的旅游。

第 2 步: 用户查看游览的详细信息。

第 3 步:如果用户为他/她找到了完美的旅行,他/她就预订了旅行。

第 4 步: 在预订旅游时,用户输入乘客详细信息。

第 5 步:用户查看最终数据。

第 6 步: 用户在线支付并预订旅游。

现在我想将用户的每个活动存储在我们的系统上,以供我们分析。为此,我有以下表格结构:

Id user_id tour_id city_id searched_at viewed_at entered_pax_info_at reviewed_at booked_at
151 34 678 1290 2021-03-14 12:00:00 2021-03-14 12:05:00 2021-03-14 12:10:00 2021-03-14 12:15:00 2021-03-14 12:20:00

现在在分析此结构中的数据时,管理员用户可能需要基于以下列的数据:

  • searched_at

  • viewed_at

  • entered_pa​​x_info_at

  • reviewed_at

  • booked_at

例如。管理员用户可以询问以下数据 - 给我报告从 2021 年 1 月到 2021 年 3 月预订的旅游“ABC”。等等...

现在要对大量数据进行这样的高效搜索,我必须在上述每个列上放置索引。通过这样做,读取数据时不会出现效率问题,但会在写入、更新操作时花费我。

为了解决上述问题,我正在考虑结构表:

id user_id tour_id city_id activity_type date
50 34 678 1290 searched 2021-03-14 12:00:00
51 34 678 1290 viewed 2021-03-14 12:05:00
52 34 678 1290 pax_info 2021-03-14 12:10:00
53 34 678 1290 reviewed 2021-03-14 12:15:00
54 34 678 1290 booked 2021-03-14 12:20:00

现在为了在上面的表结构上有效地搜索大量数据,我可能必须只在 activity_type 上放置 indexes日期列。

但对我来说,这种结构的缺点是与第一种方法相比,它会占用很大的空间。

我对哪种方法(在以上两种或任何其他方法中)将在可扩展性和功效方面成为未来的证明感到困惑。

任何解决此问题的帮助将不胜感激。

【问题讨论】:

  • 在这种类型的数据集上写入和更新的开销将非常低。在这不再正确的时候,要么你将变得足够富有以寻求专业帮助,要么太富有而无法关心。 (爱)过早优化是万恶之源
  • 这张表有多少行?每有多少插入/更新?一百万行可能不是问题。每秒 100 次修改可能不是问题。
  • 我是否正确地说只有 0 或 1 个“预订”,但所有其他项目都可以重复发生?这表示这些日期不能是单个表中的列。
  • 虽然我同意“...过早优化...”,但我们至少可以将您推向一些总体方向,让您获得更好的立足点。 (在其他情况下,一个常见的例子是警告 EAV 的危害。)
  • 或者该列可能是“FIRST_viewed_at”?这可以通过稍微复杂一点的 IODKU 轻松处理。

标签: mysql sql database database-design query-optimization


【解决方案1】:

您的第二个选择比您的第一个要好得多。一方面,它使您的系统可以灵活地确定要分析的步骤数量。规范化(垂直)表几乎总是比非规范化(水平)表更好地扩展。

关于表和索引使用的空间? Fuggedaboudit!磁盘 / SSD 空间真的很便宜,而且每个月都会变得更便宜。

除非您的系统已经有数千万行,并且您的数据库管理员为了性能而迫使您对表进行非规范化,否则不要担心表的大小。认真的。

【讨论】:

    【解决方案2】:

    分析数据库不应该是操作数据库。事实上,我经常使用批量更新的分析数据库,而且很少(如果有的话)有更新。通常,分析师不喜欢在他们解决问题时改变他们的数据。

    换句话说,要么你需要重新考虑你的方法,要么你没有描述完整的问题。

    您描述的第一个表对于用户来说似乎是一个很好的汇总表,可能非常适合分析师。它不适合作为数据的操作存储。在我生活的世界里,人们的搜索并不一致。他们在一个城市寻找最好的旅游,找到价格和其他细节,回去检查其他人。等等。这是你的结构不允许的“导航”和“路径分析”。

    这样的汇总表可以批量生成。即使在相对大量的数据上,这也可能只需要一两分钟,而且每天一次就足够了。如果是这样,问题就解决了。没有更新。索引是分析方面需要的。

    另一方面,有很多分析表明这种结构不支持。例如,用户在决定最终城市之前查看了多少个城市?好吧,也许你可以勉强回答这个问题。

    【讨论】:

    • 此外,有趣的索引位于摘要表上,而不是“事实表​​”上。后者只需要一个唯一的密钥。汇总表的大小是事实表的十分之一。
    • “多少个城市”需要知道两次点击来自同一个人。这需要浏览之前登录。这是一个商业决策。
    【解决方案3】:

    我认为你需要 2 张桌子

    • 一个用于浏览活动。在这种情况下,您可能甚至不应该识别用户;让他们匿名。
    • 一个用于预订、支付等(可能不止一张桌子,由于标准化等原因)

    浏览表可能只得到INSERTs,而且还有很多。如果会有数百万行,那么我们应该谈论“汇总表”。您不必决定他们究竟总结了什么,而是等到管理员要求一些“报告”。

    INSERTs 相比,预订表中的INSERTs 将更少,UPDATEs 可能更多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 2016-05-31
      • 2016-05-01
      • 1970-01-01
      相关资源
      最近更新 更多