SQL大数据存储-来一次存入大量数据

在今天公司的一套ERP系统系统架构中,经过一系列的筛选优化之后大量数据需要同步数据库存储,由A→B数据库存储(这里可以采用MSDTC,会涉及到网络安全验证,需要自己优化) 涉及到客户大量数据一次导入,不必苦恼SQL大数据存储,在这里我们可以采用SqlBulkCopy ,它是.net中的一个类,提供了大数据一次导入功能。具体类的使用方法如下:

using (SqlBulkCopy da = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction, null))
{
     da.BulkCopyTimeout = 10 * 60;
     da.BatchSize = 10000;
     da.DestinationTableName = "dbo.Destination";
     da.WriteToServer(reader); //reader 是一个继承自IDataReader的类的实例
}

 

自己可以写代码来实现继承自IDataReader的类。有许多成员要实现。。。

比如FieldCount, Read(), GetValue(int i), Close()等

下面是一个读文件的例子:

//返回记录的列数
        public int FieldCount  
        {
             get { return 3; }
        }

        //读记录,此方法会被自动调用
        public bool Read()
        {
            if (_Reader == null)
                _Reader = new StreamReader(_FilePath);

            string line = _Reader.ReadLine();
            
            if (line != null)
            {
                _CurrentQueryItem = GetRawData(line);
                _Count++;

                while (_CurrentQueryItem == null)//如果读出的是不满足条件的记录,则读下一条记录
                {
                    Read();
                }
                return true;
            }            
            return false;
        }

        //返回一条记录中第i 列(项)的值,此方法会被自动调用
    //SqlBulkCopy内部应该有一个循环,从0到FieldCount -1 ,再调用GetValue(int i)这个方法。我猜的。。。
        public object GetValue(int i)
        {
            if (_CurrentQueryItem == null)
                return null;

            switch (i)
            {
                //如果数据库中表的第一列是自增字段,则会忽略第一列,也就是说此方法被调用时,i只会从1开始,所以不需要case 0的情况。估计.net内部去取目的表的schema,自动判断哪些列是需要从外部导入的。有空再研究这个问题
                case 0:
                    return _CurrentQueryItem.Item1;
                case 1:
                    return _CurrentQueryItem.Item2;
                case 2:
                    return _CurrentQueryItem.Item3;
                default:
                    throw new IndexOutOfRangeException();
            }
        }

        //释放资源
        public void Close()
        {
            Dispose();
        }

        public void Dispose()
        {
            if (_Reader != null)
                _Reader.Close();
        }

 

有一些其他属性其方法需要自己实现,当然有的不实现也没关系。似乎重要的就以上几个方法了。
对照SqlDataRead,自己可以猜想出会用到哪些方法。

经过实验,一个文件如果一行一行插入到数据库里,需要大约2分钟,如果用SqlBulkCopy 10秒左右就完成了。而且可以自己实现类来指定处理什么数据,也不用把文件放在数据库机器上了。不错。

忘说了,SqlBulkCopy里用到的connction对象只能是SqlConnection。SqlBulkCopy.WriteToServer (DataRow]) 和SqlBulkCopy.WriteToServer (DataTable) 都是可以的。

补充:在批量输入存储的时候我们可以使用嵌套事务存储,1000条划分,在下次的友源吧再分享

未经允许不得转载:聚艺帮 » SQL大数据存储-来一次存入大量数据

分享到:更多 ()

牛评 抢沙发

爱生活 爱设计

齐聚智慧联系我们