c#数据库解析
- 引言
工作需要将数十万条文本数据解析存入Mysql数据库中,代码使用C#实现,存储效率还可以,以下是一些主要代码的说明。
txtdataToMysql
项目描述:解析文本文件,该文件使用爬虫爬下的数十万条数据,主要是图片以及图片关键字,图片信息使用','
分隔,关键字使用 ' '
(一个空格),关键字不允许重复。
- 分析需要创建的数据库
该数据库为多对多,所以需要三张表,一张表为image_info
,一张为image_keyword
,一张为关系表img_and_key_relation
。在这里并没有添加外键,加入外键后插入数据难度比较大,Mysql
还没有具体学习过,关于主键与外键的关系,以及外键的作用等以后补充。以下为创建数据库的代码
12345create database emotion;use emotion;create table image_Keyword(keyword_id int(4) not null primary key,keyword varchar(40) not null);create table image_info(image_id int(4) not null primary key,id_other varchar(20) not null,id_self varchar(9) not null,image_url varchar(100) not null);create table img_and_key_relation(relation_id int(4) not null primary key auto_increment,keyword_id int(4) not null,image_id int(4) not null);
这里并没有将image_info
与image_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)
,当数据量比较大时查找速度比较快。Dictionary
与hashset
的区别再去字典使用key
查找value
,查找value
的速度比较快,而hashset
为一个集合,关于这两个的区别以后还会补充,目前只知道这些。
- c#连接Mysql数据库
12345678910private static string constr = @"Server=localhost;UserId=root;password=yourpassword;Database=databaseName";public MySqlConnection sqlConnection() {MySqlConnection conn = new MySqlConnection(constr);conn.Open();string msg = conn.State.ToString();return conn;}public void sqlConnectionClose(MySqlConnection conn) {conn.Close();}
这里创建了一个数据库类,在该类中实现以上两种方法,目的保护数据库账户密码,在这里并不需要,只是个人的一点想法,不知道对错
- 如何大批量插入数据到Mysql中
这里参考了链接采用了事物处理的方法,具体的还需要进一步学习。主要是将插入语句放入到一个List<string>
中,所以需要解析文本,生成插入语句,将所有的插入语句添加到一个列表中,为了检查插入语句的正确性,将所有的插入语句写入到一个txt文本中,方便检查。 - txtFilter类分析
解析的文本文件由一些特点,有些图片没有关键字,所以对于这些信息需要判断删除,并且解析关键字的时候有的关键字是空格,这些问题在开始的时候都没有考虑到。所以在原来的代码上添加了一些判定条件。为了检查方便将三张表的插入语句各自打印了出来,有些代码存在重复,可以优化一些,比如针对不同的操作设定操作码,使用switch case
语句,选择不同的筛选方式。先写出关键的文本解析语句,将所有插入语句存入List<string>
中,并且定义了将插入语句写入文本的函数,这样有利于查看插入语句是否存在问题。以下是主要函数代码:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051大专栏 c#数据库解析ine">5253545556575859606162636465666768697071public List<string> filterToSqlCommond2(string fileName){List<string> SQLStringList = new List<string>();Data fileData = new Data();Dictionary<string, int> keywordDic = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);string sqlCommond="";int numOfKeyword = 0;int numOfImage = 0;//如果使用HashSet判断关键字是否存在会更快一些,这里并没有用这种方法//HashSet<string> keywordSet = new HashSet<string>();StreamReader sr = new StreamReader(fileName);string strContent;while ((strContent = sr.ReadLine()) != null){string[] strArr = strContent.Split(',');fileData.id_other = strArr[0];fileData.id_self = strArr[1];fileData.image_url = strArr[3];string insertImageCommond = "";string insertKeyAndR = "";string[] keyword = strArr[4].Split(' ');//numKeyword表示读取每一行获得的关键字个数int numKeyword = keyword.Length;switch(numKeyword){case 1:if (!string.IsNullOrEmpty(keyword[0])){numOfImage += 1;insertImageCommond = string.Format(@"insert into image(image_id,id_other,id_self,image_url) values('{0}','{1}','{2}','{3}');", numOfImage, fileData.id_other, fileData.id_self, fileData.image_url);if (!keywordDic.Keys.Contains(keyword[0])){numOfKeyword += 1;keywordDic.Add(keyword[0], numOfKeyword);string.Format(@" insert into imagekeyword(keyword_id,keyword) value('{0}','{1}');insert into img_and_key_relation(keyword_id,image_id) values('{2}','{3}');", keywordDic[keyword[0]], keyword[0], keywordDic[keyword[0]], numOfImage);}else{int keyword_id = keywordDic[keyword[0]];insertKeyAndR = insertKeyAndR + string.Format(@"insert into img_and_key_relation(keyword_id,image_id) values('{0}','{1}');", keyword_id, numOfImage);}}sqlCommond = insertImageCommond + insertKeyAndR;SQLStringList.Add(sqlCommond);break;default:numOfImage += 1;insertImageCommond = string.Format(@"insert into image(image_id,id_other,id_self,image_url) values('{0}','{1}','{2}','{3}');", numOfImage, fileData.id_other, fileData.id_self, fileData.image_url);for (int i = 0; i < numKeyword; i++){if (!string.IsNullOrEmpty(keyword[i])){if (!keywordDic.Keys.Contains(keyword[i])){numOfKeyword += 1;keywordDic.Add(keyword[i], numOfKeyword);insertKeyAndR = insertKeyAndR + string.Format(@" insert into imagekeyword(keyword_id,keyword) value('{0}','{1}');insert into img_and_key_relation(keyword_id,image_id) values('{2}','{3}');", keywordDic[keyword[i]], keyword[i], keywordDic[keyword[i]], numOfImage);}else{int keyword_id = keywordDic[keyword[i]];insertKeyAndR = insertKeyAndR + string.Format(@"insert into img_and_key_relation(keyword_id,image_id) values('{0}','{1}');", keyword_id, numOfImage);}}}sqlCommond = insertImageCommond + insertKeyAndR;SQLStringList.Add(sqlCommond);break;}}return SQLStringList;}
为了将关键字是空格的图像解析出去,所以使用了两种方式,一般有空格的图像信息的键值长度为1
,但是键值为1
的又不一定是空格(有点啰嗦意思理解就好)所以将解析方式设为两种,键值长度为1
与>1
两种。然后判断键值是否为空格
,不是空格的话将图像长度+1
,数据库中图像表的键值与图片长度(相当于图片的index
)相关联。
因为一个图像不一定有一个关键字,所以图像的插入语句与关键字与关系表的插入语句分开统计。获得每个图片关键字的长度,将每一个图片的关键字使用Sqlit(' ')
解析到一个字符串数组中,遍历字符串判断关键字是否存在在字典中,不存在的话将该关键字插入到关键字表中,存在的话直接在关键字字典中查找该关键字的键值,将图像的键值与该关键字的键值插入到关系表中。最后将该图片的所有插入语句赋值给sqlCommond
,加入到指令列表SQLStringList
中,解析完后返回列表。
c#数据库解析的更多相关文章
- 使用递归算法结合数据库解析成java树形结构
使用递归算法结合数据库解析成java树形结构 1.准备表结构及对应的表数据a.表结构: create table TB_TREE ( CID NUMBER not null, CNAME VARCHA ...
- 【ABAP系列】SAP 的逻辑数据库解析
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP 的逻辑数据库解析 前 ...
- oracle数据库解析json格式
随着非关系型数据大规模使用,以json格式产生的数据也出现在我所管理的Oracle数据库的CLOB字段里面,使用过程中就需要解析出指定键的值. 使用了最新版本 如果Oracle版本为12.1.0.2的 ...
- iOS sqlite3数据库解析
看来从版本3.3.1基本上已经支持线程句柄的传递功能.具体限制我标记了一下.(6) Is SQLite threadsafe?SQLite is threadsafe. We make this co ...
- 数据库解析IP,时间戳
#解析IP SELECT INET_NTOA('168494269'); #解析时间戳 SELECT FROM_UNIXTIME('1505458308');
- 递归算法结合数据库 解析 java树形结构
1.准备表结构及对应的表数据a.表结构: create table TB_TREE ( CID NUMBER not null, CNAME VARCHAR2(50), PID NUMBER //父节 ...
- Sakila——MySQL样例数据库解析(已经迁移)
一.Introduction Sakila可以作为数据库设计的参考,也可作为实验数据.我是用作数据仓库和ODI学习的实验数据. The Sakila sample database was devel ...
- 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_07-用户认证-认证服务查询数据库-解析申请令牌错误信息
1.2.5.4 解析申请令牌错误信息 当账号输入错误应该返回用户不存在的信息,当密码错误要返回用户名或密码错误信息,业务流程图如下: 修改申请令牌的程序解析返回的错误: 由于restTemplate收 ...
- 纯真IP数据库解析Delphi D10.1下正常使用
直接一个单元,代码分享出来. unit Net.IPLocation; interface uses System.Classes, System.SysUtils, Winapi.WinSock ...
随机推荐
- 转发和重定向简介及与之相关的(URL)参数(parameter)、属性(attribute)问题探讨
1.引子 转发和重定向是我们在做web项目中常用到的两个术语,有必要理清两者的区别和与之相关的参数.属性获取问题. 2.转发和重定向 1).转发 转发是服务器行为,将当前请求(Request)和响应( ...
- Maven--设置Http代理
<settings> ... <proxies> <proxy> <id>my-proxy</id> <active>true& ...
- 编译Python文件
编译Python文件 一.编译Python文件 为了提高加载模块的速度,强调强调强调:提高的是加载速度而绝非运行速度.python解释器会在__pycache__目录中下缓存每个模块编译后的版本,格式 ...
- MobileNets: Open-Source Models for Efficient On-Device Vision
https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html Wednesday, June 14, ...
- iTOP-3399开发板搭建Android编译坏境
基于迅为iTOP-3399开发板2.1 装 安装 d android 源码依赖包登录进 Ubuntu 系统,输入“ctrl+alt+t”,打开超级终端,使用“su root”命令,切换到 root ...
- mac词典安装
网上下载词典文件,比如https://www.xiaomac.com/2013121204.html,将朗道词典解压放入这里. $ ls /Library/Dictionaries/ langdao- ...
- 在Orcl中通过SQL语句修改创建表
1.创建表时定义唯一性约束 CREATE TABLE table_name ( column1 datatype null/not null, column2 datatype null/not nu ...
- 计算a^b==a+b在(l,r)的对数Codeforces Round #597 (Div. 2)
题:https://codeforces.com/contest/1245/problem/F 分析:转化为:求区间内满足a&b==0的对数(解释见代码) ///求满足a&b==0在区 ...
- LeetCode No.121,122,123
No.121 MaxProfit 买卖股票的最佳时机 题目 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你 ...
- Spring Boot中@Async的作用
在Spring中,@Async这个注解用于标记的异步的方法.方法上一旦标记了这个方法,当其它线程调用这个方法时,就会开启一个新的线程去异步处理业务逻辑. 此注解的使用说明: 1.此注解可以用在方法上, ...