【问题标题】:Need Advice: Is this a good use case for a 'NoSQL' Database? If so, which one?需要建议:这是“NoSQL”数据库的好用例吗?如果有,是哪一个?
【发布时间】:2010-09-24 17:17:19
【问题描述】:

我最近一直在研究 NoSql 选项。我的场景如下:

我们从世界各地偏远地区的定制硬件收集和存储数据。我们每 15 分钟记录一次来自每个站点的数据。我们最终希望每 1 分钟移动一次。每条记录有 20 到 200 个测量值。一旦设置硬件记录并每次报告相同的测量值。

我们面临的最大问题是我们从每个项目中获得不同的测量值。我们测量了大约 50-100 种不同的测量类型,但是任何项目都可以有任意数量的每种测量类型。没有可以容纳数据的预设列集。因此,我们在系统上设置和配置项目时,使用所需的确切列创建和构建每个项目数据表。

我们提供工具来帮助分析数据。这通常包括更多的计算和数据聚合,其中一些我们还存储。

我们目前正在使用 mysql 数据库,每个客户端都有一个表。表之间没有关系。

NoSql 看起来很有希望,因为我们可以存储一个 project_id、时间戳,然后其余的就不会被预设。这意味着一张表,数据中的更多关系,但仍处理各种测量。

“NoSql”解决方案是否适合这项工作?如果有,有哪些?

我一直在研究 MongoDB,它看起来很有希望......

说明示例:

项目 1 记录了 5 个数据点,mysql 表列如下所示: 时间戳、温度、风速、降水、辐照度、风向

项目2有3个数据点记录mysql表列: 时间戳、温度、辐照度、温度2

【问题讨论】:

  • 你有多少客户?
  • 目前 150 个,按照我们目前的速度,我们每年增加约 100 个,但我们预计(希望)会增加。期望该系统在未来几年内需要处理数千个项目并不是不合理的。

标签: ruby-on-rails ruby database nosql


【解决方案1】:

简单的答案是这类问题没有简单的答案,找出适合您的方案的唯一方法是投入研发时间。

这个问题很难回答,因为 OP 没有说明性能要求。它似乎是 7500 万/年的记录,写入速率为 num_customers*1 分钟(很低)的许多客户,但我没有所需的读取/查询性能的数据。

实际上,您已经有一个使用horizontal partitioningsharded 数据库,因为您将每个客户存储在一个单独的表中。这很好,并且会提高性能。但是,您尚未确定存在性能问题,因此需要先对此进行测量并评估问题的规模,然后才能修复它。

NoSQL 数据库确实是解决传统 RDBMS 性能问题的好方法,但它不会提供自动可扩展性,也不是通用的解决方案。您需要找到您的性能问题修复,然后设计(nosql)数据模型来提供解决方案。

根据您要实现的目标,我会查看 MongoDBApache CassandraApache HBaseHibari

请记住,NoSQL 是一个模糊的术语,通常包含

  • 读取或写入性能密集型应用程序。通常以牺牲另一个为代价来牺牲读取或写入性能。
  • 分布和可扩展性
  • 不同的持久性方法(RAM/磁盘)
  • 一种更结构化/定义更明确的访问模式,使临时查询更加困难。

因此,首先我想看看传统的 RDBMS 是否可以使用所有可用技术实现所需的性能,获取High Performance MySQL 的副本并阅读MySQL Performance Blog

版本 1:

鉴于您的 cmets,我认为可以公平地说,您可以使用上述 NOSQL 引擎之一实现您想要的。

我的主要建议是设计和实施您的数据模型,但您目前使用的并不正确。

所以请查看Entity-attribute-value model,因为我认为它完全符合您的需求。

在考虑使用哪种技术之前,您需要正确设置数据模型,说实话动态修改架构不是数据模型。

我会使用传统的 SQL 数据库来验证和测试新的数据模型,因为管理工具更好,并且在您优化数据模型时通常更容易使用模式。

【讨论】:

  • 我们正在研究 NoSQL 选项的最大原因之一是我们的数据库列具有更大的灵活性。一个项目可能有 5 列,另一个可能有 150 列。在某些情况下,我们可能需要在项目上线后更改列。我们将此过程称为“重建表”,我们的应用程序通过添加或删除字段来重新定义表结构。
  • EAV 听起来不错;老实说,“重建表”是一种可怕的数据存储方式,是模式错误的线索。您如何看待 EAV?
  • 重建表是一种可怕的方法,这也是我们寻求改变它的原因。 :) - EAV 与下面推荐的 Miky D 方法相同。通过两个建议,我们将仔细研究它。我认为我们将在几周内进行分支并尝试 EAV 和 MonogoDB 方法。我现在不会将任何一个答案标记为已接受,但会随着我们发现在我们的确切情况下最有效的方法而更新这个问题。感谢您的建议和链接。
【解决方案2】:

好吧,我可能会因为没有直接回答你的问题而被激怒,但我还是要说出来,因为我认为这是你应该考虑的事情。我没有使用 NOSQL 数据库的经验,所以我不能推荐一个,但就关系数据库而言,可能会有更好的设计适合您的情况。

首先 - 删除每个客户的 1 个表。相反,我会构建一个多对多模式,其中会有以下表格:

  • 客户
  • 测量类型
  • 测量

