首页 > 其他分享 >使用ShardingCore分表

使用ShardingCore分表

时间:2022-12-04 23:12:11浏览次数:67  
标签:builder EntityFrameworkCore TodoApp 使用 分表 ShardingCore public

项目环境:ABP+Mysql  

一、准备一个ABP项目

这里采用ABP的Samples中的一个样板项目TodoApp下的Mvc-EfCore 下载地址:https://github.com/abpframework/abp-samples/tree/master/TodoApp/Mvc-EfCore    

二、项目数据层切换为Mysql

ABP样板项目大多连接的是SqlServer,在这里我们需要先将数据源切换到Mysql,具体如下: 1.将TodoApp.WebTodoApp.DbMigrator项目下的appsettings.json文件里的默认数据库连接字符串替换为Mysql数据库连接字符串。 2.调整TodoApp.EntityFrameworkCore项目下的DbContext数据源 3.调整TodoApp.EntityFrameworkCore项目下的DbContextFactory数据源

4.调整TodoApp.EntityFrameworkCore项目下EntityFrameworkCore启动模块TodoAppEntityFrameworkCoreModule的数据源

 

 

 

 

三、集成ShardingCore分表功能

1.在EntityFrameworkCore项目下添加ShardingCore依赖包,目前最新版是6.6.0.27。

2.在TodoApp.Domain.Shard项目下新建两个接口IShardingKeyIsGuId,IShardingKeyIsCreationTime

用于将创建时间或Guid指定为ShardingKey,因为ShardingCore需要add,remove,update的时候shardingkey不可以为空。
namespace TodoApp
{
    public interface IShardingKeyIsGuId
    {
        
    }
}
namespace TodoApp
{
    public interface IShardingKeyIsCreationTime
    {
        
    }
}
3.创建AbpDbContext抽象类
  • abp:只要你的dbcontext继承至 public class TDbContext:AbpDbContext<TDbContext>那么就可以完美使用. 但是sharding-core的使用我们通过readme来查看发现
  • sharidng-core:只要你的dbcontext继承至public class TDbContext:AbstractShardingDbContext那么你就可以完美使用.
但c#又不是c++没有多继承那怎么办,这边其实是有一个误区的就是abp确实需要继承abpdbcontext但是sharding-core是以接口作为依赖来开发的,所以我们只需要实现ISharingDbContext 这个接口就可以,如果需要事务在实现ISupportShardingTransaction 最终我们是通过实现一个抽象基类来继承abpdbcntext并且实现sharding-core需要的接口 AbstractShardingAbpDbContext 这样我们就可以在不破坏abp的同时又兼顾了sharding-core 注意:这边sharing-core让继承AbstractShardingDbContext是因为重复写这些接口的实现会很麻烦所以写了一个抽象类方便使用 集成ShardingCore的AbpDbContext抽象类源码:https://github.com/dotnetcore/sharding-core/blob/main/samples/Samples.AbpSharding/AbstractShardingAbpDbContext.cs 直接在TodoApp.EntityFrameworkCore项目的EntityFrameworkCore下新建一个AbstractShardingAbpDbContext抽象类,并将源码里的内容全部写进来。

由于这一块代码太多,为避免占用过多篇幅,就只放其中一部分截图

4.配置DbContext类 注释掉原本继承的AbpDbContext类,改为继承AbstractShardingAbpDbContext抽象类和IShardingTableDbContext接口   5.配置表对象实体类   6.新建分表路由 由于目前的场景是只分表不分库,所以这里只需要创建分表路由,设定对TodoItem按照ID分表
using ShardingCore.VirtualRoutes.Mods;
using ShardingCore.Core.EntityMetadatas;

namespace TodoApp.EntityFrameworkCore
{
    public class TodoTableRoute:AbstractSimpleShardingModKeyStringVirtualTableRoute<TodoItem>

    {
        public TodoTableRoute() : base(2, 3)
        {
        }
 
        public override void Configure(EntityMetadataTableBuilder<TodoItem> builder)
        {
            builder.ShardingProperty(o => o.Id);
        }
    }
}
这里指定了对应的分表规则 根据ID取模分表,参数2代表后缀2位就是00-99最多100张表,3表示模3== key.hashcode() %3  

