分布式数据库Cachalot的使用指南

Cachalot是一个高性能的分布式数据库,适用于.NET应用程序。它具有分布式特性,能够随着节点数量的增加而线性扩展。在单个节点上,即使是在中等配置的系统上,也可以实现每秒持久化插入五万个对象。Cachalot提供了强大的LINQ支持和管理员控制台。此外,它还可以作为具有独特特性的事务性分布式缓存使用。

Cachalot的完全开源代码可以在以下地址找到:

https://github.com/usinesoft/Cachalot

预编译的二进制文件和完整文档可以在以下地址找到:

https://github.com/usinesoft/Cachalot/releases/latest

客户端代码以NuGet包的形式提供,可以在nuget.org上找到。要安装,请使用以下命令:

Install-Package Cachalot.Client

在详细介绍之前,让先展示一些代码。从一个允许个人之间出租房屋的玩具网站开始。一个简单的房地产属性描述如下:

public class Home { public string CountryCode { get; set; } public string Town { get; set; } public string Adress { get; set; } public string Owner { get; set; } public string OwnerEmail { get; set; } public string OwnerPhone { get; set; } public int Rooms { get; set; } public int Bathrooms { get; set; } public int PriceInEuros { get; set; } }

业务对象的第一个要求是必须有一个主键。在这种情况下没有“自然”的主键,所以将添加一个数值ID。

public class Home { [PrimaryKey(KeyDataType.IntKey)] public int Id { get; set; } }

现在,该对象可以存储在数据库中了。第一步是实例化一个Connector,它需要客户端配置。稍后会有更多关于配置的信息,但目前它需要包含集群中的服务器列表。首先,只运行一个本地服务器。配置通常从外部文件读取。现在,手动构建它。

var config = new ClientConfig { Servers = { new ServerConfig { Host = "localhost", Port = 4848 } } }; using (var connector = new Cachalot.Linq.Connector(config)) { var homes = connector.DataSource(); // 其余的代码在这里 }

在将对象存储到数据库之前的最后一步。需要为主键生成一个唯一值。一次调用可以生成多个唯一值。与其他数据库不同,不需要显式创建一个唯一值生成器。使用新生成器名称的第一个调用将自动创建它。

var ids = connector.GenerateUniqueIds("home_id", 1); var home = new Home { Id = ids[0], Adress = "14 rue du chien qui fume", Bathrooms = 1, CountryCode = "FR", PriceInEuros = 125, Rooms = 2, Town = "Paris" }; homes.Put(home);

现在,第一个对象已安全地存储在数据库中。目前,只能通过主键检索它。这可以通过两种等效的方式完成。

var reloaded = homes[home.Id]; // 或者使用LINQ表达式。 var reloaded = homes.First(h => h.Id == home.Id);

第一个更快,因为不需要解析表达式树。在大多数关系数据库中,使用两个不同的操作:INSERT和UPDATE。在Cachalot DB中,只暴露了一个操作:PUT。它将插入新项目(新的主键)并将更新现有项目。

可能对现代数据库有更高的期望,而不仅仅是通过主键存储和检索对象。是对的。

其他类型的索引及其使用方法

需要了解索引的三个特征。

  1. 索引数据类型
  2. 索引类型
  3. 有序索引

在Cachalot DB中,.NET属性需要可以转换为Int64或string才能被索引。使用整数类型可以使搜索稍微快一些。

自动转换为Int64提供给:所有数值类型、DateTime和DateTimeOffset、枚举类型、布尔值。转换为string是通过调用属性值的ToString()完成的。

三种类型的索引属性可用:主键(唯一强制的)、唯一键:可以在类型上定义零个或多个、索引键:可以在类型上定义零个或多个。

在任何索引上,可以应用等式运算符。如果索引声明为“有序”的,所有比较运算符都可以同样应用:<、<=、>、>=。这种类型的索引对于大多数现代系统至关重要,但要注意它有成本,因为有序索引必须始终保持排序。

大量插入/更新操作(DataStore.PutMany方法)经过良好优化。达到阈值后(默认为50项),操作将被视为“批量插入”。有序索引仅在最后排序一次。

更多代码。向房地产属性添加索引

public class Home { [PrimaryKey(KeyDataType.IntKey)] public int Id { get; set; } [Index(KeyDataType.StringKey)] public string CountryCode { get; set; } [Index(KeyDataType.StringKey)] public string Town { get; set; } public string Adress { get; set; } public string Owner { get; set; } public string OwnerEmail { get; set; } public string OwnerPhone { get; set; } [Index(KeyDataType.IntKey, ordered: true)] public int Rooms { get; set; } [Index(KeyDataType.IntKey)] public int Bathrooms { get; set; } [Index(KeyDataType.IntKey, ordered: true)] public decimal PriceInEuros { get; set; } }

使用这样索引的对象,现在可以执行一些有用的查询:

var results = homes.Where(p => p.PriceInEuros <= 200 && p.Rooms > 1 && p.Town == "Paris").Take(10);

当然,查询是在服务器端执行的,包括take运算符。通过网络发送给客户端的对象最多为十个。

“Contains”扩展方法也受到支持。

var towns = new[] { "Paris", "Nice" }; var one = homes.First(p => p.PriceInEuros < 150 && towns.Contains(p.Town));

这相当于SQL:

SELECT * from HOME where PriceInEuros < 150 and Town IN ("Paris", "Nice")

“Contains”扩展的另一个用途在传统SQL中没有等效项,将在下一节中解释。

索引集合属性

让丰富业务对象。拥有每个房屋的可用日期列表将是有用的。添加这个新属性可以启用一些有趣的功能。这是一个集合属性,可以像标量属性一样进行索引

[Index(KeyDataType.IntKey)] public List AvailableDates { get; set; } = new List();

希望能够搜索特定日期可用的房屋。

var availableNextWeek = homes.Where(p => p.Town == "Paris" && p.AvailableDates.Contains(DateTime.Today.AddDays(7))).ToList();

这在经典SQL数据库中没有直接等效项。它方便地取代了大多数经典JOIN运算符的用途。

可能需要动态创建查询。例如,在搜索屏幕中,添加标准来限制结果。这可以通过链接Where方法来完成。

var query = homes.Where(p => p.Town == "Paris"); query = query.Where(p => p.PriceInEuros < 200); query = query.Where(p => p.Rooms > 1); query = query.Where(p => p.AvailableDates.Contains(DateTime.Today)); var result = query.ToList();

这相当于一个查询,其中所有标准都使用&&(AND)运算符连接。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485