当前位置: 首页 > 后端技术 > PHP

大数据导入MySql设计空间换时间的设计更改

时间:2023-03-30 06:08:49 PHP

这几天一直在纠结一个大数据批量导入的问题。经过几天的思考,发现基于小数据的情况,原来的数据结构设计是没有问题的。是的,但是当导入大量数据的时候,问题就非常大了。之前一直在强调“程序=数据结构+算法”,到这里就钻牛角尖了。最后仔细看了之前别人设计的数据表,突然灵光一现,发现mysql层面需要用空间换取时间。具体的设计思路。基于这种情况,我先说说我经历了这个过程之后的感受。如果后续程序逻辑出现算法复杂的问题,就不要继续之前的程序设计,也不要继续之前的数据表结构设计,而是多方面思考。随着业务的变化,不仅是程序的变化,还有数据结构的变化,大量数据的处理不同于常规的处理数据的思维。这次关于产品需求的具体问题,我就从产品需求说起,从头说说我踩过的坑。用户可以根据代码知道产品的流向。该系统有几层代理。产品到达用户手中后,用户可以扫码查看整个产品的流向,经过了哪些代理商;代理人扫码发货,根据溯源码标记货物的发货状态,同时存储代理人的发货状态。溯源码分为大号、中号和小号三种。类似于大号对应一箱货品,中号对应一箱货品中的一个箱子,小号对应一箱货品中的某件商品。特定项目;也就是说,大号覆盖中号,中号覆盖小号。需要通过上层溯源码找到整条关系链。商家根据需要导入溯源码,一次导入的数据数量在10万条左右,或多或少。踩原数据表结构设计admin_id#企业IDproduct_id#产品IDsecurity_code#追溯码code_type#追溯码类型:1大码,2中码,3小码parent_id#当前追溯码的上级ID,如小码对应上层中码IDtop_id#TopID,对应大码ID,中码和小码都必须是粗码is_use#这个溯源码是否被使用is_sell_out#是否已售出#是否已售出删除原来的程序设计思路整个数据表结构的设计逻辑是关联parent_id的关系,然后用code_type表示溯源码的类型。导入时,首先要确定父对象,然后存储子对象。逐层遍历导入。这种设计带来的问题是导入必须一层层遍历,会导致导入相当慢。必须先插入rich-levelID,再插入child-levelID,因为child-levelID与parent-levelID相关联。这样,INSERTINTOtable(field1,field2)VALUES('a',1),('b',1),('c',1);不能使用mysql的批量插入,否则数据插入会很慢。经过我后来的思考,最后一层,也就是小代码使用了批量插入,但是效率还是不高。即使小代码改成批量插入,一次批量插入的数据也只有20条左右,效率上并没有太大的提升。新表设计方法新设计,我把整个表拆分成两张表,一张表存储关系链,另一张表用于追溯标记和查询,大致如下:关系表admin_id#商户IDproduct_id#商品IDcode_max#大codecode_middle#中码code_min#小码溯源码标识表admin_id#商IDproduct_id#产品IDcode#溯源码,无论大码、中码、小码,都会创建一条数据存储在该字段is_use#是否使用is_sell_out#是否出售create_time#创建时间update_time#更新时间is_delete#新逻辑是否已经删除说明首先关系表中存储关系,大号、中号、小号都齐全,可以通过大码ID中码,小码查询以下所有内容;追溯码标识表,该表专门用于查询和标识追溯码状态等。新的设计方式会增加数据表数据的管理成本,同时也会增加数据的大小。新数据表关系数据的数据结构类似这样:大码,中码,小码111111111112112123112124221211221212222221222222这个表结构的描述是一个例子,避免看不懂关系链的数据逻辑。整个表经过这样重新设计和组织后,每次同时插入两张表,可以使用MySQL的批量插入操作进行插入,插入速度大大提高。数据重复对比本产品设计中,整套溯源码不可重复。经过多方考虑,最终采用inquery机制。整套思路大致是这样的:每次遍历100条要导入的数据,然后用mysql的in查询,如果取到数据,遍历数据标记哪条是重复的。不断循环获取,然后将输出标记为CSV。遍历完成后,将带有重复标记的文档返回给用户,让用户修改后再上传。但是,对于这种数据比较,我没有更好的主意。我在数据表中测试了18W导入数据和25W数据的对比,耗时13秒左右。我估计的比较次数应该是18W。*25W,如果谁有这方面更好的数据对比算法,请留言告诉我,将不胜感激。我只是借这篇文章来纪念一下我踩过的坑,也希望后人看了这篇文章能够得到一些解决办法。