默认路由

抽象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%的规则都可以实现)   7.新建迁移数据库脚本生成类
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using ShardingCore.Helpers;
using ShardingCore.Core.RuntimeContexts;
using Pomelo.EntityFrameworkCore.MySql.Migrations;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;

namespace TodoApp.EntityFrameworkCore
{
    public class ShardingMySqlMigrationsSqlGenerator:MySqlMigrationsSqlGenerator
    {
        private readonly IShardingRuntimeContext _shardingRuntimeContext;

        public ShardingMySqlMigrationsSqlGenerator(IShardingRuntimeContext shardingRuntimeContext,
            [NotNull] MigrationsSqlGeneratorDependencies dependencies,
            [NotNull] IRelationalAnnotationProvider migrationsAnnotations,
            [NotNull] IMySqlOptions options) : base(dependencies, migrationsAnnotations,options)
        {
            _shardingRuntimeContext = shardingRuntimeContext;
        }
        
        protected override void Generate(
            MigrationOperation operation,
            IModel model,
            MigrationCommandListBuilder builder)
        {
            var oldCmds = builder.GetCommandList().ToList();
            base.Generate(operation, model, builder);
            var newCmds = builder.GetCommandList().ToList();
            var addCmds = newCmds.Where(x => !oldCmds.Contains(x)).ToList();
 
            MigrationHelper.Generate(_shardingRuntimeContext,operation, builder, Dependencies.SqlGenerationHelper, addCmds);
        }

    }
}

 

8.配置EntityFrameworkCore启动模块ShardingCore的依赖注入
public class TodoAppEntityFrameworkCoreModule : AbpModule
{
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        TodoAppEfCoreEntityExtensionMappings.Configure();
    }

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddAbpDbContext<TodoAppDbContext>(options =>
        {
            /* Remove "includeAllEntities: true" to create
             * default repositories only for aggregate roots */
            options.AddDefaultRepositories(includeAllEntities: true);
        });
        
        var configuration = context.Services.GetConfiguration();
        string mysqlconn = configuration["ConnectionStrings:Default"];

        Configure<AbpDbContextOptions>(options =>
        {
            /* The main point to change your DBMS.
             * See also TodoAppDbContextFactory for EF Core tooling. */
            options.UseMySQL();
            // options.UseSqlServer();
            
            options.Configure<TodoAppDbContext>(innerContext =>
            {
                ShardingCoreExtension.UseDefaultSharding<TodoAppDbContext>(innerContext.ServiceProvider, innerContext.DbContextOptions);
            });
        });
        
        context.Services.AddShardingDbContext<TodoAppDbContext>()
            .UseRouteConfig(op =>
            {
                op.AddShardingTableRoute<TodoTableRoute>();
            })
            .UseConfig((sp, op) =>
            {
                op.ThrowIfQueryRouteNotMatch = false;
                op.UseShardingQuery((conStr, builder) =>
                {
                    builder.UseMySql(conStr, new MySqlServerVersion(new Version()));
                });
                op.UseShardingTransaction((connection, builder) =>
                {
                    builder.UseMySql(connection, new MySqlServerVersion(new Version()));
                });
                op.UseShardingMigrationConfigure(builder =>
                {
                    builder.ReplaceService<IMigrationsSqlGenerator, ShardingMySqlMigrationsSqlGenerator>();
                });
                op.AddDefaultDataSource("ds0",mysqlconn);
                // op.AddExtraDataSource(sp =>
                // {
                //     return new Dictionary<string, string>()
                //     {
                //         {"ds1", ""},
                //         {"ds2", ""}
                //     };
                // });
            }).ReplaceService<ITableEnsureManager,MySqlTableEnsureManager>()
            .AddShardingCore();

    }
    
    public override void OnPostApplicationInitialization(ApplicationInitializationContext context)
    {
        base.OnPostApplicationInitialization(context);            //创建表的定时任务如果有按年月日系统默认路由的需要系统创建的记得开起来
        context.ServiceProvider.UseAutoShardingCreate();            
        // context.ServiceProvider.UseAutoTryCompensateTable();     //补偿表 //自动迁移的话不需要
    }
    
}

