背景介绍:

  国内一流的财经门户站点做栏目调整,需要调整相应的数据调整。

目前站点数据库采用的是 id主键自增长,根据具体业务,将数据存在多张表。

相同业务的,数据存在一张表。每一条新闻资讯都有相应的新闻类型id 和新闻id。通过 http:// www.xx.com/{type}-{newsid}.html 方式,去读取相关的新闻资讯,其中type 表示新闻类别,newsid表示新闻id。每个资讯频道有多个子栏目,类似于和讯网,

新闻频道包含了 滚动、国内、国际等资讯,在新闻表中,使用type 类别进行区分。

同一频道下或者多个频道下 的数据存放在一张表。

不同频道或者耦合性比较低的存放在不同的表中, 类似于 新闻是张新闻表,股票是张股票表。

运营团队提出,在新的形势下,需要对整站的栏目进行调整,同时要对搜索引擎收录的资讯做301重定向,在数据清理过程中,需要提供重定向依据。

任务拆解和具体实现: 

  整体需求大致分类:
    1、同一张数据表之间的调整,仅仅调整资讯type ,需要生成 重定向依据
  类似于以前的地址 http://news.xx.com/111,1101.html 重定向到 http:// news.xx.com/113,1101.html
    2、不同数据表之间的数据合并,因为主键使用int 自增长,所以避免不了id重复,需要提供重定向依据,类似于
  http://news.xx.com/111,1101.html 重定向到 http://stock.xx.com/222,2202.html

根据以上需求,决定使用 C# 控制台直接跑数据,然后将重定向的 数据存入指定的数据表中。
在数据库连接的选择上,有3中,

  • linq to sql;
  • SqlHpler 帮助类;
  • Dapper

  最终选择了 Dapper,原因是据说速度比Ado.net 快。2、接触下这个轻型的 Orm。

  新建控制台应用程序

  添加Dapper 引用。通过 nuget 安装Dapper, 依次打开 工具->Nuget包管理器->程序包管理器控制台,在 程序包管理器控制台 输入Install-Package Dapper 后,敲回车,静等安装成功提示。

  完成安装后,创建Dapper帮助类 DapperHelper,在App.config中配置数据库连接字符串。代码如下: 

 1 public class DapperHelper
 2     {
 3         private static string mssqlConn = ConfigurationManager.ConnectionStrings["appConn"].ToString().Trim();
 4
 5         /// <summary>
 6         /// Dapper 帮助类
 7         /// </summary>
 8         /// <returns></returns>
 9         public static DbConnection MssqlConnection()
10         {
11             SqlConnection conn = new SqlConnection(mssqlConn);
12             conn.Open();  // 打开连接
13
14             return conn;
15         }
16 }

Dapper帮助类

  测试数据库连接情况

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             // 测试 数据库连接情况
 6             using (DbConnection conn = DapperHelper.MssqlConnection())
 7             {
 8                 dynamic time = conn.QueryFirstOrDefault("select getdate();");
 9             }
10         }
11     }

测试数据库连接情况

  此时已经可以联通数据库了。

  因为是做数据的合并和迁移的,需要做相关的日志记录和打印当前情况,做了简单的日志处理帮助类,

  为什么不用log4net 或者其他的呢?
  因为本身就比较简单,所以就造了个轮子,核心代码如下:

 1 /// <summary>
 2     ///  简单日志帮助类
 3     /// </summary>
 4     public class LogHelper
 5     {
 6
 7         private static object loker = new object();
 8
 9         /// <summary>
10         ///  添加日志
11         /// </summary>
12         /// <param name="log"></param>
13         public static void Write(string log)
14         {
15             log = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n" + log;
16
17             WriteTextLog(log);   //记录日志到文本文件
18             Console.WriteLine(log);  //打印日志到控制台
19         }
20
21         /// <summary>
22         /// 写日志到文本文件
23         /// </summary>
24         /// <param name="log"></param>
25         private static void WriteTextLog(string log)
26         {
27             lock (loker)  // 为什么要用 lock?主要是因为 如果并发的话,会有异常的
28             {
29                 string path = AppDomain.CurrentDomain.BaseDirectory + @"Log\";
30                 if (!Directory.Exists(path))
31                     Directory.CreateDirectory(path);
32
33                 string fileFullPath = path + DateTime.Now.ToString("yyyy-MM-dd") + ".System.txt";
34
35                 StreamWriter sw;
36                 if (!File.Exists(fileFullPath))
37                 {
38                     sw = File.CreateText(fileFullPath);
39                 }
40                 else
41                 {
42                     sw = File.AppendText(fileFullPath);
43                 }
44                 sw.WriteLine(log);
45                 sw.Close();
46             }
47
48         }
49     }

简单的日志帮助类

  调用 方式 LogHelper.Write("清洗程序已经启动");
  会自动打印到控制台和 记录日志。

  主要涉及到的功能点:

    资讯表主键为ID自增张,有些不同表之间的ID有重复,怎么处理相关的ID?

  我这边的思路,先将数据按照分页大小取出来,每次清洗5000条记录,取出本表最大值,然后再去设置表的 标识值

  代码:

1                 dynamic _maxId = conn.QueryFirst("select max(id) as maxId from CLOUD_NEWS_GLOBAL ");
2                 int maxId = int.Parse(_maxId.maxId.ToString());
3                 maxId = maxId + 1000;
4                 conn.Execute("DBCC CHECKIDENT(CLOUD_NEWS_GLOBAL,RESEED," + maxId + ")");
5     

