MySQL 到 MongoDB 数据迁移。

5
我们知道MongoDB有两种建模关系/实体之间的方式,即嵌入式(embedding)引用(referencing) (这里查看区别)。假设我们有一个名为USER的数据库,在MySQL中有两个表名分别为useraddress。一个嵌入式的MongoDB文档可能如下所示:
{
  "_id": 1,
  "name": "Ashley Peacock",
  "addresses": [
    {
      "address_line_1": "10 Downing Street",
      "address_line_2": "Westminster",
      "city": "London",
      "postal_code": "SW1A 2AA"
    },
    {
      "address_line_1": "221B Baker Street",
      "address_line_2": "Marylebone",
      "city": "London",
      "postal_code": "NW1 6XE"
    }
  ]
}

在引用关系中,2个SQL表将会在MongoDB中生成2个集合,可以使用此方法pymongo进行迁移。

如何使用Python直接将MySQL数据作为嵌入式文档进行迁移?

有关伪代码和算法性能的见解将非常有用。我想到的是通过在MySQL中执行joins创建views。但在这种情况下,我们将无法在父文档中获得子文档的结构。


大体上来说,您可以从Python查询MySQL表,然后迭代结果集并生成您在上面看到的JSON输出。 - Tim Biegeleisen
1
@TimBiegeleisen,您能否附上伪代码来完成相同的操作?还有一份大型文档需要我们牢记。 - def __init__
请查看Mongo的这篇文章:https://www.mongodb.com/basics/mysql-to-mongodb - deadshot
如果您将嵌入式文档放入Mongo中,则可能需要在代码中处理文档的更新,对吗? - Hi computer
为什么要使用Mongo?我知道它不太友好于关系型数据库,因为还有很多其他的数据库可供选择,但这取决于业务需求。 - Hi computer
1个回答

4

反规范化

首先,关于“嵌入式”与“引用式”数据的问题,在正式的术语上称为反规范化(Denormalization)。Mongo提供了一个指南,描述何时应该进行反规范化。知道什么时候以及如何进行反规范化是从SQL到NoSQL转换时非常普遍的难点,如果做错了,可能会抵消你所期望的任何性能优势。因为你似乎已经决定使用嵌入式方法,所以我会假设你已经想好了这个问题。

从MySQL到Mongo

Mongo有一份很棒的Python教程,你可以参考一下。首先,加入你的useraddress表。它看起来会像这样:

| _id    | name           | address_line_1        | address_line_2 | ... 
| 1      | Ashley Peacock | 10 Downing Street ... | ...
| 1      | Ashley Peacock | 221B Baker Street ... | ...
| 2      | Bob Jensen     | 343 Main Street ...   | ...
| 2      | Bob Jensen     | 1223 Some Ave ...     | ...
...

然后遍历行以创建文档,并将它们传递给 pymongoinsert_one函数。使用insert_oneupsert=True,如果在数据库中找不到匹配的文档,则会插入一个新文档,如果找到匹配的文档,则会更新已有文档。使用$pushaddress数据附加到文档中的数组字段addresses。使用这种设置,insert_one将根据匹配的_id字段自动处理重复项并追加地址。请参阅文档了解更多详细信息:

from pymongo import MongoClient

client = MongoClient(port=27017)
db = client.my_db

sql_data = []  # should have your SQL table data
# depending on how you got this into python, you will index with a  
# field name or a number, e.g. row["id"] or row[0] 

for row in sql_data:
    address = {
        "address_line_1": row["address_line_1"],
        "address_line_2": row["address_line_2"],
        "city": row["city"],
        "postal_code": row["postal_code"],
    }
    db.users.update_one(
        {"_id": row["_id"]},
        {"name": row["name"], "$push": {"addresses": address}},
        upsert=True,
    )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接