至此我们就完成了集成ShardingCore的基本配置。

 

四、数据迁移

1.清理迁移文件夹 执行数据迁移前,记得先将之前迁移文件夹下生成的同名迁移类清除掉,避免冲突,尤其是此样板项目中默认自带的是SqlServer数据库的迁移类,都需要先进行清理掉。 2.生成数据迁移类 打开Rider控制台终端,输入创建迁移类命令
dotnet ef migrations add Inital  -s  ./src/TodoApp.Web/TodoApp.Web.csproj -c TodoAppDbContext -p ./src/TodoApp.EntityFrameworkCore/TodoApp.EntityFrameworkCore.csproj
回车,等待迁移类生成,生成成功后可以在Migrations文件夹下看到两个新生成的迁移类 3.执行迁移 右键运行TodoApp.DbMigrator项目,它会自动执行迁移类进行数据迁移 迁移成功后,可以在Mysql数据库中看到新生成的TodoApp数据库和数据表,其中TodoItems表被分成了3张。 至此,数据迁移成功。  

五、运行项目测试分表功能

右键运行TodoApp.Web项目,项目运行成功界面显示如下: 输入多条内容并提交

 

 

然后可以看到数据库中的数据是分表存储

 

 

 

 

 

本文内容为作者月井石原创,转载请注明出处~

               

标签:builder,EntityFrameworkCore,TodoApp,使用,分表,ShardingCore,public
From: https://www.cnblogs.com/mooncher/p/16951145.html

相关文章

  • 远程桌面 ubuntu20使用vnc访问
     1ubuntu20开发端口安装端口管理软件sudoapt-getinstallufw关闭所有端口(如果你知道vnc都用了哪些端口,直接开发对应的,尤其是局域网端口)sudoufwdisable查看防......
  • MongoDB 的使用
    MongoDB的使用mongoDB的常见命令使用;MongoDB默认在27017端口上运行;1.常见命令#进入交互终端mongo开启云监控平台//开启云监控平台[公司一般不会允许内部信......
  • 使用torch pruning工具进行结构化剪枝
    网络结构定义importtorchimporttorch.nnasnnimporttorch.nn.functionalasFimporttorch_pruningastpfromtorchvision.datasetsimportCIFAR10fromtorchv......
  • Python 使用MongoDB & MongoDB 工具的封装
    Python使用MongoDB补充:操作之前首先在虚拟机或者服务器端启动MongoDB;#重新加载配置,并启动mongodbsudosystemctldaemon-reloadsudosystemctlstartmongod#......
  • 使用Windbg找出程序CPU高问题
    使用Windbg找出程序CPU高问题ReggieDing系统架构师​关注 1人赞同了该文章背景本人在把应用程序部署到服务器上运行,观察一段时间后运行平稳,CPU......
  • CompletionService 使用小结
    本文为博主原创,转载请注明出处:实现异步任务时,经常使用 FutureTask来实现;一个简单的示例代码如下:publicstaticvoidmain(String[]args)throwsExecutionExcept......
  • Android 开启 viewBinding,减少 findViewById 语句的使用
    找到build.gradle文件,因为有两个build.gradle,我们要操作的是第二个:在这个位置加上这一句话,然后点击右上角的SyncNow按钮更新项目:viewBinding{enabled=tr......
  • SpringBoot中使用Spring Data JPA
    Springboot中如何集成springdatajpa一什么是ORM?ORM即Object-RelationlMapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需......
  • JDK中内嵌JS引擎介绍及使用
    原文:JDK中内嵌JS引擎介绍及使用-Stars-One的杂货小窝最近研究阅读这个APP,其主要功能就是通过一个个书源,从而实现移动端阅读的体验比如说某些在线小说阅读网站,会加......
  • SpringBoot中使用Spring Data JPA
    Springboot中如何集成springdatajpa一什么是ORM?ORM即Object-RelationlMapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时......