using System;
2 using System.Collections.Generic;
3
4 namespace STSDB
5 {
6 [Serializable]
7 public class TStudent
8 {
9 public TStudent()
10 {
11 }
12 public string Name {
get;
set; }
13 public int Age {
get;
set; }
14 public int GroupNumber {
get;
set; }
15 public List<TCourse> CourseList {
get;
set; }
16 }
17 }
18 using System;
19
20 namespace STSDB
21 {
22 [Serializable]
23 public class TCourse
24 {
25 public string CourseName {
get;
set; }
26 public string Teacher {
get;
set; }
27 public int Score {
get;
set; }
28 }
29 }
30 演示代码:
31 /*
32 * 1. STSdb 4.0 是一个开源的NoSQL 数据库和虚拟文件系统,支持实时索引,完全用c#开发的。
33 * 引擎原理基于WaterfallTree(瀑布树)数据结构搭建
34 *
35 *
36 * 2.特性
37 * 支持几十亿级别的数据存取
38 * 支持TB级别文件大小
39 * 实时索引
40 * 内置压缩
41 * 内置序列化
42 * 支持稀疏分散的文件(byte[])
43 * 存储内存可控
44 * 支持多线程,且线程安全
45 * Storage engine instance is thread-safe. Creating (opening) XTable and XFile instances in one storage engine from
46 different threads is thread-safe.
47 XTable and XFile instances are also thread-safe. Manipulating different XTable/XFile instances from different threads
48 is thread-safe.
49 *
50 * 3.缺点
51 * 不支持事务
52 * 同时处理所有打开的表
53 *
54 * 支持多种情况下的数据引擎连接
55 IStorageEngine engine = STSdb.FromMemory(); //从内存中读取
56 IStorageEngine engine = STSdb.FromStream(stream); //从数据流中读取
57 IStorageEngine engine = STSdb.FromHeap(heap); //从堆栈中读取
58 IStorageEngine engine = STSdb.FromNetwork(host, port); //从远程地址读取
59
60 *
61 *
62 */
63
64 using System;
65 using System.IO;
66 using System.Linq;
67 using System.Collections.Generic;
68
69 namespace STSDB
70 {
71 using Newtonsoft.Json;
72 using STSdb4.Data;
73 using STSdb4.Database;
74 using STSdb4.Storage;
75 using STSdb4.WaterfallTree;
76 using STSdb4.Remote.Heap;
77
78 class Program
79 {
80 static void Main(
string[] args)
81 {
82 ExecuteCode(WriteData);
83 ExecuteCode(ReadData);
84 //ExecuteCode(DatabaseSchemeInfo);
85
86 //ExecuteCode(ReadItem);
87 //ExecuteCode(DeleteItems);
88 //ExecuteCode(ReadItem);
89
90 //ExecuteCode(GetRecord);
91 //ExecuteCode(PageRecord);
92
93 //ExecuteCode(Others);
94 //ExecuteCode(ReNameTable);
95
96 //ExecuteCode(ExistsTable);
97 //ExecuteCode(DeleteTable);
98 //ExecuteCode(ExistsTable);
99
100 #region test
101 //bool quit = false;
102 //while (!quit)
103 //{
104 // Console.Write("get item data: ");
105 // string demo = Console.ReadLine();
106 // switch (demo)
107 // {
108 // case "Y":
109 // break;
110 // case "Q":
111 // quit = true;
112 // break;
113 // default:
114 // Console.WriteLine("Choose a Word between Y and Q(to quit)");
115 // break;
116 // }
117 //}
118 #endregion
119
120 Console.ReadKey();
121 }
122 /// <summary>执行方法</summary>
123 static void ExecuteCode(Action act)
124 {
125 System.Diagnostics.Stopwatch stopwatch =
new System.Diagnostics.Stopwatch();
126 stopwatch.Start();
127
128 act();
129
130 stopwatch.Stop();
131 TimeSpan timespan =
stopwatch.Elapsed;
132
133 Console.WriteLine(
"运行{0}秒", timespan.TotalSeconds);
134 }
135
136 /// <summary>
137 /// 数据库名
138 /// </summary>
139 /// <remarks>文件名和扩展名不限制</remarks>
140 protected static string DataBase =
"ClassDB.db";
141 /// <summary>
142 /// 学生表名
143 /// </summary>
144 protected static string TableName =
"tb_student";
145 /// <summary>
146 /// 【新】学生表名
147 /// </summary>
148 protected static string NewTableName =
"new_tb_student";
149 /// <summary>
150 /// XFile
151 /// </summary>
152 protected static string XFileName =
"tb_file";
153
154 #region 基本操作
155 /// <summary>
156 /// 创建库,写入数据
157 /// </summary>
158 static void WriteData()
159 {
160 /*
161 * ①:没有数据库会自动创建的,默认目录和应用程序目录一致;
162 * ②:打开表,Key支持组合结构 => OpenXTable<TKey, TRecord>
163 */
164 using (IStorageEngine engine = STSdb.FromFile(DataBase))
//①
165 {
166 var table = engine.OpenXTable<
int, TStudent>(TableName);
//②
167 //var table2 = engine.OpenXTable<TKey, TTick>("table2"); //支持key嵌套
168 for (
int i =
0; i <
1000; i++
)
169 {
170 table[i] =
new TStudent
171 {
172 Name =
"Jon_" +
i.ToString(),
173 Age =
new Random().Next(
25,
30),
174 GroupNumber = i + (
new Random().Next(
310,
399)),
175 CourseList =
new List<TCourse>
()
176 {
177 new TCourse{
178 CourseName=
"C#高级编程"+
i.ToString(),
179 Teacher=
"老陈"+
i.ToString(),
180 Score=
80
181 },
182 new TCourse{
183 CourseName=
"C#函数式程序设计"+
i.ToString(),
184 Teacher=
"老李"+
i.ToString(),
185 Score=
90
186 },
187 new TCourse{
188 CourseName=
"多线程实战应用"+
i.ToString(),
189 Teacher=
"老张"+
i.ToString(),
190 Score=
95
191 },
192 }
193 };
194 }
195 engine.Commit();
196 }
197 }
198 /// <summary>
199 /// 读取数据
200 /// </summary>
201 static void ReadData()
202 {
203 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
204 {
205 var table = engine.OpenXTable<
int, TStudent>(TableName);
//ITable:IEnumerable对象
206 foreach (
var item
in table)
207 Console.WriteLine(JsonConvert.SerializeObject(item, Newtonsoft.Json.Formatting.Indented));
208
209 Console.WriteLine(table.Count());
//TableName表中有100行数据
210 }
211 }
212
213 /// <summary>
214 ///
215 /// </summary>
216 static void DatabaseSchemeInfo()
217 {
218 using (IStorageEngine engine = STSdb.FromFile(DataBase))
//①
219 {
220 IDescriptor descriptor =
engine[TableName];
221 Console.WriteLine(descriptor.CreateTime.ToString(
"yyyy-MM-dd HH:mm:ss"));
222 Console.WriteLine(descriptor.ModifiedTime.ToString(
"yyyy-MM-dd HH:mm:ss"));
223 Console.WriteLine(descriptor.Name);
224 //ID是表的唯一标识id,表一旦创建,它就创建了,后面只要表在就不会修改
225 //重建表它会从新分配
226 Console.WriteLine(descriptor.ID);
227
228 //...
229 }
230 }
231
232 /// <summary>
233 /// 读取单条数据
234 /// </summary>
235 static void ReadItem()
236 {
237 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
238 {
239 var table = engine.OpenXTable<
int, TStudent>(TableName);
//ITable: IEnumerable对象
240 //var item = table.FirstOrDefault(x => x.Key <= 15 && x.Key >= 10); //key是5的记录
241 //table[10];
242 var item = table.FirstOrDefault(x => x.Key ==
5);
//key是5的记录
243 if (item.Value !=
null)
244 Console.WriteLine(JsonConvert.SerializeObject(item, Newtonsoft.Json.Formatting.Indented));
245 else
246 Console.WriteLine(
"key = 5 的记录不存在!");
247 //Console.WriteLine("10<= key <= 15 的记录不存在!");
248 }
249 }
250
251 static void AddItems()
252 {
253 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
254 {
255 var table = engine.OpenXTable<
int, TStudent>
(TableName);
256 //table[100] = new TStudent(){....};
257 table.InsertOrIgnore(
2,
new TStudent());
258
259 engine.Commit();
260 }
261 }
262
263 /// <summary>
264 /// 删除表数据
265 /// </summary>
266 static void DeleteItems()
267 {
268 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
269 {
270 var table = engine.OpenXTable<
int, TStudent>(TableName);
//ITable:IEnumerable对象
271 if (table !=
null)
272 {
273 //table.Clear(); //清空表数据
274 table.Delete(
5);
//删掉key是5的记录
275 //table.Delete(10, 15); //删掉key从10到15的记录
276 engine.Commit();
//提交操作,不能少
277 }
278 }
279 }
280
281 /// <summary>
282 /// 按需获取数据
283 /// </summary>
284 static void GetRecord()
285 {
286 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
287 {
288 /*
289 Forward向前读取, Backward向后读取, 它们都有2个重载,下面重点说明第二个重载
290 * Forward(TKey from, bool hasFrom, TKey to, bool hasTo);
291 * Backward(TKey to, bool hasTo, TKey from, bool hasFrom);
292 * 超出范围的都不会排除,另外,查询范围超出也不会有影响,但是要注意一点,formkey和endkey的大小关系
293 *
294 * 0<----------[(S)]----------------[(E)]------------->N
295 *
296 */
297 var table = engine.OpenXTable<
int, TStudent>
(TableName);
298 var fiterTB = table.Forward(
2,
true,
9,
true);
//索引从2到9
299 //var fiterTB = table.Forward(2, false, 9, true); //索引从0到9
300 //var fiterTB = table.Forward(2, false, 9, false); //索引从0到表结尾
301 //var fiterTB = table.Forward(2, true, 9, false); //索引从2到表结尾
302 //Backward刚好相反
303 foreach (
var item
in fiterTB)
304 Console.WriteLine(JsonConvert.SerializeObject(item, Newtonsoft.Json.Formatting.Indented));
305 }
306 }
307 /// <summary>
308 /// 数据分页
309 /// </summary>
310 static void PageRecord()
311 {
312 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
313 {
314 int pageIndex =
2;
315 int pageSize =
10;
316
317 var table = engine.OpenXTable<
int, TStudent>
(TableName);
318 var fiterTB = table.Skip(pageSize * (pageIndex -
1)).Take(pageSize);
319 foreach (
var item
in fiterTB)
320 Console.WriteLine(JsonConvert.SerializeObject(item, Newtonsoft.Json.Formatting.Indented));
321 }
322 }
323 /// <summary>
324 /// 文件数和记录数
325 /// </summary>
326 static void Others()
327 {
328 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
329 {
330 //表和虚拟文件的数量
331 Console.WriteLine(
"数据库 " + DataBase +
" 中有 {0} 张表:{1}", engine.Count, TableName);
332
333 //表记录数
334 var table = engine.OpenXTable<
int, TStudent>
(TableName);
335 Console.WriteLine(
"表" + TableName +
"中有" + table.Count() +
"条记录");
336 }
337 }
338
339 /// <summary>
340 /// 表是否存在
341 /// </summary>
342 static void ExistsTable()
343 {
344 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
345 {
346 //判断表存在与否
347 //bool exists = engine.Exists(NewTableName);
348 //Console.WriteLine(NewTableName + " exist?=>{0}", exists.ToString());
349
350 bool exists =
engine.Exists(TableName);
351 Console.WriteLine(TableName +
" exist?=>{0}", exists.ToString());
352 }
353 }
354
355 /// <summary>
356 /// 重命名表名
357 /// </summary>
358 static void ReNameTable()
359 {
360 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
361 {
362 //判断表存在与否
363 bool exists =
engine.Exists(TableName);
364 Console.WriteLine(TableName +
" exist? =>{0}", exists.ToString());
365
366 //表重命名
367 engine.Rename(TableName, NewTableName);
368 Console.WriteLine(
"表" + TableName +
"被重命名为:" +
NewTableName);
369
370 if (engine.Exists(TableName))
371 Console.WriteLine(
"old table name \"" + TableName +
"\" exist");
372 if (engine.Exists(NewTableName))
373 Console.WriteLine(
"new table name \"" + NewTableName +
"\" exist");
374 }
375 }
376 /// <summary>
377 /// 删除表
378 /// </summary>
379 static void DeleteTable()
380 {
381 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
382 {
383 //删除表
384 engine.Delete(TableName);
385 //engine.Delete(NewTableName);
386 engine.Commit();
387 }
388 }
389 #endregion
390
391 #region XFile
392
393 static void TestXFile()
394 {
395 using (IStorageEngine engine =
STSdb.FromFile(DataBase))
396 {
397 XFile file =
engine.OpenXFile(XFileName);
398
399 Random random =
new Random();
400 byte[] buffer =
new byte[] {
1,
2,
3,
4,
5,
6,
7,
8,
9,
10 };
401
402 for (
int i =
0; i <
100; i++
)
403 {
404 long position =
random.Next();
405
406 file.Seek(position, SeekOrigin.Begin);
407 file.Write(buffer,
0, buffer.Length);
408 }
409 engine.Commit();
410 }
411 }
412 //XFile uses special XTable<long, byte[]> implementation to provide effective sparse file functionality.
413 //One storage engine can have many files
414 #endregion
415
416 #region Client/Server
417
418 static void ClientUpdateData()
419 {
420 using (IStorageEngine engine = STSdb.FromNetwork(
"localhost",
7182))
421 {
422 ITable<
int,
string> table = engine.OpenXTable<
int,
string>(
"table");
423 for (
int i =
0; i <
100000; i++
)
424 {
425 table[i] =
i.ToString();
426 }
427 engine.Commit();
428 }
429 }
430
431 static void ServerHandleData()
432 {
433 string _dbname =
"test.stsdb4";
434 using (IStorageEngine engine =
STSdb.FromFile(_dbname))
435 {
436 var server = STSdb.CreateServer(engine,
7182);
437 server.Start();
438 //server is ready for connections
439 //server.Stop();
440 }
441 }
442 //The created server instance will listen on the specified port
443 //and receive/send data from/to the clients
444
445 #endregion
446
447 #region Memory Usage
448 /*
449 min/max children (branches) in each internal (non-leaf) node
450 max operations in the root node
451 min/max operations in each internal node
452 min/max records in each leaf node
453 number of cached nodes in the memory
454 */
455 static void MemoryUsageHandle()
456 {
457 using (StorageEngine engine =
(StorageEngine)STSdb.FromFile(DataBase))
458 {
459 //