在.net core中完美解决多租户分库分表的问题

前几天有人想做一个多租户的平台,每个租户一个库,可以进行水平扩展,应用端根据登录信息,切换到不同的租户库

计划用ef core实现,他们说做不出来,需要动态创建dbContext,不好实现

然而这个使用CRL很轻松就能解决了

以下为演示数据库,有两个库testdb和testdb2,查询结果如下

目标:

根据传入登录信息连不不同的库,查询返回结果,如登录人为01,返回d1.default,登录人为02 返回 d2.default

实际上这个需求就是分库分表的实现,通过设置数据库/表映射关系,根据传入的定位数据进行匹配,找到正确的库表配置,生成数据访问对象

以core控制台程序为例

class Program
    {
        static IServiceProvider provider;
        static Program()
        {
            var services = new ServiceCollection();
            services.AddCRL<DBLocationCreator>();
            services.AddScoped<Code.Sharding.MemberManage>();

            provider = services.BuildServiceProvider();
            provider.UseCRL();
        }

        static void Main(string[] args)
        {

        label1:
            var instance = provider.GetService<Code.Sharding.MemberManage>();
            var data = new Code.Sharding.MemberSharding();

            data.Code = "01";
            instance.SetLocation(data);
            var find1 = instance.QueryItem(b => b.Id > 0)?.Name;
            Console.WriteLine($"定位数据输入{data.Code},查询值为{find1}");

            data.Code = "02";
            instance.SetLocation(data);
            var find2 = instance.QueryItem(b => b.Id > 0)?.Name;
            Console.WriteLine($"定位数据输入{data.Code},查询值为{find2}");
            Console.ReadLine();
            goto label1;
        }
    }

上面代码中,通过SetLocation方法传入定位数据Code,通过QueryItem方法查询出数据并打印出来

通过services.AddCRL<DBLocationCreator>()注入定位配置,DBLocationCreator继承了接口IDBLocationCreator

这里完全符合core注入规范,可以通过配置或数据库存储动态读取定位设置

 public class DBLocationCreator : IDBLocationCreator
    {
        ISettingConfigBuilder _settingConfigBuilder;
        public DBLocationCreator(ISettingConfigBuilder settingConfigBuilder)
        {
            _settingConfigBuilder = settingConfigBuilder;
        }

        public void Init()
        {
            //自定义定位
            _settingConfigBuilder.RegisterLocation<Code.Sharding.MemberSharding>((t, a) =>
            {
                var tableName = t.TableName;
                var dbName = a.Code == "02" ? "testdb2" : "testdb";
                var dataBase = $"Data Source=.;Initial Catalog={dbName};User ID=sa;Password=123";
                //返回定位库和表名
                return new CRL.Sharding.Location(dataBase, tableName);
            });
            _settingConfigBuilder.RegisterDBAccessBuild(dbLocation =>
            {
                var connectionString = "Data Source=.;Initial Catalog=testdb;User ID=sa;Password=123";
                if (dbLocation.ShardingLocation != null)
                {
                    connectionString = dbLocation.ShardingLocation.DataBaseSource;
                }
                return new CRL.DBAccessBuild(DBType.MSSQL, connectionString);
            });
        }
    }

在Init方法里,实现了两个操作,通过RegisterLocation定义如何根据定位数据Code,返回不同的库/表

通过RegisterDBAccessBuild实现数据访问

运行测试程序,结果输出为

上面代码通过自定义定位参数和定位规则,没有任何耦合,调用也很简单,完美达到了预期效果

测试代码地址:https://github.com/CRL2020/CRL.NetStandard/tree/master/Test/CRLCoreTest

原文地址:https://www.cnblogs.com/hubro/p/12693868.html

时间: 2024-08-05 11:52:48

在.net core中完美解决多租户分库分表的问题的相关文章

水平分库分表的关键问题及解决思路

