- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C#中efcore-ShardingCore呈现“完美”分表由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
如果您对分表有以下痛点那么不妨试试我这边开源的框架sharding-core ,是否需要无感知使用分表组件,是否需要支持abp,是否需要支持自定义分表规则,是否需要支持自定义分表键,是否需要支持特定的efcore版本,是否希望框架不带任何三方框架干净,是否需要支持读写分离,是否需要动态添加表,是否需要支持join,group等操作,是否需要支持追踪特性,是否想在不修改原先代码的基础上扩展分表功能,如果一起上几个条件任意组合且你在市面上没办法找到可替代的框架可以试试本框架。如何使用代码具体可以参考github 将代码下载下来如果本地装了sqlserver直接运行单元测试或者Sample.SqlServer程序会自动在本地新建数据库新建数据库表结构,目前初始化数据为用户信息和用户对应的月薪信息表,用户表以用户id取模,用户月薪表以月份分表.
首先需要了解本框架的一个版本号不然将对您的使用产生一定的分期,目前框架分为3个版本分别是2.x,3.x,5.x3个版本,分别对应efcore 2.x efcore 3.x efcore 5.x,有人要问为什么不支持6.x呢(小弟刚刚在上周完成对本框架的开发重构,目前还未对efcore 6.x进行着手不过将在不远的将来即将支持(目测1-2个星期内)).
目前efcore生态下有着许许多多的分表、分库的解决方案,但是目前来讲都有其不足点,比如需要手动设置分表后缀、需要大量替换现有代码、不支持事务等等一系列问题,所以在这个大前提下我之前开源了sharding-core 分表组件,这个分表组件是目前来说个人认为比较“完美”的分表组件,这个分表组件目前是参考了sharding-jdbc来实现的,但是比sharding-jdbc更加强大(因为C#的表达式)。首先我们来看下目前市面上有的分表组件的缺点我们来针对其缺点进行痛点解决.
。
efcore版本 | 是否支持 |
---|---|
2.x | 支持 |
3.x | 支持 |
5.x | 支持 |
6.x | 即将支持 |
。
数据库 | 理论是否支持 |
---|---|
SqlServer | 支持 |
MySql | 支持 |
PostgreSql | 支持 |
SQLite | 支持 |
Oracle | 支持 |
其他 | 支持(只要efcore支持) |
理论上只要是efcore对应版本支持的数据库,sharding-core都将支持.
。
1.创建一个数据库对象继承IShardingTable并且在对应的分表字段上进行[ShardingTableKey]特性的标注 。
/// <summary> /// 用户表 /// </summary> public class SysUserMod : IShardingTable { /// <summary> /// 用户Id用于分表 /// </summary> [ShardingTableKey(TailPrefix = "_")] public string Id { get; set; } /// <summary> /// 用户名称 /// </summary> public string Name { get; set; } /// <summary> /// 用户姓名 /// </summary> public int Age { get; set; } }
2.创建对应的实体表对应配置 推荐 fluent api 。
public class SysTestMap:IEntityTypeConfiguration<SysTest> { public void Configure(EntityTypeBuilder<SysTest> builder) { builder.HasKey(o => o.Id); builder.Property(o => o.Id).IsRequired().HasMaxLength(128); builder.Property(o => o.UserId).IsRequired().HasMaxLength(128); builder.ToTable(nameof(SysTest)); } }
3.创建对应的分表规则 取模分表,参数2代表后缀2位就是00-99最多100张表,3表示模3== key.hashcode() %3 。
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod> { public SysUserModVirtualTableRoute() : base(2,3) { } }
4.创建对应执行的dbcontext 这一步除了继承IShardingTableDbContext外其他和普通dbcontext一样 。
public class DefaultTableDbContext: DbContext,IShardingTableDbContext { public DefaultTableDbContext(DbContextOptions<DefaultTableDbContext> options) :base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ApplyConfiguration(new SysUserModMap()); } public IRouteTail RouteTail { get; set; } }
5.添加分表dbcontext 。
public class DefaultShardingDbContext:AbstractShardingDbContext<DefaultTableDbContext> { public DefaultShardingDbContext(DbContextOptions<DefaultShardingDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ApplyConfiguration(new SysUserModMap()); } public override Type ShardingDbContextType => this.GetType(); }
6.添加配置 。
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); //原先的dbcontext可以用也可以不用如果原先的dbcontext还在用就继续 //services.AddDbContext<DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx3;Integrated Security=True")); services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>( o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;") , op => { op.EnsureCreatedWithOutShardingTable = true; op.CreateShardingTableOnStart = true; op.UseShardingOptionsBuilder( (connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),//使用dbconnection创建dbcontext支持事务 (conStr,builder) => builder.UseSqlServer(conStr).UseLoggerFactory(efLogger));//使用链接字符串创建dbcontext op.AddShardingTableRoute<SysUserModVirtualTableRoute>(); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... //添加启动项 app.UseShardingCore(); ... }public static class ShardingCoreExtension{ public static IApplicationBuilder UseShardingCore(this IApplicationBuilder app) { var shardingBootstrapper = app.ApplicationServices.GetRequiredService<IShardingBootstrapper>(); shardingBootstrapper.Start(); return app; }}
7.控制器使用 。
private readonly DefaultShardingDbContext _defaultTableDbContext; public ValuesController(DefaultShardingDbContext defaultTableDbContext) { _defaultTableDbContext = defaultTableDbContext; } [HttpGet] public async Task<IActionResult> Get() { var resultx11231 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Age == 198198).Select(o=>o.Id).ContainsAsync("1981"); var resultx1121 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "198").SumAsync(o=>o.Age); var resultx111 = await _defaultTableDbContext.Set<SysUserMod>().FirstOrDefaultAsync(o => o.Id == "198"); var resultx2 = await _defaultTableDbContext.Set<SysUserMod>().CountAsync(o => o.Age<=10); var resultx = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "198").FirstOrDefaultAsync(); var resultx33 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "198").Select(o=>o.Id).FirstOrDefaultAsync(); var resulxxt = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "198").ToListAsync(); var result = await _defaultTableDbContext.Set<SysUserMod>().ToListAsync(); var sysUserMod98 = result.FirstOrDefault(o => o.Id == "98"); _defaultTableDbContext.Attach(sysUserMod98); sysUserMod98.Name = "name_update"+new Random().Next(1,99)+"_98"; await _defaultTableDbContext.SaveChangesAsync(); return Ok(result); }
。
目前市面上有的框架要么对分表字段有限制比如仅支持DateTime类型或者int等,要么对分表规则有限制:仅支持按天、按月、取模...等等,但是基于分表规则和分表字段是业务规则所以本框架遵循将其由业务系统自己定义,最大化来实现分表库的适用性,基本上满足一切分表规则,且sharding-core目前默认提供一些常用的分表规则可以快速集成.
。
抽象abstract | 路由规则 | tail | 索引 |
---|---|---|---|
AbstractSimpleShardingModKeyIntVirtualTableRoute | 取模 | 0,1,2... | = |
AbstractSimpleShardingModKeyStringVirtualTableRoute | 取模 | 0,1,2... | = |
AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute | 按时间 | yyyyMMdd | >,>=,<,<=,=,contains |
AbstractSimpleShardingDayKeyLongVirtualTableRoute | 按时间戳 | yyyyMMdd | >,>=,<,<=,=,contains |
AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute | 按时间 | yyyyMMdd_dd | >,>=,<,<=,=,contains |
AbstractSimpleShardingWeekKeyLongVirtualTableRoute | 按时间戳 | yyyyMMdd_dd | >,>=,<,<=,=,contains |
AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute | 按时间 | yyyyMM | >,>=,<,<=,=,contains |
AbstractSimpleShardingMonthKeyLongVirtualTableRoute | 按时间戳 | yyyyMM | >,>=,<,<=,=,contains |
AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute | 按时间 | yyyy | >,>=,<,<=,=,contains |
AbstractSimpleShardingYearKeyLongVirtualTableRoute | 按时间戳 | yyyy | >,>=,<,<=,=,contains |
所谓的索引就是通过改对应的条件操作符可以缩小减少指定表的范围,加快程序的执行 如果以上默认分表无法满足您的需求您还可以自定义分表,如何分表可以通过继承 AbstractShardingOperatorVirtualTableRoute<TEntity,TKey>来实现自定义分表规则(近乎90%的规则都可以实现) 。
。
很多分表组件默认不带动态分表信息导致很多分表没办法根据业务系统来进行动态创建,sharding-core默认提供动态建表接口可以支持动态按时间,按租户等不需要数据做迁移的动态分表信息, 如果需要请参考Samples.AutoByDate.SqlServer 。
。
目前sharding-core支持select按需查询,join分表连表查询,group by聚合查询,虽然本框架支持但是出于性能原因本框架还是不建议使用join操作符来操作,因为过多的表路由会导致笛卡尔积,会导致需要查询的表集合增长对数据库连接比较考验。 以下代码来自github的单元测试中,SysUserMod表示用户表,SysUserSalary表示用户月薪表用户表按id取模,用户月薪表按月分表 。
//join查询var list = await (from u in _virtualDbContext.Set<SysUserMod>() join salary in _virtualDbContext.Set<SysUserSalary>() on u.Id equals salary.UserId select new { u.Id, u.Age, Salary = salary.Salary, DateOfMonth = salary.DateOfMonth, Name = u.Name }).ToListAsync();//group聚合查询var ids = new[] {"200", "300"}; var dateOfMonths = new[] {202111, 202110}; var group = await (from u in _virtualDbContext.Set<SysUserSalary>() .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) group u by new { UId = u.UserId } into g select new { GroupUserId = g.Key.UId, Count = g.Count(), TotalSalary = g.Sum(o => o.Salary), AvgSalary = g.Average(o => o.Salary), AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), MinSalary = g.Min(o => o.Salary), MaxSalary = g.Max(o => o.Salary) }).ToListAsync();
。
我们常说的分页是分表的难点也是最考验分表组件的 1我们首先来看普通的分表组件如何分页 首先我们定义一组组数据比如是1-100的连续数字,然后分成两张表按奇偶分表 。
表名 | 数据 |
---|---|
table1 | 1,3,5,7,9... |
table2 | 2,4,6,8,10... |
select * from table limit 2,2理论上结果3,4 如果本次查询会做落到table1 和table2那么会改写成 2句sql 第一句 select * from table1 limit 4 ---> 1,3,5,7 第二句 select * from table2 limit 4 ---> 2,4,6,8 将8条数据放入内存然后排序 1,2,3,4,5,6,7,8 获取第3到4条数据 结果[3,4] 。
这个情况是我们常见的也是最简单的分页,但是这个情况仅仅适用于数据量小的时候,如果用户不小心点到了分页的最后一页那么结果将是灾难性的这是毋庸置疑的 那么sharding-core是如何处理的呢 。
select * from table limit 2,2 首先还是一样对数据库语句进行改性并且生成对应的sql 第一句 select * from table1 limit 4 第二句 select * from table2 limit 4 因为ado.net默认DataReader是流式获取,只要连接不关闭那么可以一直实现next获取到内存 创建一个优先级队列一个可以具有排序功能的队列 因为DataReader的特性我们分别对sql1和sql2进行一次next获取到2个数组一个是[1,.....] A和数组[2......] B 获取到两个数组我们只知道头部第一个对象因为没有进行后续的next所以无法知晓剩下的数据但是有一点可以知道后面的数据都是按sql的指定顺序的所以都不会比当前头大或者小 先将1和2放入优先级队列可以知道如果asc那么数组A放在队列头 数组B放在队列尾部,然后对优先级队列进行poll弹出,并且对A进行next这个时候A变成了[3,....]再将A放入优先级队列 这时候优先级队列就是B在前A在后依次操作,然后对分页的进行过滤因为要跳过2个对象所以只需要空执行2次那么指针就会指向A数组的3和B数组的4,剩下的只要获取2个数据就可以了, 这样做可以保证内存最小化,然后分页不会成为程序的灾难.
。
目前的分表框架很少有做到无感知使用的,你在使用的时候好一点的框架不依赖三方,一般一点的不但要依赖很多三方框架并且在使用的时候还有一大堆限制,必须使用他的东西还没办法做到和dbcontext原生的使用方法。 sharding-core目前使用的是一种类似dbcontext的wrap模式,用一个新的dbcontext来包装真实的dbcontext,这个包装的dbcontext我们成为shardingdbcontext,shardingDbContext因为本身也是集成于DbContext所以它的使用方法和原生dbcontext没有差别。并且仅需少量改动即可支持abp和abp.next 。
。
目前sharding-core已经支持单node节点的读写分离操作,将在不久的未来(1-2)天内支持多节点的读写分离 。
services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o => o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"]) ,op => { op.EnsureCreatedWithOutShardingTable = true; op.CreateShardingTableOnStart = true; op.UseShardingOptionsBuilder((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger), (conStr,builder)=> builder.UseSqlServer("read db connection string").UseLoggerFactory(efLogger)); op.AddShardingTableRoute<SysUserModVirtualTableRoute>(); op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>(); });
未来计划将支持分库,支持强制路由,显示路由等... 。
最后具体如何使用且使用方式可以参考github(https://github.com/xuejmnet/sharding-core) 。
到此这篇关于efcore-ShardingCore呈现“完美”分表的文章就介绍到这了,更多相关ShardingCore“完美”分表内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://www.cnblogs.com/xuejiaming/p/15173965.html 。
最后此篇关于C#中efcore-ShardingCore呈现“完美”分表的文章就讲到这里了,如果你想了解更多关于C#中efcore-ShardingCore呈现“完美”分表的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
为了加速测试字谜字符串的快速输出行为,我 came up with基于质数的哈希方案——尽管它看起来像 I wasn't the first . 基本思想是将字母映射到素数,并计算这些素数的乘积。字母
我使用 Perfect Framework 创建了一个 Swift 3.0 服务器。一切都按预期进行得很好,但我正在尝试了解是否有更好的方法来做一些事情。 来自 iOS 背景,我知道总是在不同的线程中
我有一个固定大小的正方形 div,希望使用 CSS 在其中放置任意大小的图像,以便它在水平和垂直方向上都居中。横向很容易: .container { text-align: center } 对于垂直
程序员离不开终端,配置一个好看又好用的终端,可以提高工作效率. 本篇文章记录了使用 Oh My Zsh + PowerLevel9k + zsh插件 快速配置Ubuntu下默认终端的过程. 我们在
在请求处理程序中,处理例如获取 https://example.com/collections/1或 POSThttp://0.0.0.0:8080/collections 如何获取服务器地址 htt
我正在使用 perfect 和 SQLite司机和StORM作为连接器。我可以一一保存(创建)多行。为了使其更快,我想一次创建多行,我该怎么做? 最佳答案 从完美的 SQLite-StORM 和 Pe
这是我在这里的第一篇文章,所以我希望我提供所有正确的信息。 我目前正在开发一个简单的菜单应用程序,它有一个按钮控制数组(使用 MSDN 建议的控制数组的变通方法),我很难重新调整表单大小和将按钮居中。
在 androidplot XYPlot 中,如果您有较大的值(许多数字)和/或较大的字体大小,则 Y 轴上的刻度标签会被剪裁。这个(以及 X 轴上的类似问题)之前已经在这些问题中讨论过: Range
注意:我遗漏了不相关的代码 所以我目前正在研究 CCC 1996 P1,这个问题的全部目的是能够计算一个整数输入是完美数、不足数还是充数。我上面列出的代码可以工作,但是我认为它太慢了。该代码会迭代每个
我需要什么 我需要一个产生双射输出的算法。我有一个 31 位输入,需要一个伪随机 31 位输出。 我考虑过的 CRC 在其位宽内是双射的。 我查看了 Google 并找到了多项式,但找不到表格或算法。
我在 Ubuntu 14.04.1、clang-3.8 上使用 PerfectSwift我使用的是 Perfect,一切正常,但现在,我不能再编译了(但它可以在我的 mac 上编译) 错误日志是 /h
如果您对分表有以下痛点那么不妨试试我这边开源的框架sharding-core ,是否需要无感知使用分表组件,是否需要支持abp,是否需要支持自定义分表规则,是否需要支持自定义分表键,是否需要支持特定
我正在尝试确定我的 crc 与“ 理想 ”32 位 crc 的比较。 因此,我运行我的 crc 超过 100 万个完全随机的数据样本并收集了碰撞数量,我想将此数字与我可以从“ 理想 ”crc 中预期的
我正在开发一个项目,需要验证我的 URL,并偶然发现了以下正则表达式模式; /(((http|ftp|https):\/{2})+(([0-9a-z_-]+\.)+(aero|asia|biz|cat
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 4 年前。 Improve
我正在创建一个需要居中于中间的圆形网站。背景由围绕中心图像的圆圈组成。每当我以全屏(F11 快捷键)查看我的网站时,无论我的屏幕分辨率如何,它都完美居中。 如果我在没有全屏显示的情况下查看我的网站,我
所以我有一个网站,在开发人员工具中测试响应能力时看起来很棒,但在 iPhone 本身上实际测试时却没有居中并且看起来有些破烂。 什么会导致这种情况,如果我无法使用 iPhone(在我的 android
我有一个内部类,它扩展了 AbstractTableModel。 import javax.swing.table.AbstractTableModel; public class MyClass e
所以我正在使用 Perfect 服务器开发一个将值返回给客户端的应用程序。目前,它需要从另一个 API 下载一些数据,对其进行处理,然后将其发送给客户端。 然而,出于某种原因,它在 OSX 中编译良好
我有一些 CSS 按钮。 “按钮”效果是通过在 anchor 标记中使用固定大小的 元素来完成的,并且 css 规则以 a span:active 、 a span:hover 的形式显示按钮状态。
我是一名优秀的程序员,十分优秀!