就我而言,MongoDB是正确的选择吗?[关闭]


9

我将在Rails中构建我的第一个真实项目,该项目包含一个由3个主要部分组成的网络应用程序:

  • 不使用数据库的静态部分
  • 用户注册部分将需要一个数据库,我可以使用MySQL,因为每个用户的行将具有相同的字段
  • 用户可以在其中创建,组织,编辑...项目的“应用”,并与其他用户共享

将有几种项目类型,每种类型都有不同的选项,例如,我可能有带有以下选项的“视频”项目:

  • ID
  • 用户身份
  • collection_id
  • 标题
  • 平台(如果嵌入式)
  • 网址(如果已嵌入)
  • 文件名(如果托管在我的应用程序中)
  • 文件大小(我的应用程序上托管的ID)

和“地图”项:

  • ID
  • 用户身份
  • collection_id
  • 标题
  • 平台(谷歌地图,必应地图...)
  • 位置
  • 网址
  • 地图尺寸

对于用户,我可能会使用MySQL作为项目,因此MongoDB的灵活性可能会很有用,因为每个项目可能需要与另一个项目不同的选项

到目前为止,我一直使用PHP和MySQL(始终在小型项目的共享主机上使用),而可扩展性对我来说是一个全新的词。

我有时间学习,但我希望能够在1个月内完成一些具体的工作。

我已经阅读了很多有关MongoDB和NoSQL以及RDMS和MySQL的文章,尝试之后,我不得不说我喜欢MongoDB的工作方式:没有表,没有行以及它的文档JSON像这样:

  • 在我的情况下,您会推荐什么?为什么?
  • 关于可伸缩性,MongoDB可能存在问题?如果是的话(以数据库大小计),是否会出现这些问题,从而使我的应用程序速度大大降低?

编辑:应用程序将如何工作

由于许多人问这是我希望该应用程序如何工作:

  1. 用户注册
  2. 他已登录
  3. 他创建了自己的第一个收藏系列,可以创建无限的物品
  4. 项目是各种类型的,每种类型需要在数据库中保存不同的数据,并且可以添加或修改项目的类型

用户可以在其中创建其他集合和项目。

因此,对于集合及其内部的项目,我们都有CRUD,每个集合/项目都针对特定的用户

MySQL的主要问题是它没有灵活的架构,有办法解决这个问题(解决方法?)?

考虑NoSQL时,我唯一的疑问就是联接,例如,鉴于某个特定的选择,我想检索与集合中id = user_id的User相关的数据

编辑:继续使用MySQL的想法

在“项目”表中创建带有可选设置的字段,每个设置均用|分隔。或其他符号。

然后,我将在某处保存每个项目的可选设置的结构,例如,“ notes”项目类型需要两个可选设置“ colour”和“ strange_setting”,当我从MySQL获取数据时,我会将可选设置的字段拆分为一个知道数组中的第一项是用于“颜色”的,依此类推。

你怎么看?该解决方案有问题吗?你还有其他想法吗?


4
除非您向我们提出要解决的特定问题,否则有关技术建议的Matteo问题将不在讨论之列。您需要向我们提供有关您的项目的更多信息,以及为什么您认为需要使用除MySQL(您熟悉的MySQL)以外的任何其他数据库的信息。例如:是否有任何可扩展性问题,以及您需要花费多少时间研究新技术。考虑修改您的问题,如果需要,请将其标记为适当注意,以便我们审核您的修改。
扬尼斯2012年

Answers:


10

在您告诉我们您打算如何使用该应用程序之前,我们可能无法为您提供帮助。关系数据库对某些事物有好处,而NoSQL数据库对其他事物也有好处。

正如有人曾经在这里对我说的:

关系数据库的关系部分比其他一些部分进行了优化

这意味着,如果看起来适合您的用例,您也可以使用关系数据库。不要因为MongoDB的灵活性/可扩展性而继续前进。这是有关Wikipedia上MongoDB的第一行:

MongoDB(来自“ humongous”)是一个开源的面向文档的NoSQL数据库系统。

您真的打算使用面向文档的数据库吗?如果用例中有些图形化,那么您很可能会选择Neo4j之类的图形数据库。或者您可以像某些人一样很好地结合使用SQL和NoSQL的优点。

顺便说一句,我也在做一个项目,在其中我同时使用了SQL和NoSQL的最佳部分。