设置标识值

  因为资讯的主键值会做改变,所以插入代码主要是用的以下Sql。

1                         conn.Execute(
2                         @"SET IDENTITY_INSERT CLOUD_NEWS_GLOBAL ON
3                         INSERT INTO CLOUD_NEWS_GLOBAL([ID],[INDUSTRYID],...)
4                         values(@ID ,@INDUSTRYID ....)
5                         SET IDENTITY_INSERT CLOUD_NEWS_GLOBAL OFF",
6                        info);
7     

插入数据代码

  主要是设置允许 主键显示插入值。

  总结:

   为什么没有采用异步的方式开几个线程一起搞?主要是我的观点是,保证数据平稳的迁移合并,比速度要重要。宁愿画点时间盯着控制

  台程序输出日志

转载于:https://www.cnblogs.com/nysoft/p/6744027.html

记一次使用Dapper 进行的数据迁移和清洗工作相关推荐

  1. 记一次业务系统拆分的数据迁移及系统切换事项

    一.迁移背景 老系统使用商业化软件,同时包含模块较多,架构无法支撑,维护成本高等考虑,需要根据业务模块拆分多个系统,新系统支持水平扩缩容 ,rcp框架等,新系统基本上包含常用的技术栈(wildfly. ...

  2. Mapreuduce实现网络数据包的清洗工作

    处理后的数据可直接放到hive或者mapreduce程序来统计网络数据流的信息,比如当前实现的是比较简单的http的Get请求的统计 第一个mapreduce:将时间.十六进制包头信息提取出来,并放在 ...

  3. 记一次在K8s集群搭建的MySQL主从无法正常启动之数据迁移恢复实践

    本章目录:记一次在K8s集群搭建的MySQL主从无法正常启动之数据迁移恢复实践 描述:在K8s集群中里利用bitnami提供的mysql:5.7.32-debian-10-r61镜像并利用helm进行 ...

  4. 记一次微信公众号后台数据抓取

    记一次微信公众号后台数据抓取 缘起 思路 缘起 自己参与的公众号做年末总结,需要进行数据爬取,但是微信自带的api只能进行最多一个月的数据对照,不太方便,于是决定自己写一个脚本.原本想用py爬虫,但是 ...

  5. 记一次大规模数据迁移和加密

    公司的核心业务合作伙伴淘宝网,最近出现泄漏用户信息的现象,找了好久找不到根源,于是乎,淘宝那边决定对所有敏感数据进行加密,从出口和入口都走密文,于是乎,我们的工作量就来了. 我们的一个底单数据库,存储 ...

  6. 一部分 数据 迁移_软件测试员12小时惊魂记:数据库迁移出大事故,如何测试?...

    信息时代,随着用户数量不断增加,业务量不断增长,企业原有数据库不足以有效支撑业务的发展,在此情况下,企业更多的是寻求一款更加稳定的数据库进行替代. 本文以Sybase数据库和Oracle数据库为例.O ...

  7. 记nexus2升级nexus3数据迁移

    版本 nexus-2.14 nexus-3.31 数据迁移 方法一: 1.打开nexus2访问页面,创建upgrade(如果存在,直接进行下一步) 2.存在upgrade点击在下面的status找到 ...

  8. 记一次重装系统MySQL数据迁移

    目录 一.前言 二.重装系统 1.数据备份 2.系统重装 三.数据库迁移 1.环境变量 2.安装MySQL服务 3.启动服务 4.连接测试 四.总结 一.前言 电脑无限重启,于是打算重装系统,由于电脑 ...

  9. 【转】记一次 ClickHouse 数据迁移

    转载地址:https://zhuanlan.zhihu.com/p/220172155 背景 大约在 2018 年 8 月份开始正式接触 ClickHouse,当时机房没有合适的服务器,就在 Azur ...

最新文章

  1. Git与Ftp协同工作
  2. python路径拼接问题
  3. python怎么把数据写入txt-python(如何将数据写入本地txt文本文件)
  4. 练习一:GitHub Desktop下载及使用
  5. python命名空间特性_Python命名空间与作用域
  6. Cookie 和 Session的区别 1
  7. c语言rtu crc16,Modbus-RTU-crc16校验方法C语言实现
  8. office数据集dslr_如何将照片从DSLR无线传输到智能手机
  9. TIOBE 6月编程语言排行榜:Python势不可挡
  10. android 音量级别调节,调整Android音量等级及默认音量
  11. es6—变量的解构赋值
  12. bzoj 3367: [Usaco2004 Feb]The Big Game 球赛(DP)
  13. 字体样式及其属性、文本外观属性
  14. OSPF高级特性(华为设备)
  15. cisco独臂路由(即单臂路由)的配置
  16. 计算机考试表格函数应用题,2017年职称计算机考试Excel练习题2
  17. 数字后端设计流程小结
  18. Cocos2d-js 音乐or音效
  19. RHEL7平台下电信拨号上网配置
  20. 顶级公司程序员,一天只写100行代码?

热门文章

  1. oracle删除死锁进程
  2. 如何自己写xuetr(一) 每次改变的驱动名和服务名
  3. JavaScript(JS)常用的正则表达式
  4. android手机分享app,Android Pie如何快捷分享文件至特定App
  5. 数据中心的容器操作系统--k8s理解
  6. DynamoRIO工作原理
  7. 自行搭建嵌入式持续集成工具:从0到1
  8. (216)滤波器介绍
  9. FPGA原语类型介绍
  10. linux日志删除1天前,Linux自动删除n天前日志