iBoxDB

e^d = Ne^(Kd)

    cos { (1/2) ( y^(1/d) + (y^(-1/d)) ( 1 - (1-y)^(2/d) ) ) }
    projection { x = x*cos( a ) + k*cos( XtoK + a ) }

双核高效应用程序数据库引擎

项目介绍

iBoxDB 是一个高能效的应用程序数据库,提供事务支持,使用数据库表的风格存取任意结构的文档对象数据,包含无须安装配置的 JAVA 与 .NET 数据库引擎。

iBoxDB 提供一个优雅设计的编程接口,让应用程序无缝地与数据引擎溶为一体, 你能方便地把它发布到移动设备, 桌面设备和服务器上, 然后让它帮助你存取各种有结构的,或者无结构的数据,具备保持数据一致性的能力。

双引擎数据库
支持   JAVA   C#   Android   Unity   Xamarin   Mono   ASP.NET   Linux

特性


示例

每个 BOX 都是一个完全隔离的独立数据空间
  using(var box = auto.Cube())
  {                            
     //select, insert, update, delete ...
     //replace()=(insert or update)
     var result = box.Commit();
  }

  try(Box box = auto.cube()){
     ...
     CommitResult r = box.commit();
  }  
Box 是本地变量,每个 Box 都是单独的事务。AutoBox 在单进程应用程序中可以用作全局变量。

普通对象操作
  box["Member"].Insert(new Member() {  
       ID=box.NewId(),
       Name = "Andy",
       Password = EncodePassowrd("123")
     }
  );

  Member m = new Member();
  m.ID = box.newId();
  m.setName("Kevin");
  box.d("Member").insert(m); 

动态列的文档数据
  //Game : Dictionary<string, object>
  game["GameType"] = "ACT";
  box["Product"].Insert(game);

  //Game extends HashMap<String,Object>
  game.put("GameType", "ACT");
  box.d("Product").insert(game);  

键-值风格的查询
  box["Table", 2L].Select<Member>();
   //支持复合键
  box["Table2", 99, "ABC"].Select<Product>();

  box.d("Table", 3L).select(Member.class);
   //支持复合键
  box.d("Table2", 88, "ABC").select(Product.class);  

复合键支持
config.ensureTable(Item.class, "Item", "UID", "Type")
iBoxDB Fast ACID NoSQL Application Database Composite Key
SQL 风格数据查询
  //from TABLE where A>? & B<=? order by C limit 0,10
  box.Select<Member>("from Member where Name==?", "MyName");
  //from [table] where [condition] 
  //                    order by [field1] desc,[field2] limit [0,10]
  //[Condition:] == != < <= > >= & | ( )
  //[IFunction:] =[F1,F2,F3]
  box.select(Member.class, "from Member where Name==?", "MyName"); 
查询
  box.Select("from Member");  
查询选项
  //先加载到内存,使用 “*”.
  //因为操作系统有预读,这选项一般不需要, 
  box.Select("*from Member");
  //查询追溯 使用 “!”.
  box.Select("!from Member");  

弱类型支持
  //使用强类型
  box.select("from Table where Id > ?" , 1L);
  //使用弱类型
  box.select("from Table where Id > ?" , new Variant("1")); 

支持索引提升查询速度,平均快一百倍
  //索引
  config.EnsureIndex<Member>("Member", "Field1")
  config.ensureIndex(Member.class, "Member", isUnique,"Field1")
  //复合索引
  config.EnsureIndex<Member>("Member", "Field1","Field2")
  config.ensureIndex(Member.class, "Member", isUnique,"Field1","Field2")
 //两种索引都可以加速查询,随意选择.
 //但一个查询只会加载一个索引, 
 //同时使用两个会产生浪费.
 //一般索引已经足够快.
 //复合索引一般用于关联表主键,两个条件相等的情况
  box.Select("from Member where Field1 == ? & Field2 == ?",arg1,arg2)

  //Id 在左边一般会更快
  box.Select("from Member where Id == ? & Field == ?",id,arg)

  //主键同时也是主索引,可以创建复合索引包含主键
  //但主键是唯一的,所以第二个字段一般很少用到
  config.EnsureIndex(..., "Id","Field")
  //交换顺序在一些情况下可能有用
  config.EnsureIndex(..., "Field","Id")
  //具体可查看数组比较的方法
  //键值数据库一定有主键

  //合并结果会比 OR 条件更快,
  //取决于数据集的大小与索引设置.	
  //where Id == ? | Id == ? | Id == ?
  foreach(var id in [ 1, 2, 3 ])
    combiner.Add( box.Select("from Member where Id == ?",id) )

