用于分析或趋势仪表板的MongoDB架构设计

时间:2012-07-05 15:08:59

标签: mongodb

目前正致力于POC从RDBMS迁移并评估MongoDB,在执行架构的过程中,并希望确保它满足我们的需求。

一些背景知识 - 我们每天处理+ -100,000个文件 - 大约10种不同的文件类型(可以进入不同的集合) - 每天+ 1亿条记录 - 文件是管道分隔文本 - 将使用python加载数据 - 每个文件包含100-250个字段

当前设置 - 每个文件类型都被加载到它自己的表中(按天划分) 即 文件类型A将在FileA中(分区20120701) 文件类型B将在FileB中(分区20120701) 等。

  • 我们每5到10分钟(每小时趋势)总结一次数据
  • 我们每天都会编制一份工作来总结数据(每日趋势)
  • 未对数据进行连接等

我已经包含了源数据的修剪文件(删除的字段和记录),以及4种不同的结构数据选项。我目前的设计是:

  1. 每种文件类型每天收集(详细记录) 即 FileA_20120701 FileB_20120701

  2. 每小时汇总数据的每月收集,将包括所有文件类型记录 即Hourly_usage_201207

  3. 每日汇总数据每年收集一次,包括所有文件类型记录,即Daily_usage_2012

  4. 所以: 每小时地图缩小>每日地图减少

    现在我专注于如何存储详细记录,请查看文件中提供的原始数据:

    SERIAL  TIMESTAMP   CUSTOMER_ID RESERVED01  PRODUCT_ID  CUSTOMER_TYPE   CUSTOMER_STATE  ChargeAmount_OF_UNITS   ChargeAmount_OF_FUND    ChargeAmount_FROM_ACCOUNT1  ACCOUNT1_BALANCE    ChargeAmount_FROM_ACCOUNT2  ACCOUNT2_BALANCE    WalletType1 UnitType1   ChargeAmount1   WalletBalance1  WalletType2 UnitType2   ChargeAmount2   WalletBalance2  WalletType3 UnitType3   ChargeAmount3   WalletBalance3  Bonus1  Bonus2  Bonus3  AddtionaInfo 
    379120186   20120701235122  1345567 0   555 0   1000000 0   0   5   664 0   0   200 1   5   664 0   0   0   0   0   0   0   0               1234
    379120190   20120701235124  1345568 0   1   0   1000000 0   0   4   108 0   0   200 1   4   108 0   0   0   0   0   0   0   0               
    379120197   20120701235132  1345569 0   4   0   1000000 0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0               
    379120203   20120701235136  1345570 0   1   0   1000000 0   0   0   346 0   0   0   0   0   0   0   0   0   0   0   0   0   0               XXX
    379120207   20120701235138  1345571 0   10  0   1000000 0   0   0   0   3   100 200 1   3   100 500 2   10  0   610 2   20  80  10          
    379120208   20120701235138  1345571 0   1   0   1000000 0   0   3   306 0   0   200 1   3   306 0   0   0   0   0   0   0   0               
    379120211   20120701235141  1345573 0   1   0   1000000 0   0   0   181 0   0   0   0   0   0   0   0   0   0   0   0   0   0               
    379120213   20120701235143  3101015742206   0   349 1   1000001 0   0   0   274 0   0   0   0   0   0   0   0   0   0   0   0   0   0               
    379120214   20120701235144  3101015742206   0   349 1   1000001 0   0   0   0   120 680 210 1   37  0   200 18  120 680 0   0   0   0               
    379120215   20120701235147  3101015742206   0   349 1   1000001 0   0   0   992 0   0   0   0   0   0   0   0   0   0   0   0   0   0               
    379120217   20120701235147  3101015742206   0   349 1   1000001 0   2   0   1   0   0   400 3   2   1766    0   0   0   0   0   0   0   0               
    379120223   20120701235149  3101015742206   0   349 1   1000001 0   0   11  196 0   0   200 1   11  196 0   0   0   0   0   0   0   0               
    379120229   20120701235153  1345579 0   349 3   1000000 0   0   40  707 0   0   200 1   40  707 0   0   0   0   0   0   0   0   20  5       XXX
    379120230   20120701235153  3101015742206   0   349 1   1000001 0   0   9   1702    0   0   200 1   9   1702    0   0   0   0   0   0   0   0               
    379120232   20120701235153  1345581 0   349 2   1000000 0   0   150 59  0   0   200 1   150 59  0   0   0   0   0   0   0   0               
    379120237   20120701235158  1345582 0   1   2   1000000 0   0   3   303 0   0   200 1   3   303 0   0   0   0   0   0   0   0               
    379120241   20120701235202  538552582   0   14  0   1000000 0   0   0   779 10  777 210 1   150 200 0   0   0   0   0   0   0   0               YYY
    379120245   20120701235206  538552582   0   14  0   1000000 0   0   3   300 0   0   200 1   3   300 0   0   0   0   0   0   0   0               
    379120248   20120701235206  538552582   0   14  0   1000000 0   0   155 202 0   0   200 1   155 202 0   0   0   0   0   0   0   0               
    379120250   20120701235208  538552582   0   14  0   1000000 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0               
    

    data1.json结构:只是从CSV加载数据而不进行任何转换,删除空值等。这不是理想的,但处理时间最短

    [
        {
            'SERIAL': 379120186,
            'TIMESTAMP': 20120701235122,
            'CUSTOMER_ID': 1345567,
            'RESERVED01': 0,
            'PRODUCT_ID': 555,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 5,
            'ACCOUNT1_BALANCE': 664,
            'ChargeAmount_FROM_ACCOUNT2': 0,
            'ACCOUNT2_BALANCE': 0,
            'WalletType1': 200,
            'UnitType1': 1,
            'ChargeAmount1': 5,
            'WalletBalance1': 664,
            'WalletType2': 0,
            'UnitType2': 0,
            'ChargeAmount2': 0,
            'WalletBalance2': 0,
            'WalletType3': 0,
            'UnitType3': 0,
            'ChargeAmount3': 0,
            'WalletBalance3': 0,
            'Bonus1': '',
            'Bonus2': '',
            'Bonus3': '',
            'AddtionaInfo': '1234'
        },
        {
            'SERIAL': 379120203,
            'TIMESTAMP': 20120701235136,
            'CUSTOMER_ID': 1345570,
            'RESERVED01': 0,
            'PRODUCT_ID': 1,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 0,
            'ACCOUNT1_BALANCE': 346,
            'ChargeAmount_FROM_ACCOUNT2': 0,
            'ACCOUNT2_BALANCE': 0,
            'WalletType1': 0,
            'UnitType1': 0,
            'ChargeAmount1': 0,
            'WalletBalance1': 0,
            'WalletType2': 0,
            'UnitType2': 0,
            'ChargeAmount2': 0,
            'WalletBalance2': 0,
            'WalletType3': 0,
            'UnitType3': 0,
            'ChargeAmount3': 0,
            'WalletBalance3': 0,
            'Bonus1': '',
            'Bonus2': '',
            'Bonus3': '',
            'AddtionaInfo': XXX
        },
        {
            'SERIAL': 379120207,
            'TIMESTAMP': 20120701235138,
            'CUSTOMER_ID': 1345571,
            'RESERVED01': 0,
            'PRODUCT_ID': 10,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 0,
            'ACCOUNT1_BALANCE': 0,
            'ChargeAmount_FROM_ACCOUNT2': 3,
            'ACCOUNT2_BALANCE': 100,
            'WalletType1': 200,
            'UnitType1': 1,
            'ChargeAmount1': 3,
            'WalletBalance1': 100,
            'WalletType2': 500,
            'UnitType2': 2,
            'ChargeAmount2': 10,
            'WalletBalance2': 0,
            'WalletType3': 610,
            'UnitType3': 2,
            'ChargeAmount3': 20,
            'WalletBalance3': 80,
            'Bonus1': 10,
            'Bonus2': '',
            'Bonus3': '',
            'AddtionaInfo': ''
        }
    ]
    

    data2.json结构:删除空值。来自未充电的充电字段(WalletType1-3)的值(钱包ID = 0)被移除。只保留受影响的钱包。

        [
            {
                'SERIAL': 379120186,
                'TIMESTAMP': 20120701235122,
                'CUSTOMER_ID': 1345567,
                'PRODUCT_ID': 555,
                'CUSTOMER_TYPE': 0,
                'CUSTOMER_STATE': 1000000,
                'ChargeAmount_OF_UNITS': 0,
                'ChargeAmount_OF_FUND': 0,
                'ChargeAmount_FROM_ACCOUNT1': 5,
                'ACCOUNT1_BALANCE': 664,
                'ChargeAmount_FROM_ACCOUNT2': 0,
                'ACCOUNT2_BALANCE': 0,
                'WalletType1': 200,
                'UnitType1': 1,
                'ChargeAmount1': 5,
                'WalletBalance1': 664,
                'AddtionaInfo': 1234
            },
            {
                'SERIAL': 379120203,
                'TIMESTAMP': 20120701235136,
                'CUSTOMER_ID': 1345570,
                'RESERVED01': 0,
                'PRODUCT_ID': 1,
                'CUSTOMER_TYPE': 0,
                'CUSTOMER_STATE': 1000000,
                'ChargeAmount_OF_UNITS': 0,
                'ChargeAmount_OF_FUND': 0,
                'ChargeAmount_FROM_ACCOUNT1': 0,
                'ACCOUNT1_BALANCE': 346,
                'ChargeAmount_FROM_ACCOUNT2': 0,
                'ACCOUNT2_BALANCE': 0,
                'AddtionaInfo': 'XXX'
            },
            {
                'SERIAL': 379120207,
                'TIMESTAMP': 20120701235138,
                'CUSTOMER_ID': 1345571,
                'RESERVED01': 0,
                'PRODUCT_ID': 10,
                'CUSTOMER_TYPE': 0,
                'CUSTOMER_STATE': 1000000,
                'ChargeAmount_OF_UNITS': 0,
                'ChargeAmount_OF_FUND': 0,
                'ChargeAmount_FROM_ACCOUNT1': 0,
                'ACCOUNT1_BALANCE': 0,
                'ChargeAmount_FROM_ACCOUNT2': 3,
                'ACCOUNT2_BALANCE': 100,
                'WalletType1': 200,
                'UnitType1': 1,
                'ChargeAmount1': 3,
                'WalletBalance1': 100,
                'WalletType2': 500,
                'UnitType2': 2,
                'ChargeAmount2': 10,
                'WalletBalance2': 0,
                'WalletType3': 610,
                'UnitType3': 2,
                'ChargeAmount3': 20,
                'WalletBalance3': 80,
                'Bonus1': 10,
            }
        ]
    

    data3.json结构:删除空字符串,将来自计费的值插入到“Charging”键中,并带有一个列表。钱包类型用作密钥,该钱包类型的链接信息更进一步。只插入了受影响的钱包。

    [
        {
            'SERIAL': 379120186,
            'TIMESTAMP': 20120701235122,
            'CUSTOMER_ID': 1345567,
            'PRODUCT_ID': 555,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 5,
            'ACCOUNT1_BALANCE': 664,
            'ChargeAmount_FROM_ACCOUNT2': 0,
            'ACCOUNT2_BALANCE': 0,
            'CHARGING': 
                [
                    {
                        '200': 
                            {
                                'UnitType': 1,
                                'ChargeAmount': 5,
                                'WalletBalance': 664
                            }
                    }
                ] , 
    
            'AddtionaInfo': '1234'
        },
        {
            'SERIAL': 379120203,
            'TIMESTAMP': 20120701235136,
            'CUSTOMER_ID': 1345570,
            'RESERVED01': 0,
            'PRODUCT_ID': 1,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 0,
            'ACCOUNT1_BALANCE': 346,
            'ChargeAmount_FROM_ACCOUNT2': 0,
            'ACCOUNT2_BALANCE': 0,
            'CHARGING' : [],
            'AddtionaInfo': 'XXX'
        },
        {
            'SERIAL': 379120207,
            'TIMESTAMP': 20120701235138,
            'CUSTOMER_ID': 1345571,
            'RESERVED01': 0,
            'PRODUCT_ID': 10,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 0,
            'ACCOUNT1_BALANCE': 0,
            'ChargeAmount_FROM_ACCOUNT2': 3,
            'ACCOUNT2_BALANCE': 100,
            'CHARGING': 
                [
                    {
                        '200': 
                            {               
                                'UnitType': 1,
                                'ChargeAmount': 3,
                                'WalletBalance': 100,
                            }
                    },
                    {
                        '500':
                            {
                                'UnitType': 2,
                                'ChargeAmount': 10,
                                'WalletBalance': 0,
                            }
                    },
                    {
                        '610':
                            {
                                'UnitType': 2,
                                'ChargeAmount': 20,
                                'WalletBalance': 80
                            }
                    }
                ],
            'Bonus1': 10,
        }
    ]
    

    data4.json 删除空字符串,将“充值”放入“充电”,但是我们将其保持在此级别,现在使用“WalletType”键,再次只保留那些钱包影响。列表为您提供收费的顺序。

    [
        {
            'SERIAL': 379120186,
            'TIMESTAMP': 20120701235122,
            'CUSTOMER_ID': 1345567,
            'PRODUCT_ID': 555,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 5,
            'ACCOUNT1_BALANCE': 664,
            'ChargeAmount_FROM_ACCOUNT2': 0,
            'ACCOUNT2_BALANCE': 0,
            'CHARGING': 
                [
                    {
                        'WalletType': '200',
                        'UnitType': 1,
                        'ChargeAmount': 5,
                        'WalletBalance': 664
                    }
                ] , 
    
            'AddtionaInfo': '1234'
        },
        {
            'SERIAL': 379120203,
            'TIMESTAMP': 20120701235136,
            'CUSTOMER_ID': 1345570,
            'RESERVED01': 0,
            'PRODUCT_ID': 1,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 0,
            'ACCOUNT1_BALANCE': 346,
            'ChargeAmount_FROM_ACCOUNT2': 0,
            'ACCOUNT2_BALANCE': 0,
            'CHARGING' : [],
            'AddtionaInfo': 'XXX'
        },
        {
            'SERIAL': 379120207,
            'TIMESTAMP': 20120701235138,
            'CUSTOMER_ID': 1345571,
            'RESERVED01': 0,
            'PRODUCT_ID': 10,
            'CUSTOMER_TYPE': 0,
            'CUSTOMER_STATE': 1000000,
            'ChargeAmount_OF_UNITS': 0,
            'ChargeAmount_OF_FUND': 0,
            'ChargeAmount_FROM_ACCOUNT1': 0,
            'ACCOUNT1_BALANCE': 0,
            'ChargeAmount_FROM_ACCOUNT2': 3,
            'ACCOUNT2_BALANCE': 100,
            'CHARGING': 
                [
                    {
                        'WalletType': '200',    
                        'UnitType': 1,
                        'ChargeAmount': 3,
                        'WalletBalance': 100,
                    },
                    {
                        'WalletType': 500,
                        'UnitType': 2,
                        'ChargeAmount': 10,
                        'WalletBalance': 0,
                    },
                    {
                        'WalletType': 610,
                        'UnitType': 2,
                        'ChargeAmount': 20,
                        'WalletBalance': 80
                    }
                ],
            'Bonus1': 10,
        }
    ]
    

    注意: - 当我们总结数据时,希望看到类似于

    的内容
    Date | Hour | Wallet  200 Total Charge| Wallet 500 Total Charge | Wallet 610 Total Charge 
    
    • 我修剪了这个,但实际文件有WalletType1-20

    • 字段名称WalletType(1)中的数字是指钱包的收费顺序(由电子钱包ID表示),即WalletType1 = 200,表示第一个钱包200已收费等。

    • 查看详细记录(摘要)时,收费的顺序是相关的

    • 任何WalletType ID都可以显示在wallet字段中的任何位置。即Wallet ID = 200可以在WalletType1或WalletTyp2等中填充,这取决于优先级规则。

    问题:

    • 您会推荐哪种文档结构,为什么?

    • 所提供的结构会有什么缺陷?

    • 您还有其他建议/其他可能的结构吗?

    • 是否有任何分片/分区建议?

2 个答案:

答案 0 :(得分:2)

最终的架构对我来说看起来最紧凑和可查询。

避免使用长密钥名称 - 密钥名称存储在每个文档中,并且它们的存储大小可以相加。如果SERIAL字段是唯一的,则可以将_id设置为该值,而不是单独存储SERIAL。

答案 1 :(得分:1)

每天处理+ -100,000个文件可能不需要进行分片。