Access数据库是一个相当古老的文件型数据库,主打一个简单+方便,没有复杂的安装过程,没有庞大的后端管理,整个数据库就是一个文件。可以像普通文件一样复制和修改,可以同时读写。
在小型系统中,还是有较多的存量系统在使用Access数据库,相对简单的文件存储,还是有很大的进步。Access是关系型数据库,数据是结构化存储,数据的关系和格式,相对文件严谨很多。
定义数据库表Measurement,定义几个字段。
2、写入代码片段
using System.Data.OleDb;
OleDbConnection odcConnection=null;
string fileName = "D:\\Tools\\Pascal.mdb";
//*********连接本地ACCESS数据库************************
String sAccessConnection = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " + fileName;
odcConnection = new OleDbConnection(sAccessConnection);
odcConnection.Open(); //打开连接
Random ranValue = new Random();
int wdCount = 0;
int wdErrCount = 0;
private void WriteAccessData()
{
int FieldCount = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
try
{
OleDbCommand odCommand = odcConnection.CreateCommand(); //建立SQL查询
//3、输入查询语句
string dtStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
double f = ranValue.NextDouble()*1000;
string sqlCmd = $"INSERT INTO Measurement (站点名称,日期时间,Data_1,Data_2,Data_3,Data_4,Data_5) VALUES ('站点1','{dtStr}','{f}','{f}','{f}','{f}','{f}')";
odCommand.CommandText = sqlCmd;
odCommand.ExecuteNonQuery(); //建立读取
//*********连接本地ACCESS数据库************************
Console.WriteLine($"Write Count:{++wdCount},FieldCount:{FieldCount},Elapsed(s):{sw.Elapsed.TotalSeconds}");
}catch (Exception ex)
{
wdErrCount++;
Console.WriteLine($"write err:{ex.Message}");
}
}
通过定时写入观察,在数据量持续增加,数据文件到达100MB+后,数据的写入性能没有明显变化。
OleDbConnection odcConnection = null;
private void GetAccessData()
{
string rcStatus = "";
int FieldCount = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
try
{
readCount++;
//*********连接本地ACCESS数据库************************
String sAccessConnection = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = "+ fileName;
if (odcConnection==null)
{
odcConnection = new OleDbConnection(sAccessConnection);
odcConnection.Open(); //2、打开连接
}
{
string sqlCmd = "SELECT TOP 1 * FROM Measurement ORDER BY 日期时间 DESC";
//查询数据,仅读取第一条记录
using (OleDbCommand odCommand = odcConnection.CreateCommand())
{
odCommand.CommandText = sqlCmd;
infoRunMsg = sqlCmd;
using (DbDataReader odrReader = odCommand.ExecuteReader())
{
while (odrReader.Read()) //查询并显示数据
{
FieldCount = odrReader.FieldCount;
for (int i = 0; i < odrReader.FieldCount; i++)
{
var f = odrReader.GetName(i);
var v = odrReader.GetValue(i);
//Console.WriteLine($"{f}:{v}");
}
break;
}
}
}
}
//*********连接本地ACCESS数据库************************
rcStatus = "Ok";
Console.WriteLine($"Read Count:{readCount},Err:{readErrCount},FieldCount:{FieldCount},Elapsed(s):{sw.Elapsed.TotalSeconds}");
}catch (Exception ex)
{
odcConnection?.Close();
odcConnection = null;
readErrCount++;
rcStatus = ex.Message;
Console.WriteLine("Read Err:"+ex.Message);
}
}
读取数据时,随着数据量的增加,性能有明显的下降,这点与其他数据库有点类似。
读取数据的优化方面,Access和普通的数据库有点类似,可以尝试常规的方法来改进读取性能。
我们数据定义中有时间参数,加入时间过滤条件筛选SQL不需要的数据时,可以明显改善性能。比如将上面的SQL改为:
“SELECT TOP 1 * FROM Measurement where 日期时间>\"2024-01-01 12:00:00\" ORDER BY 日期时间 DESC”,性能提升明显。
继续优化,使用具体列名称替代SELECT *,新的SQL如下:
"SELECT TOP 1 站点名称,日期时间,Data_1,Data_2,Data_3,Data_4,Data_5 FROM Measurement where 日期时间>\"2024-01-01 12:00:00\" ORDER BY 日期时间 DESC",也有比较明显的改善。