【问题标题】:MongoDB Database Structure and Best Practices HelpMongoDB 数据库结构和最佳实践帮助
【发布时间】:2011-09-13 04:10:29
【问题描述】:

我正在为我的垃圾收集公司开发路线跟踪/优化软件,希望对我当前的数据结构/情况提供一些反馈。

这是我的 MongoDB 结构的简化版本:

数据库:数据

收藏:

“客户” - 包含所有客户数据的数据集合。

  [
    {
        "cust_id": "1001",
        "name": "Customer 1",
        "address": "123 Fake St",
        "city": "Boston"
    },
    {
        "cust_id": "1002",
        "name": "Customer 2",
        "address": "123 Real St",
        "city": "Boston"
        },
    {
        "cust_id": "1003",
        "name": "Customer 3",
        "address": "12 Elm St",
        "city": "Boston"
    },
    {
        "cust_id": "1004",
        "name": "Customer 4",
        "address": "16 Union St",
        "city": "Boston"
        },
    {
        "cust_id": "1005",
        "name": "Customer 5",
        "address": "13 Massachusetts Ave",
        "city": "Boston"
    }, { ... }, { ... }, ...
]

“卡车” - 包含所有卡车数据的数据集合。

[
    {
        "truckid": "21",
        "type": "Refuse",
        "year": "2011",
        "make": "Mack",
        "model": "TerraPro Cabover",
        "body": "Mcneilus Rear Loader XC",
        "capacity": "25 cubic yards"
    },
    {
        "truckid": "22",
        "type": "Refuse",
        "year": "2009",
        "make": "Mack",
        "model": "TerraPro Cabover",
        "body": "Mcneilus Rear Loader XC",
        "capacity": "25 cubic yards"
    },
    {
        "truckid": "12",
        "type": "Dump",
        "year": "2006",
        "make": "Chevrolet",
        "model": "C3500 HD",
        "body": "Rugby Hydraulic Dump",
        "capacity": "15 cubic yards"
    }
]

“驱动程序” - 包含所有驱动程序数据的数据集合。

  [
    {
        "driverid": "1234",
        "name": "John Doe"
    },
    {
        "driverid": "4321",
        "name": "Jack Smith"
    },
    {
        "driverid": "3421",
        "name": "Don Johnson"
    }
]

“路由列表” - 包含所有预定路由列表的数据集合。

   [
    {
        "route_name": "monday_1",
        "day": "monday",
        "truck": "21",
        "stops": [
            {
                "cust_id": "1001"
            },
            {
                "cust_id": "1010"
            },
            {
                "cust_id": "1002"
            }
        ]
    },
    {
        "route_name": "friday_1",
        "day": "friday",
        "truck": "12",
        "stops": [
            {
                "cust_id": "1003"
            },
            {
                "cust_id": "1004"
            },
            {
                "cust_id": "1012"
            }
        ]
    }
]

“路线” - 包含所有活动和已完成路线的数据的数据集合。

[
    {
        "routeid": "1",
        "route_name": "monday1",
        "start_time": "04:31 AM",
        "status": "active",
        "stops": [
            {
                "customerid": "1001",
                "status": "complete",
                "start_time": "04:45 AM",
                "finish_time": "04:48 AM",
                "elapsed_time": "3"
            },
            {
                "customerid": "1010",
                "status": "complete",
                "start_time": "04:50 AM",
                "finish_time": "04:52 AM",
                "elapsed_time": "2"
            },
            {
                "customerid": "1002",
                "status": "incomplete",
                "start_time": "",
                "finish_time": "",
                "elapsed_time": ""
            },
            {
                "customerid": "1005",
                "status": "incomplete",
                "start_time": "",
                "finish_time": "",
                "elapsed_time": ""
            }
        ]
    }
]

到目前为止的过程如下:

司机每天都从开始一条新路线开始。在开始新路线之前,司机必须先输入数据:

  1. 驱动程序ID
  2. 日期
  3. 卡车

正确输入所有数据后,开始新路线:

  1. 在集合中创建新对象“路由”
  2. “day” + “truck” 的查询集合 “route-lists” 匹配并返回 “stops”强>
  3. “route-lists”数据插入“routes”集合

随着司机进行他的日常停靠/任务,“路线”集合将相应更新。

完成所有任务后,驾驶员只需将“路线”集合中的“状态”字段从“完成”更改为“活动”即可完成路线流程。

总结一下。非常感谢任何反馈、意见、cmets、链接、优化策略。

提前感谢您的宝贵时间。

【问题讨论】:

    标签: mongodb database-design database


    【解决方案1】:

    您的数据库架构在我看来就像“经典”关系数据库架构。 Mongodb 非常适合数据非规范化。我猜当您显示路线时,您会加载所有相关的客户、司机、卡车。

    如果您想让您的系统真正快速,您可以将所有内容嵌入到路由集合中。

    所以我建议对您的架构进行以下修改:

    1. 客户 - 原样
    2. 卡车 - 原样
    3. 驱动程序 - 原样
    4. 路由列表:

      在停靠点内嵌入有关客户的数据,而不是参考。还嵌入卡车。在这种情况下,架构将是:

       {
           "route_name": "monday_1",
           "day": "monday",
           "truck": {
               _id = 1,
               // here will be all truck data
           },
           "stops": [{
               "customer": {
                   _id = 1,
                   //here will be all customer data
               }
           }, {
               "customer": {
                   _id = 2,
                   //here will be all customer data
               }
           }]
       }
      
    5. 路线:

      当司机开始新的路线时,从路线列表复制路线并嵌入司机信息:

       {
           //copy all route-list data (just make new id for the current route and leave reference to routes-list. In this case you will able to sync route with route-list.)
           "_id": "1",
           route_list_id: 1,
           "start_time": "04:31 AM",
           "status": "active",
           driver: {
               //embedd all driver data here
           },
           "stops": [{
               "customer": {
                   //all customer data
               },
               "status": "complete",
               "start_time": "04:45 AM",
               "finish_time": "04:48 AM",
               "elapsed_time": "3"
           }]
       }
      

    我猜你会问自己,如果主集合中的驱动程序、客户或其他非规范化数据发生了变化,该怎么办。是的,您需要更新其他集合中的所有非规范化数据。您可能需要更新数十亿个文档(取决于您的系统大小),这没关系。如果需要很长时间,您可以异步执行。

    上述数据结构有什么好处?

    1. 每个文档都包含您可能需要在应用程序中显示的所有数据。因此,例如,当您需要显示路线时,您无需加载相关的客户、司机、卡车。
    2. 您可以对数据库进行任何困难的查询。例如,在您的架构中,您可以构建查询,该查询将返回包含名称 =“Bill”的客户停靠站的所有路线(您需要先按名称加载客户,获取 ID,然后在当前架构中按客户 ID 查找)。

    您可能会问自己,在某些情况下您的数据可能会不同步,但要解决这个问题,您只需构建一些单元测试以确保您正确更新去规范化的数据。

    希望以上内容能帮助您从文档数据库的角度,从非关系的角度看世界。

    【讨论】:

    • 如果客户或卡车或司机信息更新到系统中会怎样。它会造成数据的歧义。最好只保留其他型号的 ID。
    • @Love-Kesh 如果这是您的目标,那么您应该使用关系数据库。 MongoDB 显然不是一个关系型数据库,因此尝试在其上强制执行关系模式并没有什么意义,不是吗?
    猜你喜欢
    • 1970-01-01
    • 2023-04-08
    • 2010-12-14
    • 1970-01-01
    • 2016-09-21
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多