.Net操作Clickhouse的庫比較少,大多數都是基於[ClickHouse.ADO](https://github.com/killwort/ClickHouse-Net)的一個封裝,下麵也主要介紹一下ClickHouse.ADO的使用,以及自己封裝的一個庫的使用。 ...
該篇內容由個人博客點擊跳轉同步更新!轉載請註明出處!
我不喜歡拿一堆數據的運行耗時來對比各個解決方案的性能等,有時候看一些測評長篇大論寫耗時的一些對比,有時就差個 幾百毫秒 我覺得也沒啥必要,關鍵是好用就行,一切從簡,我寫博客也喜歡一切從簡。
.Net操作Clickhouse的庫比較少,大多數都是基於ClickHouse.ADO的一個封裝,下麵也主要介紹一下ClickHouse.ADO的使用,以及自己封裝的一個庫的使用。
前言
Clickhouse適用於大數據量分析,我的應用場景是每十秒從公交軌跡中取固定時間段數據分析一些情況,電腦配置就是普通的開發配置,總體數據軌跡量在3億左右,處理的數據時間段在一天以內,取出的數據量在2.3萬條左右。大家可以當個借鑒!
具體操作
一、簡單的查詢和新增以及批量新增(Clickhouse不推薦數據的編輯和刪除此處就不再舉例)
public class Demo
{
private ClickHouseConnection GetConnection(string cstr= "Compress=True;CheckCompressedHash=False;Compressor=lz4;Host=ch-test.flippingbook.com;Port=9000;Database=default;User=andreya;Password=123")
{
var settings = new ClickHouseConnectionSettings(cstr);
var cnn = new ClickHouseConnection(settings);
cnn.Open();
return cnn;
}
/*查詢*/
public void Select()
{
using (var cnn = GetConnection())
{
var reader = cnn.CreateCommand("SELECT * FROM test").ExecuteReader()
......省略
}
}
/*增加*/
public void Insert()
{
using (var cnn = GetConnection())
{
var cmd = cnn.CreateCommand("INSERT INTO test (date,x, arr)values ('2017-01-01',1,['a','b','c'])");
cmd.ExecuteNonQuery();
}
}
/*批量新增*/
public void InsertBulk()
{
using (var cnn = GetConnection())
{
var cmd = cnn.CreateCommand("INSERT INTO test (date,x, values.name,values.value)values @bulk;");
cmd.Parameters.Add(new ClickHouseParameter
{
DbType = DbType.Object,
ParameterName = "bulk",
Value = new[]
{
new object[] {DateTime.Now, 1, new[] {"[email protected]", "awdasdas"}, new[] {"dsdsds", "dsfdsds"}},
new object[] {DateTime.Now.AddHours(-1), 2, new string[0], new string[0]},
}
});
cmd.ExecuteNonQuery();
}
}
}
二、鑒於使用原始方法讀取數據後轉換的方式太麻煩,分頁等也需要自己實現,所以寫了一個幫助類,方便操作Clickhouse,點擊跳轉
使用方式也很簡單,如下:
public HistoryModel GetHistories(string busid, string begindt, string enddt)
{
using (var helper = new ClickHouseHelper())
{
try
{
HistoryModel historyModel = new HistoryModel();
historyModel.Histories = helper .ExecuteList<HistoriesModel>($"select mile,speed,lon,lat,direct,termtime from its.gps_MergeTree where termtime >='{begindt}' and termtime<='{enddt}' and busid={busid} order by termtime");
historyModel.Inouts = helper .ExecuteList<InoutModel>($"SELECT * FROM its.inout_t WHERE Adtime>='{begindt}' and Adtime<='{enddt}' and Busid={busid} order by Recvtime");
//clickhouse中取出來的時間預設會有時區的問題,這裡需要手動轉下本地的時區
historyModel.Histories.ForEach(u => u.termtime = DateTime.Parse(u.termtime).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"));
historyModel.Inouts.ForEach(u => u.Recvtime = u.Recvtime.ToLocalTime());
return historyModel;
}
catch (Exception e)
{
ckhelper.Dispose();
Console.WriteLine(e);
throw;
}
}
}
三、一些小問題記錄
- 時區問題
Clickhosue中取出來的時候會多8個小時,之前一度懷疑安裝時伺服器時區不對,但實際上都是正確的,只能手動將時間通過ToLocalTime轉成本地時區 - 批量插數據
批量插數據的時候如果傳入一個List的話,對應的類需要增加GetEnumerator方法,就像這樣
public class Demo
{
public string obu { get; set; }
public int busid { get; set; }
public string buscode { get; set; }
public IEnumerator GetEnumerator()
{
yield return obu;
yield return busid;
yield return buscode;
.....
}
}
- 類型統一問題
具體參考我的這篇文章 點擊跳轉
微信關註我哦!(轉載註明出處)