【问题标题】:MySQL --> MongoDB: Keep IDs or create mapping?MySQL --> MongoDB:保留 ID 还是创建映射?
【发布时间】:2014-08-19 13:16:36
【问题描述】:

我们要将数据库从 MySQL 迁移到 MongoDB。 一些指向我们 Web 应用程序的 URL 使用数据库 ID(例如 http://example.com/post/5) 目前我看到了两种可能性:

1) 保留现有的 MySQL ID 并将它们用作 MongoDB ID。新文档的 ID 将获得新的 MongoDB ObjectID。

2) 为所有文档生成新的 MongoDB ObjectID,并使用 MySQLId --> MongoDBId 为所有带有旧 ID 的外部链接创建映射。

2 会稍微弄乱我的 PHP 应用程序,但我可以想象 #1 会导致索引或分片问题? 避免问题的最佳做法是什么?

【问题讨论】:

    标签: mysql mongodb migration identifier


    【解决方案1】:

    1) 保留现有的 MySQL ID 并将它们用作 MongoDB ID。新的ID 文档将获得新的 MongoDB ObjectID。

    ObjectId 在您不希望/拥有文档的自然主键时非常有用,但是将 ObjecID 和数字 ID 混合作为主键只会在以后的查询中引起问题。我会建议一条不同的路线。保留现有的 MySQL ID 并将其用作 MongoDB ID;创建带有数字 ID 的新文档,就像对 MySQL 所做的那样。这样您就不必在一个字段中混合数据类型。

    2) 为所有文档生成新的 MongoDB ObjectID 并创建一个 使用 MySQLId 映射 --> MongoDBId 用于所有具有旧 ID 的外部链接 在里面。

    这也可以,但正如您所说,您需要映射您的新 ID 和旧 ID。如果您保持 ID 不变,这可能是一些额外的工作,您可以避免这些工作。

    我可以想象 #1 会导致索引或分片出现问题?

    ObjectID 和 MySQL AUTO_INCREMENT ID 都是单调递增的,因此如果将它们用作分片键(在这种情况下您可能会使用散列分片键;您可以阅读更多详细信息 here)。

    编辑

    混合使用 ObjectID 和数字 ID 时会出现哪些问题?

    如果您正在进行简单的相等检查(即使用{_id: 5}{_id: ObjectId("53aeb2dcb9f8955d1a927b97") 获取文档),您将没有问题。但是,范围查询会更复杂:

    举个例子:

    db.coll.find({_id : { $gt : 5}}) 
    

    此查询将只返回具有 num 的文档。 ID。

    这个查询:

    db.coll.find({_id : { $gt : ObjectId("53aeb2dcb9f8955d1a927b97")}}); 
    

    将仅返回具有 ObjectIds 的文档。

    显然,您可以使用 $or 查找其中任何一个,但我的观点是您的查询不会像使用非混合 ID 那样简单。

    【讨论】:

    • 我不知道我是否真的喜欢在我的文档中使用数字 ID...就分片而言,我真的很喜欢 ObjectID 的结构。因此我倾向于使用映射策略。混合使用 ObjectID 和数字 ID 时会出现哪些问题?
    • 好点。混合 ID 似乎是个坏主意。我试过了,只是想看看它是否可以工作:框架也可能会遇到问题。 (例如,将 Symfony 与 Doctrine ODM 一起使用,您必须在使用 find() 之前将传递的 ID 转换为 ObjectID,因为自动转换器将不再工作)因此创建映射类可能是对我来说最好的解决方案。非常感谢@christian-p!
    猜你喜欢
    • 2011-08-20
    • 2011-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多