Customers 表将包含客户信息和唯一的 CustomerID 字段:

   CustomerID      | CustomerName  |   ..and other fields
 ---------------------------------------------------------------------

MeasurementTypes 表将描述您支持的每种测量类型,并指定一个唯一名称(MeasurementType 字段)来引用它:

   MeasurementType | Description   |  ..and other pertinent fields
 ---------------------------------------------------------------------

测量表是汇总所有数据的地方。对于收集到的每个数据点,您将拥有一个记录,并带有客户 ID、测量类型、时间戳和唯一的“批次”标识符(以便能够将来自每个测量的数据点组合在一起)——当然还有测量值。如果您的测量需要不同类型的值,您可能需要在设计上有点创意,但很可能测量值都可以用一种数据类型表示。

  Customer  | MeasurementBatch |  MeasurementType  |  Timestamp  |     Value   |
--------------------------------------------------------------------------------
      1     |    {GUID}        |  'WIND_SPEED'     |      ...    |    ...
--------------------------------------------------------------------------------
            |                  |                   |             |             |

这样,您可以拥有一个非常灵活的设计,让您可以独立于其他客户为每个客户添加尽可能多的数据点。并且您可以获得关系数据库的好处..

如果您的 SQL 引擎支持此功能,您甚至可以按客户列对 Measurements 表进行分区。

希望这会有所帮助..

编辑

我必须提到,我与 Microsoft 没有任何关联,也没有试图给他们免费广告 - 碰巧我最熟悉他们的 SQL 服务器。

基于 Alan 的评论 - 关于 SQL 数据库是否可以支持每年几千万条记录的数据量,并有可能每年增长到十亿条记录 - 对 MS 的限制/规格进行了很好的总结此处提供 SQL 服务器:

http://msdn.microsoft.com/en-us/library/ms143432.aspx

似乎对每个表可以拥有多少记录的唯一限制是磁盘上的可用大小(如果您要针对该数据运行某些报告,可能还有 RAM)。

【讨论】:

  • 我们已经研究过这样的事情。我们预见的问题是测量表的大小。按照我们目前 15 分钟的数据收集速度,我们每年每个项目将达到 525 万条记录。当我们移动到一分钟间隔时,每个项目每年有 7880 万条记录。然后,通过 100 个项目,我们每年将达到 70 亿条记录。这是MySql可以处理的吗?
  • 我不确定 MySQL 在每个表的记录数方面的限制,但是通过仔细的数据库设计(即分区),像 MS SQL Server 或 Oracle 这样的产品在处理几亿条记录方面应该没有问题表中的记录..特别是因为每条记录都会很小。您可以对 MeasurementType 使用整数标识符并使​​用 unix 时间戳,根据您用于 Value 的数据类型,记录的大小将在 32 到 44 个字节之间。
【解决方案3】:

FWIW:在 MySQL 中工作和扩展 EAV 架构一年半之后,我们找到了我们的选择:

  1. 将数据库移至昂贵的裸机设置。
  2. 重新调查 NoSQL 解决方案。

我们最终选择了 Cassandra 并使用深受 OpenTSDB 项目影响的架构。

Cassandra 是存储时间序列数据的一个非常好的选择,并且很好地满足了我们的要求。

【讨论】:

    【解决方案4】:

    我假设如果您有很多客户,您最终会拥有很多桌子。我将首先删除此限制并转移到单个表模型或为客户和具有适当关系的数据提供一个表。这样你就可以保留mysql。不要假设 mysql 对一切都不利。

    就 NOSQL 而言,这取决于您的数据模型和使用模式,但如果您有很多客户端并且您更喜欢这种模型,那么 couchdb 视图可以解决这个问题,因为 couchdb 可以支持数千个视图。您可以将所有数据存储在 couchdb 中的一个数据库中,但每个客户端都有一个视图。我不知道mongodb如何解决这个问题。

    【讨论】:

    • 我应该更具体。我们使用 mysql 数据库存储关系数据并且确实有多租户。因为每个客户的数据点都不同,所以每个客户都有自己的数据表,该数据表严格存储测量数据,每个测量都有自己的列。
    • 我认为作者不一定说MySQL不好,但更想知道是否有更好的选择。键/值存储似乎是为每个表容纳不同列的好方法。
    • 您提到“我们目前正在使用 mysql 数据库,每个客户端都有一个表” - 如果您有很多客户端,这似乎很愚蠢。也许我只是不明白这个例子,因为它看起来仍然很模糊。
    • 另一种方法是将它们全部放在一个表中,其中可能有 500 多列,其中大多数列对于每个项目都是空的。这对我来说似乎是一个更糟糕的选择。不幸的是,每个站点都记录了不同数量的测量值。没有一致性,也无法强制执行。
    • 如果您可以将每个客户端表示为从 0 到 65k 的数字,那么您只需要一个 SMALLINT 类型的列即可为每个客户端标记一个位。您可以使用它来编写 SQL 来获取客户端集或测试单个客户端以获取数据记录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 2019-06-15
    • 2012-04-22
    • 1970-01-01
    • 2010-09-24
    • 2021-10-15
    相关资源
    最近更新 更多