我想象中“文本数据库”,再怎么简单,也得应该有以下几个的吧:
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;
}
}