2011-06-11 74 views
10

我正在为我的垃圾收集公司开发Route Tracking/Optimization软件,并希望对我当前的数据结构/情况提供一些反馈。MongoDB数据库结构和最佳实践帮助

这里是我的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. driverid
  2. 日期
  3. 卡车

一旦所有数据被正确输入开始一个新航线将开始:

  1. 在集合中创建新的对象“路线”
  2. 查询收集“路由列表”为“天” + “卡车”匹配,并返回“停止”
  3. 插入“路由表”数据为‘路线’收集

由于司机继续他的每日停止/任务“路线”收集将相应更新。

完成所有任务后,驾驶员将有能力通过在“路线”集合中将“状态”字段从“完成”更改为“活动”来完成路线过程。

总结一下。任何反馈,意见,评论,链接,优化策略都将不胜感激。

提前感谢您的时间。

回答

11

您的数据库模式对我来说就像'经典'关系数据库模式。 Mongodb非常适合数据非归一化。我想当你显示路线你加载所有相关的客户,司机,卡车。

如果你想让你的系统真的很快,你可以嵌入路由集合中的所有东西。

所以我建议你的方案的以下修改:

  1. 客户 - 为 - 是
  2. 卡车 - AS-是
  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)。

也许你会问自己,你的数据可以在某些情况下不同步,但要解决这个问题,你只需要多建几个单元测试,以确保正确更新denormolized数据。

希望以上将帮助您从文档数据库的角度从非关系方面看世界。

+0

如果客户或卡车或驾驶员信息更新到system.It会造成数据模糊不清。更好地保留其他模型的id。 – 2016-08-31 08:54:21