编辑: 我再说一遍:

退房的Neo4j VS Hadoop的一节这个文章。它说:

原则上,Hadoop和其他键值存储主要关注相对平坦的数据结构。也就是说,它们在检索简单对象(例如值,文档甚至对象)时非常快速且可扩展。

提到同一篇文章,您真的需要一个用于MongoDB的平面数据结构吗?这最终取决于您的详细用例,步骤3和步骤4的执行方式。

此外,您可能要参考以下问题:

/programming/2124274/mongodb-what-to-know-before-using

/programming/1476295/when-to-use-mongodb-or-other-document-iented-database-systems

请确保检查出第二个问题的顶部/选定答案。您正处于这个难题可能会解决的问题。

我想这些问题都包含您想知道的所有信息。最后,您只能决定是MongoDb还是其他,我们可以建议。唯一了解您的详细用例的人是您和您的团队。

再次编辑(对于MySQL部分): 据我了解,您打算将某些内容存储在db中,并通过分隔符将它们分开。这带来了两个问题:

  1. 您还需要处理将带有分隔符的所有输入。
  2. 关系数据库的关系存储部分比字符串匹配部分优化得多。我不会采用需要在数据库中进行字符串匹配以获得某些特定结果的方案。我再次强调:

    关系数据库的关系部分比其他一些部分(例如字符串匹配)的优化程度更高

  3. 不要使用多值属性。人们普遍害怕它们。

主要是我打算将MongoDB用于其灵活的架构,但是由于它没有加入,我对此有些怀疑。无论如何,在我的应用程序中,我将为用户提供一个dtabase,然后是一个基本的讲义,其中每个元素都与用户相关联,并包含一个元素集合
Matteo Pagliazzi 2012

您不需要加入mongo,但需要计划架构。如果使用mongo,请以对象而不是表的方式考虑。然后考虑如何访问对象。
ltfishie 2012年

8

我经常看到这个问题。似乎总是将其视为“或”。MongoDB是一个很棒的新工具。有时候,它似乎也可以作为一切的闪亮工具,根据我的经验,这可能是一个糟糕的选择。

我认为最好的组合肯定是两者,我想赞扬您在某些部分(例如用户)使用mylsql的方法,但是在其他部分使用MongoDB,因为我认为认证和授权最好使用mySQL完成,并且大量的示例和模块确实做到了这一点。

对于“大量项目”,这是您要在使用大量磁盘和/或主要读取和/或非结构化数据的情况下使用mongoDB的地方。

我建议不要将您的决定基于Mongo的无模式灵活性。SQL和sql方案源自对结构化数据的需求,并且能够执行只有使用这种结构才可能进行的计算和转换。我从从事数据仓库工作的5年中学到了这一点。我只希望MongoBD可以解决性能问题。如果您正在或期望大量的用户和请求,例如每秒100,000个用户和20个请求,那么我将使用mongoDB,否则,我将尝试使用sql。在很多情况下,我会使用mySQL进行少量处理,然后,由于其容量,收入和基础架构的支持,在切换到mongoDB之前,请切换到Oracle。我同意您在遇到体积问题之前不应该尝试处理它们,但是,如果您对前进的方向有一个清楚的认识,不想半途重写东西,从一开始就选择正确的技术很有意义。请记住,如果您确实有那么大的数量,那么您会在堆栈的各个级别上使用大量的选择和技术。

结构松散的数据有缺点。我在这里用停车场比喻。对于进入的前三辆汽车,没有分界线是很好的选择,但是随着越来越多的汽车进入,许多混乱的事情开始发生,试图停放汽车或轻松计算汽车数量并保持车道畅通成为一场噩梦。组织这项工作需要事先进行工作-划定线路,分隔线和交通流量等,但会有所收获。有时情况当然会发生变化(汽车变大),并且您必须做一些更改-重新绘制线条。加上仅标准的停机时间即可进行年度重新喷漆和维护。

模式设计方面可能是传统mysql用户最大的障碍。我认为有关模式设计MongoDb页面对此有所帮助。我的最后一点是,添加到组合中的每种技术都会增加复杂性。对于任何给定的作品,通常都会有巨大的拥护者会说您“拥有”使用它,但是我发现真正重要的因素是有多少件作品。它暗示了更多的可能的故障点,而且最重要的是,其他任何人都必须知道要解决它所需要的知识库。

