目前正致力于POC从RDBMS迁移并评估MongoDB,在执行架构的过程中,并希望确保它满足我们的需求。
一些背景知识 - 我们每天处理+ -100,000个文件 - 大约10种不同的文件类型(可以进入不同的集合) - 每天+ 1亿条记录 - 文件是管道分隔文本 - 将使用python加载数据 - 每个文件包含100-250个字段
当前设置 - 每个文件类型都被加载到它自己的表中(按天划分) 即 文件类型A将在FileA中(分区20120701) 文件类型B将在FileB中(分区20120701) 等。
我已经包含了源数据的修剪文件(删除的字段和记录),以及4种不同的结构数据选项。我目前的设计是:
每种文件类型每天收集(详细记录) 即 FileA_20120701 FileB_20120701
每小时汇总数据的每月收集,将包括所有文件类型记录 即Hourly_usage_201207
每日汇总数据每年收集一次,包括所有文件类型记录,即Daily_usage_2012
所以: 每小时地图缩小>每日地图减少
现在我专注于如何存储详细记录,请查看文件中提供的原始数据:
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等中填充,这取决于优先级规则。
问题:
您会推荐哪种文档结构,为什么?
所提供的结构会有什么缺陷?
您还有其他建议/其他可能的结构吗?
是否有任何分片/分区建议?
答案 0 :(得分:2)
最终的架构对我来说看起来最紧凑和可查询。
避免使用长密钥名称 - 密钥名称存储在每个文档中,并且它们的存储大小可以相加。如果SERIAL字段是唯一的,则可以将_id设置为该值,而不是单独存储SERIAL。
答案 1 :(得分:1)
每天处理+ -100,000个文件可能不需要进行分片。