MongoDB 从 MYSQL 迁移到 MongoDB 时的性能
MongoDB performance while migration from MYSQL to MongoDB
我在 MySQL 中有一个包含 10 table 的数据库。
这些 table 之间存在复杂的映射。现在我想将同一个数据库迁移到 MongoDB 。
我在 MongoDB 中创建了一个示例数据库。数据库中的映射使文档变得复杂。
假设 table 中有 100,00 行,它在 MySQL 中映射了 3 或 4 个 table,在这种情况下 MongoDB单个文档的数据量会很大。
我对此几乎没有疑问 -
- 由于MongoDB 不支持 Join 概念,所以集合中会有重复数据。我想知道单个集合的最大可能大小?
- 如果文档尺寸变大,更新的时候对性能有影响吗?
- 因为 MongoDB 支持基于集合的事务,即如果事务发生在单个集合上,则可以回滚。
它有基于 document/collections 的锁定机制吗?多个线程可以同时更新单个文档吗?
我根据我在 mongoDB 的 3 年经验来回答这个问题。
集合的最大可能大小
在MongoDB中maximum possible size that you can have on a database is 32TB. If you think your collection is going to exceed that limit then you should consider about sharding.
正在更新文档
MongoDB 即使您有数百万个文档,只要您设置了适当的索引,也能很好地执行更新。关于更新,您需要考虑的另一件事是,如果您的更新将彻底改变文档的大小,那么 mongoDB 需要将此文档移动到另一个内存位置。如果您同时进行此类更新,这会降低性能。但是如果您的应用程序有很多这样的更新操作,那么您需要为您的集合设置适当的填充因子。这可以按照 here 所述的方式完成。请注意,填充因子仅在您使用 MMAPv1 存储引擎时适用。
锁定
您必须注意 mongoDB 不支持事务,它在文档级别而非集合级别提供 ACID 属性。根据最新版本 MongoDB (v3.0.x),它提供文档级锁定。 MongoDB 数据库中描述了整页的项目,解释了 mongodb 中的锁定。 Linkhere。多个线程只有在获得写锁后才能更新同一个文档。一次只有一个线程可以持有写锁。因此,线程执行的更新 - 最后收到锁 - 将存储在集合中。
希望这能消除你的疑虑。
基本思想是对数据进行反规范化。如果您的模式基于不同的关系结构,您可以在您的文档中使用引用指向其他集合中的相关文档,然后您的应用程序可以解析这些文档。例如,PHP 驱动程序为此类引用提供 API,"but they do not load it or automatically follow the link/reference"。
MongoDB 3.2在聚合框架中引入了$lookup
运算符,可以直接引用同一数据库中的另一个集合。
单个(无上限)集合的大小没有明确限制(在 64 位系统上);主要限制是单个文档的最大大小为 16MB,最大嵌套级别为 100。隐式大小限制是数据库大小、命名空间和索引大小以及数据库中的最大集合数,所有这些都取决于所使用的存储引擎和底层 OS。另请参阅 SO 上的相关问题 here。
对于基于集合的事务,MongoDB docs 建议提供两阶段提交模式 "transaction-like semantics",使用更新文档中的事务集合和事务状态键。
我在 MySQL 中有一个包含 10 table 的数据库。 这些 table 之间存在复杂的映射。现在我想将同一个数据库迁移到 MongoDB 。 我在 MongoDB 中创建了一个示例数据库。数据库中的映射使文档变得复杂。
假设 table 中有 100,00 行,它在 MySQL 中映射了 3 或 4 个 table,在这种情况下 MongoDB单个文档的数据量会很大。 我对此几乎没有疑问 -
- 由于MongoDB 不支持 Join 概念,所以集合中会有重复数据。我想知道单个集合的最大可能大小?
- 如果文档尺寸变大,更新的时候对性能有影响吗?
- 因为 MongoDB 支持基于集合的事务,即如果事务发生在单个集合上,则可以回滚。 它有基于 document/collections 的锁定机制吗?多个线程可以同时更新单个文档吗?
我根据我在 mongoDB 的 3 年经验来回答这个问题。
集合的最大可能大小
在MongoDB中maximum possible size that you can have on a database is 32TB. If you think your collection is going to exceed that limit then you should consider about sharding.
正在更新文档
MongoDB 即使您有数百万个文档,只要您设置了适当的索引,也能很好地执行更新。关于更新,您需要考虑的另一件事是,如果您的更新将彻底改变文档的大小,那么 mongoDB 需要将此文档移动到另一个内存位置。如果您同时进行此类更新,这会降低性能。但是如果您的应用程序有很多这样的更新操作,那么您需要为您的集合设置适当的填充因子。这可以按照 here 所述的方式完成。请注意,填充因子仅在您使用 MMAPv1 存储引擎时适用。
锁定
您必须注意 mongoDB 不支持事务,它在文档级别而非集合级别提供 ACID 属性。根据最新版本 MongoDB (v3.0.x),它提供文档级锁定。 MongoDB 数据库中描述了整页的项目,解释了 mongodb 中的锁定。 Linkhere。多个线程只有在获得写锁后才能更新同一个文档。一次只有一个线程可以持有写锁。因此,线程执行的更新 - 最后收到锁 - 将存储在集合中。
希望这能消除你的疑虑。
基本思想是对数据进行反规范化。如果您的模式基于不同的关系结构,您可以在您的文档中使用引用指向其他集合中的相关文档,然后您的应用程序可以解析这些文档。例如,PHP 驱动程序为此类引用提供 API,"but they do not load it or automatically follow the link/reference"。
MongoDB 3.2在聚合框架中引入了$lookup
运算符,可以直接引用同一数据库中的另一个集合。
单个(无上限)集合的大小没有明确限制(在 64 位系统上);主要限制是单个文档的最大大小为 16MB,最大嵌套级别为 100。隐式大小限制是数据库大小、命名空间和索引大小以及数据库中的最大集合数,所有这些都取决于所使用的存储引擎和底层 OS。另请参阅 SO 上的相关问题 here。
对于基于集合的事务,MongoDB docs 建议提供两阶段提交模式 "transaction-like semantics",使用更新文档中的事务集合和事务状态键。