自定义查询函数
  box.Select<Member>("from Member where [Tags]", new IFunction("Value"));

自定义表-对象绑定
  public bool Insert(Member m){
    return auto.Insert(nameof(Member), m);
  }

兼容 LINQ (.NET)
  from o in box.Select<Class>("from Class")
  where o.Text.Contains(text)
  select o;

兼容 Stream (Java8)
  StreamSupport.stream(db.select("from Table").spliterator(), true)
  .collect(Collectors.groupingBy((l) -> l.get("GroupID"),
   Collectors.summingLong((l) -> (Long) l.get("Value"))));

Ason 和 原型对象
  //定义原型, Id 是 Long		
  Ason prototype = new Ason("Id:", 0L, "Name:", "Guest");

  Ason record = prototype.select();
  //设置 Id 为 String,
  record.set("Id", "123");
  //自动转为定义原型的 Long
  System.out.println("Output: " + record.get("Id").getClass());
  //输出: class java.lang.Long

数据库热备份
  auto.GetDatabase().CopyTo(bakAddr, bakRoot, buffer) 

快读查询
  //从小文件中直接查询数据,
  //不用启动数据库引擎                   
  IEnumerable records = DB.Select(fileAddress) 

事务抱团
  //三个事务一起提交
  long huggersBuffer = 1024L * 1024L * 32L;                   
  box1.Commit(huggersBuffer);
  box2.Commit(huggersBuffer);
  box3.Commit(); 

可编程热同步,下载文件了解详细内容
  //主-主
  BoxData.masterReplicate();  
  //主-从
  BoxData.slaveReplicate();

更新自增
作用域 触发条件 数据类型 数据来源
更新自增 索引 插入/更新 长整数 Database NewId (MaxPos,1)
主键自增 主键 插入 数字 Table Max (ID)+1

查询追溯
线程 用法
查询追溯 不阻塞 读写不同的数据行
数据锁 阻塞 读写同一数据行

Snapshot-Serializable 两级事务
程序区域 隔离级别
应用程序 Snapshot
数据库 Serializable
using(var box = auto.Cube()){
  //Snapshot...
  box.Commit( ()=>{
    //Serializable...  
  }); 
}

数据持久层
IO
 BoxFileStreamConfig
 BoxMemoryStreamConfig
 ReadonlyStreamConfig
 CacheStreamConfig 

数据库路径设置
C# & JAVA,  把数据库文件放到项目工作目录外会有更好性能
//在虚拟机里,不同的路径有很大的读写速度差别.
//先创建目录,再放入数据库.
//new File(path).mkdirs(); 
//Directory.CreateDirectory(path)
iBoxDB.LocalServer.DB.Root("/data/"); 
扫描软件中把数据库根目录设置为例外,可以加快读写速度

ASP.NET Cross Platform
iBoxDB.LocalServer.DB.Root(MapPath("~/App_Data/"));

Xamarin
iBoxDB.LocalServer.DB.Root(System.Environment.GetFolderPath( 
       System.Environment.SpecialFolder.Personal));

Unity3D
iBoxDB.LocalServer.DB.Root(Application.persistentDataPath);

Android
iBoxDB.LocalServer.DB.root(android.os.Environment.getDataDirectory()
       .getAbsolutePath() + "/data/" + packageName + "/"); 

JSP WebApplication
@WebListener()
public class StartListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
       String path = System.getProperty("user.home") + "/data/"; 
       new File(path).mkdirs();   
       iBoxDB.LocalServer.DB.root(path); 
    }
} 

Godot
<PackageReference Include="iBoxDB" Version="" />  
var dir = Godot.OS.GetUserDataDir();
dir = Path.Combine(dir, "DBROOT");
Directory.CreateDirectory(dir);
DB.Root(dir)

