• 引言
    工作需要将数十万条文本数据解析存入Mysql数据库中,代码使用C#实现,存储效率还可以,以下是一些主要代码的说明。

txtdataToMysql

项目描述:解析文本文件,该文件使用爬虫爬下的数十万条数据,主要是图片以及图片关键字,图片信息使用','分隔,关键字使用 ' '(一个空格),关键字不允许重复。

  • 分析需要创建的数据库
    该数据库为多对多,所以需要三张表,一张表为image_info,一张为image_keyword,一张为关系表img_and_key_relation。在这里并没有添加外键,加入外键后插入数据难度比较大,Mysql还没有具体学习过,关于主键与外键的关系,以及外键的作用等以后补充。以下为创建数据库的代码

这里并没有将image_infoimage_keyword的主键设为自动增加,为了插入img_and_key_relation表时能够获得其余两张表的键值,具体获得方法将在代码中讲解。
解析文本
代码使用c#写的所以可以使用按行读取文本,使用Split()方法将文本进行解析,对于文本解析专门设置了一个class TxtFilter,在该类中实现文本解析方法,在插入关键字时,使用Dictionary<string, int> keywordDic,将关键字存入字典中,字典的关键字为解析的关键字,使用字典因为要求键值唯一,这样在匹配关键字是可以方便,开始的时候并没有注意到Mysql数据库大小写不敏感,而c#的字典键值为大小写敏感的,所有在插入关键字是有些重复了,设置字典大小写不敏感需要如此创建字典
Dictionary<string, int> keywordDic = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);这样可以保证插入的关键字唯一。对判断关键字的唯一性使用hashset也是可以,但是不知道它能否无视大小写,所以还需要补充,hashset的时间复杂度为O(1),而Dictionary的时间复杂度为O(n),当数据量比较大时查找速度比较快。Dictionaryhashset的区别再去字典使用key查找value,查找value的速度比较快,而hashset为一个集合,关于这两个的区别以后还会补充,目前只知道这些。

  • c#连接Mysql数据库

这里创建了一个数据库类,在该类中实现以上两种方法,目的保护数据库账户密码,在这里并不需要,只是个人的一点想法,不知道对错

  • 如何大批量插入数据到Mysql中
    这里参考了链接采用了事物处理的方法,具体的还需要进一步学习。主要是将插入语句放入到一个List<string>中,所以需要解析文本,生成插入语句,将所有的插入语句添加到一个列表中,为了检查插入语句的正确性,将所有的插入语句写入到一个txt文本中,方便检查。
  • txtFilter类分析
    解析的文本文件由一些特点,有些图片没有关键字,所以对于这些信息需要判断删除,并且解析关键字的时候有的关键字是空格,这些问题在开始的时候都没有考虑到。所以在原来的代码上添加了一些判定条件。为了检查方便将三张表的插入语句各自打印了出来,有些代码存在重复,可以优化一些,比如针对不同的操作设定操作码,使用switch case语句,选择不同的筛选方式。先写出关键的文本解析语句,将所有插入语句存入List<string>中,并且定义了将插入语句写入文本的函数,这样有利于查看插入语句是否存在问题。以下是主要函数代码:

为了将关键字是空格的图像解析出去,所以使用了两种方式,一般有空格的图像信息的键值长度为1,但是键值为1的又不一定是空格(有点啰嗦意思理解就好)所以将解析方式设为两种,键值长度为1>1两种。然后判断键值是否为空格,不是空格的话将图像长度+1,数据库中图像表的键值与图片长度(相当于图片的index)相关联。
因为一个图像不一定有一个关键字,所以图像的插入语句与关键字与关系表的插入语句分开统计。获得每个图片关键字的长度,将每一个图片的关键字使用Sqlit(' ')解析到一个字符串数组中,遍历字符串判断关键字是否存在在字典中,不存在的话将该关键字插入到关键字表中,存在的话直接在关键字字典中查找该关键字的键值,将图像的键值与该关键字的键值插入到关系表中。最后将该图片的所有插入语句赋值给sqlCommond,加入到指令列表SQLStringList中,解析完后返回列表。

05-27 19:13