fyi Rick Obsorne有一个非常惊人的比较图,它是非常独特的!


那是我在Rails上的第一个真正的项目:这是一种业余爱好,现在我不知道它是成功还是失败。读物不会是主要的,我还将拥有很多新数据并更新其中的数据……
Matteo Pagliazzi 2012年

1
关于mongodb的一件好事是没有固定的架构,因此对于一个爱好项目而言,安装工作更少。模式可以随着时间的推移而发展,您不必采取额外的步骤来更新SQL表。
凯文(Kevin)

不知道我的-1还是为什么0个不好的建议或不同意?
Michael Durrant 2012年

无论如何,如果这是您在Rails中的第一个项目,我会坚持使用mySQL。有很多需要学习的知识,一旦您开始拉开帷幕,则价值超过1个月。
Michael Durrant 2012年

@michael看到我的最新更新
Matteo Pagliazzi 2012年

3

我在这里确实看到了许多关于NoSQL vs MySQL的有效参数。但是,缺少一个有关规模的链接:如果您想真正地规模化并想使用内部数据库来实现,那么您将需要大量有关数据库的知识。那里的恐怖故事太多了,人们未能尝试实现无限扩展的系统。

如果您真的选择采用NoSQL路线(并准备承担随之而来的成本-就像没有联接一样),请考虑使用AWS DynamoDB(http://aws.amazon.com/dynamodb/)。在这里,您可以忽略整个数据库扩展部分,而将精力集中在应用程序上。祝好运。

免责声明:我是AWS DynamoDB团队的开发人员,但我确实相信我们的产品。尝试一下:)


1

因此,您的设计将两种不同类型的对象保存到数据库中:

  • 用户对象(始终具有字段)。
  • Apps对象(可以具有不同的字段)。一个应用只能属于一个用户。

我能否将一个收藏集作为一个不同的对象来制作,就像一个将不同应用程序分组的标签一样。为了争辩,我们假设没有集合,而用户只有一个应用程序列表。

虽然我认为可以在MySQL上实现,但在MongoDB中,您在应用程序对象的结构方面将具有更大的灵活性,并且可能会将您的表示形式更自然地映射到数据库中,从而使代码更简单。

在MySQL中,您会遇到针对不同应用程序使用不同格式的问题,但这是可能的。一些想法:

  • 您可以创建一个中间表,其中包含所有对象(id,user_id,title等)之间的所有公共信息,然后是类型,因此您可以在仅具有该格式的非公共字段的另一张表上搜索该中间表文件的文件名和文件大小)。您需要为每种不同的格式创建一个不同的表。如果两个表都由app_id(主键)建立索引,则速度将足够快,因为通过索引值访问表将很快。
  • 您可以以某种格式对数据进行编码并标准化存储。例如,将JSON中的非常见数据编码为字符串并将其存储在VARCHAR字段中。请注意该字段的大小,以免空间不足。格式可以是复杂的(JSON)或简单的(只是值之间用逗号分隔)
  • 您可以创建不同的“通用”字段,例如int1,int2,str1,str2,并为应用程序类型定义str1为“ file_name”,而为其他类型定义为“ location”。

在MongoDB上,它可能就像只使用两个MongoDB集合一样简单,一个用于用户,另一个用于应用程序。假设存在某种限制(不是您所描述的那样,而是为了说),您甚至可以将应用程序存储在用户对象列表中。存储和检索数据更为自然,因为您可以存储任何类型的对象,而不论字段是哪个。您可以按user_id搜索以获取属于用户的所有应用。在MongoDB上,无论如何,您都失去了进行联接查询的可能性,但是在这种情况下,我认为基本查询将是检索用户并检索与用户相关的应用程序。如果您打算做很多事情,例如“给我两个以上的集合,每个集合具有三个或更少的应用程序的用户”,则必须生成它而不是将其作为联接查询,但作为代码中的过程,它会比关系数据库中的过程自然,并且可能会花费更多时间。如果您想搜索参数(例如,给我所有属于特定用户的应用程序;给我所有类型为X的应用程序),那么在MongoDB上这很容易,不需要使用联接。

我不确定MongoDB on Rails的支持。我已经在Python和JavaScript中使用了它。

编辑:添加了关于访问两个表和另一个MySQL选项时的时间的注释