在之前的文章中,我介绍了分库分表的几种表现形式和玩法,也重点介绍了垂直分库所带来的问题和解决方法.本篇中,我们将继续聊聊水平分库分表的一些技巧. 分片技术的由来 关系型数据库本身比较容易成为系统性能瓶颈,单机存储容量.连接数.处理能力等都很有限,数据库本身的“有状态性”导致了它并不像Web和应用服务器那么容易扩展.在互联网行业海量数据和高并发访问的考验下,聪明的技术人员提出了分库分表技术(有些地方也称为Sharding.分片).同时,流行的分布式系统中间件(例如MongoDB.ElasticSe

为什么会决定进行分库分表,分库分表过程中遇到什么难题,如何解决的?

一.为什么决定进行分库分表? 根据业务类型,和业务容量的评估,来选择和判断是否使用分库分表 当前数据库本事具有的能力,压力的评估 数据库的物理隔离,例如减少锁的争用.资源的消耗和隔离等 热点表较多,并且数据量大,可能会导致锁争抢,性能下降 数据库的高并发,数据库的读写压力过大,可能会导致数据库或系统宕机 数据库(MySQL5.7以下)连接数过高,会增加系统压力 单表数据量大,如SQL使用不当,会导致io随机读写比例高.查询慢(大表上的B+树太大,扫描太慢,甚至可能需要4层B+树) 备份和恢复时间

【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)

原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_log分析 4分库分表 5子查询优化 二数据转移 21插入数据 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求.这个时候NoSQL的出现暂时解决了这一危机.它通过降低数据的安全性,减少对事务

分库分表的几种常见玩法及如何解决跨库查询等问题

在谈论数据库架构和数据库优化的时候,我们经常会听到"分库分表"."分片"."Sharding"-这样的关键词.让人感到高兴的是,这些朋友所服务的公司业务量正在(或者即将面临)高速增长,技术方面也面临着一些挑战.让人感到担忧的是,他们系统真的就需要"分库分表"了吗?"分库分表"有那么容易实践吗?为此,笔者整理了分库分表中可能遇到的一些问题,并结合以往经验介绍了对应的解决思路和建议. 垂直分表 垂直分表在日常开

Mysql中的分库分表

mysql中的分库分表分库:减少并发问题分表:降低了分布式事务分表1.垂直分表把其中的不常用的基础信息提取出来,放到一个表中通过id进行关联.降低表的大小来控制性能,但是这种方式没有解决高数据量带来的性能损耗.优点1.拆分后业务清楚,达到专库专用.2.可以实现热数据和冷数据的分离,将不经常变化的数据和变动较大的数据分散到不同的库/表里面.3.便于维护.缺点1.不能解决数据量大带来的性能损耗,读写的压力依旧很大.2.不同的业务不能夸库关联,只能通过业务关联.2.水平分表以某个字段按照一定的规则将一

水平分库分表的关键问题及解决思路(转)

分片技术的由来 关系型数据库本身比较容易成为系统性能瓶颈,单机存储容量.连接数.处理能力等都很有限,数据库本身的“有状态性”导致了它并不像Web和应用服务器那么容易扩展. 单机存储容量.连接数.处理能力等都很有限,数据库本身的“有状态性”导致了它并不像Web和应用服务器那么容易扩展. 单机存储容量.连接数.处理能力等都很有限,数据库本身的“有状态性”导致了它并不像Web和应用服务器那么容易扩展. 单机存储容量.连接数.处理能力等都很有限,数据库本身的“有状态性”导致了它并不像Web和应用服务器那

分布式中的分库分表之后,ID 主键如何处理?

面试题 分库分表之后,id 主键如何处理?(唯一性,排序等) 面试官心理分析 其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 开始累加,那肯定不对啊,需要一个全局唯一的 id 来支持,排序问题等.所以这都是你实际生产环境中必须考虑的问题. 面试题剖析 基于数据库的实现方案 数据库自增 id 这个就是说你的系统里每次得到一个 id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个 id.拿到这个 id 之后再

完美解决CodeSmith无法获取MySQL表及列Description说明注释的方案

全部代码如下: public ExtendedProperty[] GetExtendedProperties(string connectionString, SchemaObjectBase schemaObject) { List<ExtendedProperty> extendedProperties = new List<ExtendedProperty>(); if (schemaObject is ColumnSchema) { ColumnSchema column

分表需要解决的问题 &amp; 基于MyBatis 的轻量分表落地方案

分表:垂直拆分.水平拆分 垂直拆分:根据业务将一个表拆分为多个表. 如:将经常和不常访问的字段拆分至不同的表中.由于与业务关系密切,目前的分库分表产品均使用水平拆分方式. 水平拆分:根据分片算法将一个表拆分为多个表. 如:按照ID的最后一位以3取余,尾数是1的放入第1个库(表),尾数是2的放入第2个库(表)等. 解决的问题:单纯的分表可以解决数据量过大导致检索变慢的问题. 分表无法解决过多并发请求访问同一个库,导致数据库响应变慢的问题.所以通常水平拆分都至少要采用分库的方式,用于一并解决大数据量