使用SQLite实现数十亿条记录

时间:2019-04-04 17:47:18

标签: c# wpf sqlite csv

在我的WPF应用程序中,我正在将客户数据插入SQLite数据库。我有2个表格(邮政编码和客户)。数据可以增长到数十亿。我需要从数据库中快速插入和检索。

我正在使用SQLite,因为该应用程序仅在单个系统上使用。根据我的研究,SQLite可以处理TB的数据,所以我想知道它是否有问题?

以前,我使用MySQL和EF,但是插入和检索非常慢。

这是两个表。从ZipCode获取客户信息时,会将其添加到记录中。

CREATE TABLE ZIPCODE(
                    Zip NUMERIC PRIMARY KEY ,
                    City VARCHAR,
                    County VARCHAR,
                    State VARCHAR
                );
CREATE TABLE CUSTOMER(
                Phone NUMERIC PRIMARY KEY,
                FirstName VARCHAR,
                LastName VARCHAR,
                Address VARCHAR,
                Zip NUMERIC,
                Status CHAR(5),
                Category CHAR(10),
                Options CHAR(5),
                Email VARCHAR,
                Seconds NUMERIC,
                FOREIGN KEY(Zip) REFERENCES ZIPCODE(Zip)
            );

下面是我用来插入数据的C#函数。

public int AddCustomersToDB(List<Customer> customers)
        {
            int invalidCount = 0;
            try
            {
                _dbConnection.Open();
                using (var cmd = new SQLiteCommand(_dbConnection))
                {
                    using (var transaction = _dbConnection.BeginTransaction())
                    {
                        foreach (Customer c in customers)
                        {
                            string values = String.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\",\"{9}\"", c.Phone, c.FirstName, c.LastName, c.Address, c.Zip, c.Status, c.Category, c.Options, c.Email, c.Seconds);
                            cmd.CommandText = String.Format(@"INSERT INTO CUSTOMER(Phone,FirstName,LastName,Address,Zip,Status,Campaign,Options,Email,Seconds) VALUES ({0});", values);
                            try
                            {
                                cmd.ExecuteNonQuery();
                            }
                            catch (SQLiteException e)
                            {
                                invalidCount++;
                                continue;
                            }
                        }
                        transaction.Commit();
                    }
                }
                return invalidCount;
            }
            catch (SQLiteException e)
            {
                throw new Exception("SQLiteException:" + e.Message);
            }
            finally { _dbConnection.Close(); }
        }

它需要有关此方法的一些建议,我在GitHub上有Code,所以如果有人想看完整的代码,我也可以分享。

1 个答案:

答案 0 :(得分:1)

我会改变一些事情。我会使用sql命令参数,因为它将防止sql注入攻击并清理您的代码。 try / catch / finally块使您的代码更容易出错,因为您必须手动处理连接。将代码包装在using block中,即使在using块中发生异常,也可以确保调用Dispose。

关于您的SQLite问题-maximum database size for a SQLite数据库大约为140 TB。这样它可以处理很多数据,但是您是否要使用这种大小的SQLite数据库

我在多个项目上使用过SQLite,但从未在大型数据集上使用过。将其用于大型数据集的不利之处在于,它将整个数据库存储在单个磁盘文件中,许多文件系统将文件的最大大小限制为小于SQLite的限制。

我将复查以下内容以获取一般使用准则:Appropriate Uses For SQLite

显示参数用法和using块的示例代码:

        var customers = new List<Customer>(); // get your customers

        using (var conn = new SQLiteConnection("your connection string"))
        {
            await conn.OpenAsync();

            using (var cmd = new SQLiteCommand(conn))
            {
                cmd.CommandText = cmd.CommandText = "INSERT INTO CUSTOMER (Phone, FirstName) VALUES(@param1, @param2)";
                cmd.CommandType = CommandType.Text;

                using (var trans = conn.BeginTransaction())
                {
                    foreach (var c in customers)
                    {
                        cmd.Parameters.AddWithValue("@param1", c.Phone);
                        cmd.Parameters.AddWithValue("@param2", c.FirstName);

                        await cmd.ExecuteNonQueryAsync();
                    }
                }
            }
        }