我不喜欢使用MySQL存储可选设置的第二个选项,因为我认为它可能会为每一行加载很多不必要的字节...对于第二个:它将使我的应用程序加载两行的速度大大降低从两个不同的表加载一项?
Matteo Pagliazzi 2012年

请查看我的最新更新
Matteo Pagliazzi 2012年

关于速度的问题,它应该不会慢很多(您可以通过索引的唯一值来访问它)。我还编辑了答案,因为上次编辑的提案类似于第一个提案,并添加了另一个选项。
Khelben 2012年

1

我想说的是,使用您最了解的技术,尤其是当它是一个真实的项目并且想要快速推出时。使用MySQL和Mongo都会带来自己的好处和头痛。两者都曾合作过,如果您遵循良好的设计原则,我还补充道从MySQL迁移到Mongo并不是很难。

话虽如此,在您的情况下使用MongoDB的一个很好的理由是您的数据。如前所述,您的收藏集将有几种不同的输入类型:地图,视频等。如果要使用RDBMS来实现此目的,则有3种方法:

  • 每个类型的表:每个表包含特定于每种对象类型的列

    缺点:N查询来搜索所有数据类型。

    优点:良好的OO设计,易于维护

  • 单个表:一个巨大的表,其中包含所有类型的所有可能属性,其中大多数对于任何特定条目为null

    缺点:更改任何对象都需要更改表,一旦表变大则很麻烦。难以维护。

    优点:易于实施。

  • 带有元数据的核心表:您有一个具有核心属性(例如标题,日期)的表,以及一个具有键值对的其他属性的元数据表

    缺点:两次查询以获取单个对象的所有数据。

    优点:非常灵活,实施起来不是很困难。

我以前曾经使用过每种方法,并且可以说没有一种方法与Mongo一样自然。您的数据可能看起来像这样:

{_id:"collection1",
 name:"My first Collection",
 owner: "user123243342",
 entries: [
    {type:"video",
     url: "http://www.youtube.com/234324",
     tags: ["roadtrip", "fun", "camera"]
     },
    {type:"map",
     coordinates: [LOC: [38, –102], LOC: [43, –33], LOC: [228, –102]],
     description: "Road trip to nowhere",
 ]
}

但是,您实际上不必担心架构设计,因为可以直接将您的域对象持久化。本质上,MongoDB是您可以查询的对象存储。

注意,我没有对MySql和Mongodb之间的性能比较进行任何讨论。尽管您应该始终牢记性能,但是除非您知道数据访问模式,否则您将无法有效地做出决策。任何好的项目都可能随着它的发展和新挑战的出现而经历几次重构。不必过早担心性能,而选择最了解的工具并开始编码。

编辑

要回答有关使用MySQL并使用“ |”将属性保留在同一字段中的特定问题。不要这样 这种方法给您带来的问题多于解决的问题。首先,您将无法使用MySql查询单个属性。其次,它给您的数据访问层增加了太多的复杂性。而是使用每表类型或元数据方法。如果您以前使用过WordPress,那么它将使用元数据方法:

  • 用户表+用户的usemeta
  • 帖子表+ postmeta表帖子

这使得数据结构极其灵活,并且仍然可以以合理的速度进行查询。


我不喜欢元数据选项...但是我在考虑不使用字段而使字段为null的单个表
Matteo Pagliazzi 2012年

单表方法可能是最糟糕的一种。虽然您可以在单个查询中完成所有操作,但是对任何单个数据类型的任何更改都将需要alter table。一旦表变大,这在mysql中很痛苦。
ltfishie 2012年

0

考虑到数据库中的数据量和检索到的数据量,下面的文章在选择,获取和插入方面对MySQL和MongoDB进行比较提供了良好的结果。结果显示MongoDB在“插入”方面表现出色,但在其他情况下MySQL胜出。见下文:

http://www.moredevs.ro/mysql-vs-mongodb-performance-benchmark/

我有使用MongoDB的经验,我认为这是一个很好的解决方案。我每天用它插入成千上万个收藏集。结合Solr解决方案(缓存解决方案,每天更新一次),我可以在需要时按集合ID检索MongoDB数据,因此不需要即时选择。因此,考虑到您必须处理大量插入操作,而无需关心选择和获取操作,MongoDB可能是一个好主意,它取决于每种情况并进行良好的分析。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.