【问题标题】:Storing large amount of data in database在数据库中存储大量数据
【发布时间】:2011-07-25 09:16:43
【问题描述】:

我对存储大量数据有疑问。情况如下:

  1. 我要收藏

    • GPS 坐标(纬度和经度)(每分钟甚至更短的间隔,但我正在考虑每分钟)
    • 事件,可以在多个坐标中重复
    • 输入的日期时间或时间戳(不知道在我的情况下哪个更好用)
    • (用户 ID)
  2. 我希望能够查询:

    • 按区域划分事件(定义经纬度范围,例如从 (1,1) 到 (2,2))
    • 从日期 X 到日期 Y 的用户跟踪(一个或多个用户)

到目前为止,我正在考虑解决方案:

解决方案 1

id_user (int)
id_experince (int)
id_event (int)
dt (datetime)
latitude (decimal)
longitude (decimal)

我开始进行一些计算,结果类似于: - 每天/用户大约 500 个条目 - 因为我正在为一些负载准备应用程序,所以可能有大约 100-150 个用户,这将是 75000 个条目/天 - 一个月后将有数百万条条目

可能解决方案1不是很好的解决方案,因为数据库的大小增长非常快。

解决方案 2

有 2 个表,其中一个是根据事件的聚合坐标,例如我有事件“晚餐”,它需要 30 分钟,所以 30 个条目将被分组到一个 BLOB 类型的字段中。该表将如下所示:

id_user (int)
id_experience (int)
id_event (int)
dt (datetime)
coordinates(blob)

另一个表,它已经计算了一些“宽度”和“长度”的位置,并具有指向第一个表的指针

latitude (decimal)
longitude (decimal)
id_entry_in_first_table (int)

这个解决方案只是部分解决了我的问题,想象一下,有些事件不会超过几分钟,并且需要第二个数据库..

解决方案 3

这可能不是非常正确的解决方案,但似乎有些道理。我有用户与某种体验相关联,它有开始日期和结束日期。当体验添加时,我将为该体验创建数据转储并保存到文件中,删除与体验相关的条目。当用户想咨询“存档”体验时,我会在一天之内(例如)将数据加载到某个临时表中并删除,这种情况下我将按照解决方案1保存数据。

主要问题是:就数据库性能而言,所提出的解决方案是否可以接受?我的问题有更好的解决方案吗?

【问题讨论】:

  • Float 是一种非常糟糕的数据类型,不适合用于 lat long。它不准确,会导致距离计算不正确。使用带有预先定义的小数位的小数。
  • mySQL 有空间数据类型吗?这就是你应该使用的。
  • 目前我用十进制设计了数据库,很抱歉浮点数,它是伪代码:) 但还是感谢您的提前。

标签: mysql database database-design


【解决方案1】:

“数以百万计的条目”听起来很多,但这是数据库旨在处理的内容。无论您如何设计它,如果您根据以后想要从中提取结果的方式对其进行优化(因为这将花费时间而不是插入),那么您就可以开始了。

当然是这么说...如果您有很多用户同时对您的数据库做很多事情,那么我认为您的服务器/带宽会在您的数据库之前运行!

【讨论】:

  • 但是您认为即使有索引表,有数百万个条目,数据库也不会成为瓶颈?
  • 这完全取决于数据库的整体设计、程序以及向用户提供内容的方式——但不应该如此。
  • 数以百万计的记录是一个非常小的数据库!关系数据库通常存储数十亿条记录,如果设计得当,性能会非常好。
  • 处理分钟数据时,如果插入时间超过一分钟,您将永远赶不上。高频数据的插入速度很重要,不能轻易忽视。我在一家大型公用事业公司工作,我们从数万米处获得 1 分钟的数据。我们绝对必须针对插入进行优化。
  • 那么,您的建议是坚持解决方案 1(我在我的问题中提出的问题)并根据我的需要对其进行优化(强调数据插入)?
【解决方案2】:

我会选择主细节方法。

两个优点:

  1. 你没有多余的条目(1 个主行和 x 个带坐标的子行)

  2. 它仍然很容易查询(与 blob 方法相比)。

    SELECT m.id_user, m.id_experince, m.id_event, c.latitude, c.longitude
    FROM master_table m
    LEFT JOIN child_table c ON m.id = c.master_table_id
    

如果您在 master_table_id 上设置外键或索引,即使主表中有数百万条记录,这也应该非常快

【讨论】:

  • 而且表的数量不是问题吗?我也在考虑这个解决方案,例如为每种体验制作“子”表。
  • 为什么要多个表?您可以将所有内容存储在一个表中并创建与主表的关系。如果您想获取体验的所有坐标,您可以从体验表连接到 master_table(来自示例)到 child_table:SELECT e.name, c.latitude, c.longitude FROM experience e LEFT JOIN master_table m ON e.id = m.id_experience LEFT JOIN child_table c ON m.id = c.master_table_id
【解决方案3】:

您可能想阅读以下内容:http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html

一般而言,只要您可以在查询中使用索引,庞大的表就不是问题 - 数十亿条记录可以在消费级笔记本电脑上进行查询。如果您打算扩展到大量历史记录,则应该有一个归档策略,但这不是一个重要的优先事项。

更棘手的是支持您在特定地理边界内查找事件的愿望;这很容易以各种讨厌的方式破坏您的索引策略。如果您必须基于数学运算进行查询,您可能无法使用索引 - 因此在 1 英里圆的半径内查找用户可能必须评估数据库表中每条记录的圆公式。

空间扩展为此提供了解决方案 - 但它们不是“免费”的,您必须专门为此优化您的设计。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多