jMonkeyEngine
File dir = JmeSystem.getStorageFolder(StorageFolderType.Internal);
dir = new File(dir, "ProjectName");
dir = new File(dir, "DatabaseName");
dir.mkdir();       
DB.root(dir.getAbsolutePath()); 

快速入门   C# and JAVA
 using IBoxDB.LocalServer;

 var db = new DB();
 db.GetConfig().EnsureTable<Record>("Table", "Id");
 AutoBox auto = db.Open();

 auto.Insert("Table", new Record { Id = 1L, Name = "Andy" });
 var record = auto.Get<Record>("Table", 1L);
 record.Name = "Kelly";
 auto.Update("Table", record);
 auto.Delete("Table", 1L);  

 import iboxdb.localserver.*;

 DB db = new DB();
 db.getConfig().ensureTable(Record.class, "Table", "Id");
 AutoBox auto = db.open();

 auto.insert("Table", new Record(1L, "Andy"));
 Record record = auto.get(Record.class, "Table", 1L);
 record.Name = "Kelly";
 auto.update("Table", record);
 auto.delete("Table", 1L);  

内存使用
 DatabaseConfig cfg = db.getConfig();
 //缓存,小于三分一总内存
 cfg.CacheLength = cfg.mb(1024L);
 //移动设备 64MB 
 cfg.CacheLength = cfg.mb(64L);
 //读线程, 在小缓存机器中设置 8+
 cfg.ReadStreamCount = 8;
 //写线程, 在小缓存机器中设置 4- 或者 1
 cfg.WriteStreamCount = 1;

安装使用
.NET: 在项目中引用 NETDB/iBoxDB.DLL  
Java: 在项目中引用 JavaDB/iBoxDB.jar 

与 MySQL 的性能参照
iBoxDB
 Insert: 1,000,000 AVG: 47,016 objects/s 
 Update: 1,000,000 AVG: 25,558 objects/s 
 Delete: 1,000,000 AVG: 42,714 objects/s 

MySQL
 Insert: 1,000,000 AVG: 5,514 objects/s 
 Update: 1,000,000 AVG: 5,109 objects/s 
 Delete: 1,000,000 AVG: 6,044 objects/s 

数据类型支持
.NET JAVA
 bool
 char
 byte
 sbyte
 short 
 ushort
 int
 uint
 long
 ulong
 float
 double
 decimal
 DateTime
 Guid
         
 bool? 
 char? 
 byte? 
 sbyte? 
 short?
 ushort? 
 int? 
 uint? 
 long? 
 ulong?
 float? 
 double? 
 decimal?
 DateTime?
 Guid? 
 string 
       
 //non indexable
 Dictionary
 <string, object>
 MemoryStream
 byte[]
 string[]
  
 boolean 
 Boolean
 byte 
 Byte
 char 
 Character
 short 
 Short
 int 
 Integer
 long 
 Long
 float
 Float
 double
 Double
 UUID
 Date

 //dynamic length
 BigDecimal
 BigInteger
 String
 
 //non indexable
 HashMap
 <String, Object>
 MemoryStream
 byte[]
 Object[]










ORM
//Name
*.Name

//name
*.name




//Name
*.Name
*.Name(val)
*.setName(val)

//name
*.name
*.name(val)
*.setname(val)
 DatabaseConfig cfg;
 //创建表
 ensureTable(Record.class, "Table", "Id");
 //创建长度为 32 的索引
 ensureIndex(Record.class, "Table", "Name(32)");

 //如果要索引 byte[] 或其它, 
 //使用 ToBase64String(byte[]) 转换为字符串 String. 

.NET AOT 注册类型
 public static object Register
  <[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>() 
  where T : new()
 {
   return new T();
 }
 //触发 DynamicallyAccessedMemberTypes.All
 Register<T1>();
 EnsureTable<T1>("T1", "Id"); 

全平台支持
iBoxDB Fast Transactional NoSQL Application Database For Java, .Net, Android, Windows Phone, Mono, Unity3D, Xamarin, Linux, Windows