我想象中“文本數據庫”,再怎么簡單,也得應該有以下幾個的吧:
1:有存儲結構[表結構]
2:有主鍵ID,不是GUID時,咋也得整個自增ID吧(大伙的應用習慣)。
3:能添加,修改,刪除數據。
4:最好還能查詢,排序,分頁,至于分組可能要求高了點。
5:再最好有并發控制。
復制代碼
回頭再看秋色園 QBlog 當前的應用是:
1:文本存儲的內容少:1個文本存的不是表,基本是1行(偶爾多行)。
2:基于第1點,只能說是文本的讀取應用,和“數據庫”還扯不上關系。
復制代碼
故從以上目前的應用來說,完全達不到文本數據庫應用的境界。
當然,有了基于文本的應用,故而順理成章的對文本擴展出的“文本數據庫”產生了些許興趣與沖動也就很自然了。
于是,我上網搜了一下“文本數據庫”,發現.net界幾乎沒有它的身影,倒是曾在php界大放過異采,這是為什么呢?
這是為什么呢?估計是為了以下內容:
用文本當數據庫的基本優勢:
1:簡單的文本操作速度比數據庫快:
非要解釋,我只能這么說:大伙都存的磁盤,直接存肯定比數據庫繞了一定的存儲結構規則后存的快,當然越往后越復雜,就不好說了。
2:存取操作簡單:
不用啥ADO.NET,直接System.IO.File就可以搞定,多省事啊!
復制代碼
用文本當數據庫的基本劣勢:
1:數據量不適合大。
2:并發似乎不太好
3:刪除與修改不好操作
4:要變身成“文本數據庫”有好多要事要處理:
a:這自增加ID咋出來啊?
b:這要查詢咋整啊?
c:這要排序咋整啊?
復制代碼
用文本數據庫的基本適用的應用場景:
1:小型應用,以文本為主數據庫:
單個(表)文本數據量不大:10萬條數據以下,10M大小以下(一次性加載到內存中操作,就成了內存數據庫了,速度嘩啦啦)。
2:大型應用,以文本為輔數據庫:
通過將一些數據庫分散到零散的文本中,降低主數據庫的壓力。
3:中型應用,以文本為主數據庫:
這個不好說,說不好,不說好,需要有一定強力的技術陣容支持。
復制代碼
為了更好的發揮“文本數據庫”的能動性,本人花了些時間對其進行了些許研究及思考,下面和大伙分享一下經驗:
1:存儲結構
這個我從秋色園 QBlog 的文本應用中得到提示,存成json,挺好的呀,這不json都流行的么,直接讀取傳到前端,愛干啥干啥!
所以這里的技術點是:如何輸出json和讀取json解析。
這里:CYQ.Data V3.0 框架開源版本(下載)里有一個JsonHelper,能把數據生成Json,也能把json字符串解析成KeyValue鍵值對應,感興趣的可去研究。
于是,基本讀與取就解決了。
復制代碼
2:數據插入
使用:System.IO.File.AppendAllText就可以輕松把一行的json加到文本的末尾中。
3:更新、刪除
這兩個操作幾乎是差不多,個人想到的兩種方式:
方式一:簡單型 [這個其實挺好,因此從文本數據庫的應用場景上看,基本要求并不是太高]
將整個表的重新輸出json,再重寫一次文本就可以了。
方式二:復雜型[這個是性能考慮的多一些,對于文本數據庫追求的過些過了一點,因為如果太復雜,何不找其它數據庫,用文本不就圖個簡單么]
這個比較痛苦,這里也給出一點個人的思路想法:
1:定表結構時,必須定好每個字段的長度,這樣就定出一行總的最大長度。
2:寫一行數據時,不夠總長時,后面補空(好像通常是寫入\0)。
3:更新或刪除時,根據行的(ID-1)*總長,定位到起始寫的位置,然后改寫一行即可,如果是刪除則當行全寫空(\0)。
這里其實就是空間換時間,而且數據刪除時,文本大小也沒變化,是不是有點像access呢?
復制代碼
針以上面方式二,這里給出點示例代碼:
FileStream fs = File.Open(文件路徑);
fs.Seek(定位要寫入的開始位置, SeekOrigin.Current);
fs.Write(..寫入內容...);
fs.Close();
復制代碼
4:自增ID咋出來
增加ID還是比較容易,讀取文本最后一行的首字段的值+1就出來了,當然僅適合于數字型的了,然后全局緩存,每次讀取++。
復制代碼
下面給出一個參考的示例代碼:
///
/// 下一個自增加ID
///
private int NextID
{
get
{
lock (lockNextIDobj)
{
if (maxID > 0)
{
maxID++;
}
else if (DataType.GetGroupID(Table.Columns[0].SqlType) == 1)//自增ID僅對int有效
{
if (Table.Rows.Count > 0)
{
int lastIndex = _Table.Rows.Count - 1;
do
{
if (lastIndex >= 0)
{
if (_Table.Rows[lastIndex][0].IsNull)
{
lastIndex--;
}
else
{
maxID = Convert.ToInt32(_Table.Rows[lastIndex][0].Value) + 1;
}
}
原文轉自:http://www.anti-gravitydesign.com