Skip to content

Commit

Permalink
文档更新
Browse files Browse the repository at this point in the history
  • Loading branch information
Coldairarrow committed Jul 18, 2020
1 parent df52031 commit 90ff8c1
Showing 1 changed file with 79 additions and 134 deletions.
213 changes: 79 additions & 134 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
- [按时间自动分表](#按时间自动分表)
- [性能测试](#性能测试)
- [其它简单操作(非Sharing)](#其它简单操作非sharing)
- [常用配置](#常用配置)
- [多主键支持](#多主键支持)
- [索引支持](#索引支持)
- [高级配置](#高级配置)
- [注意事项](#注意事项)
- [总结](#总结)

Expand Down Expand Up @@ -37,31 +35,30 @@
## 配置
```c#

ShardingConfig.Init(config =>
ServiceCollection services = new ServiceCollection();
//配置初始化
services.AddEFCoreSharding(config =>
{
config.AddAbsDb(DatabaseType.SQLite)
.AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, "DataSource=db.db")
.AddPhysicDbGroup()
.SetHashModShardingRule<Base_UnitTest>(nameof(Base_UnitTest.Id), 3);
//添加数据源
config.AddDataSource(Config.CONSTRING1, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.SqlServer);

//对3取模分表
config.SetHashModSharding<Base_UnitTest>(nameof(Base_UnitTest.Id), 3);
});
```
上述代码中完成了Sharding配置

- **AddAbsDb**是指添加抽象数据库,抽象数据库就是将多个分库看成同一个数据库来进行操作
- **AddPhysicDbGroup**是指添加物理数据库组,在同一组物理数据库中,它们数据库类型相同,拥有的表相同,每个数据库拥有的数据是一致的(之间通过主主复制或主从复制进行数据同步)
- **AddPhysicTable**是指添加物理数据表,传入的Base_UnitTest是抽象数据表(即将Base_UnitTest拆分为Base_UnitTest_0~2)
- **SetHashModShardingRule**是采用哈希取模的分表规则,分表字段为**Id**,取模值为**3**,会自动生成表Base_UnitTest_0,Base_UnitTest_1,Base_UnitTest_2
- **AddEFCoreSharding**注入EFCoreSharding
- **AddDataSource**添加分表数据源
- **SetHashModSharding**是采用哈希取模的分表规则,分表字段为**Id**,取模值为**3**,会自动生成表Base_UnitTest_0,Base_UnitTest_1,Base_UnitTest_2

## 使用
配置完成,下面开始使用,使用方式**非常简单**,与平常使用基本一致
首先获取分片仓储接口IShardingDbAccessor
配置完成,下面开始使用,使用方式**非常简单**,与平常使用基本一致
首先通过注入获取到IShardingDbAccessor

```c#
using(IShardingDbAccessor _db = DbFactory.GetShardingDbAccessor())
{

}
var db=ServiceProvider.GetService<IShardingDbAccessor>();
```

然后即可进行数据操作:

```c#
Expand Down Expand Up @@ -106,18 +103,16 @@ _db.Update(_newData);
//更新多条数据
_db.Update(_insertList);
//更新单条数据指定属性
_db.UpdateAny(_newData, new List<string> { "UserName", "Age" });
_db.Update(_newData, new List<string> { "UserName", "Age" });
//更新多条数据指定属性
_db.UpdateAny(_insertList, new List<string> { "UserName", "Age" });
_db.Update(_insertList, new List<string> { "UserName", "Age" });
//更新指定条件数据
_db.UpdateWhere<Base_UnitTest>(x => x.UserId == "Admin", x =>
_db.Update<Base_UnitTest>(x => x.UserId == "Admin", x =>
{
x.UserId = "Admin2";
});
//GetList获取表的所有数据
var list=_db.GetList<Base_UnitTest>();
//GetIQPagination获取分页后的数据
var list=_db.GetIShardingQueryable<Base_UnitTest>().GetPagination(pagination);
//Max
var max=_db.GetIShardingQueryable<Base_UnitTest>().Max(x => x.Age);
//Min
Expand Down Expand Up @@ -145,36 +140,44 @@ Assert.AreEqual(succcess, false);

using EFCore.Sharding;
using EFCore.Sharding.Tests;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Demo.AutoExpandByDate
namespace Demo.DateSharding
{
class Program
{
static void Main(string[] args)
static async Task Main(string[] args)
{
DateTime startTime = DateTime.Now.AddMinutes(-5);
DateTime endTime = DateTime.MaxValue;

ServiceCollection services = new ServiceCollection();
services.AddLogging(config =>
{
config.AddConsole();
});
//配置初始化
ShardingConfig.Init(config =>
services.AddEFCoreSharding(config =>
{
config.AddAbsDb(DatabaseType.SqlServer)//添加抽象数据库
.AddPhysicDbGroup()//添加物理数据库组
.AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.CONSTRING1)//添加物理数据库1
.SetDateShardingRule<Base_UnitTest>(nameof(Base_UnitTest.CreateTime))//设置分表规则
.AutoExpandByDate<Base_UnitTest>(//设置为按时间自动分表
ExpandByDateMode.PerMinute,
(startTime, endTime, ShardingConfig.DefaultDbGourpName)
);
//添加数据源
config.AddDataSource(Config.CONSTRING1, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.SqlServer);

//按分钟分表
config.SetDateSharding<Base_UnitTest>(nameof(Base_UnitTest.CreateTime), ExpandByDateMode.PerMinute, startTime);
});
var db = DbFactory.GetShardingDbAccessor();
var serviceProvider = services.BuildServiceProvider();

using var scop = serviceProvider.CreateScope();

var db = scop.ServiceProvider.GetService<IShardingDbAccessor>();
var logger = scop.ServiceProvider.GetService<ILogger<Program>>();

while (true)
{
try
{
db.Insert(new Base_UnitTest
await db.InsertAsync(new Base_UnitTest
{
Id = Guid.NewGuid().ToString(),
Age = 1,
Expand All @@ -183,17 +186,17 @@ namespace Demo.AutoExpandByDate
});

DateTime time = DateTime.Now.AddMinutes(-2);
var count = db.GetIShardingQueryable<Base_UnitTest>()
var count = await db.GetIShardingQueryable<Base_UnitTest>()
.Where(x => x.CreateTime >= time)
.Count();
Console.WriteLine($"当前数据量:{count}");
.CountAsync();
logger.LogWarning("当前数据量:{Count}", count);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

Thread.Sleep(50);
await Task.Delay(1000);
}
}
}
Expand All @@ -212,54 +215,69 @@ namespace Demo.AutoExpandByDate
```c#
using EFCore.Sharding;
using EFCore.Sharding.Tests;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;

namespace Demo.Performance
{
class Program
{
static void Main(string[] args)
{
ShardingConfig.Init(config =>
ServiceCollection services = new ServiceCollection();
services.AddEFCoreSharding(config =>
{
config.AddAbsDb(DatabaseType.SqlServer)
.AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.CONSTRING1)
.AddPhysicDbGroup()
.SetHashModShardingRule<Base_UnitTest>(nameof(Base_UnitTest.Id), 3);
});
config.UseDatabase(Config.CONSTRING1, DatabaseType.SqlServer);

//添加数据源
config.AddDataSource(Config.CONSTRING1, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.SqlServer);

DateTime time1 = DateTime.Now;
DateTime time2 = DateTime.Now;
//对3取模分表
config.SetHashModSharding<Base_UnitTest>(nameof(Base_UnitTest.Id), 3);
});
var serviceProvider = services.BuildServiceProvider();

var db = DbFactory.GetDbAccessor(Config.CONSTRING1, DatabaseType.SqlServer);
var db = serviceProvider.GetService<IDbAccessor>();
var shardingDb = serviceProvider.GetService<IShardingDbAccessor>();
Stopwatch watch = new Stopwatch();

Expression<Func<Base_UnitTest, bool>> where = x => EF.Functions.Like(x.UserName, $"%00001C22-8DD2-4D47-B500-407554B099AB%");

var q = db.GetIQueryable<Base_UnitTest>()
.Where(x => x.UserName.Contains("00001C22-8DD2-4D47-B500-407554B099AB"))
.Where(where)
.OrderByDescending(x => x.Id)
.Skip(0)
.Take(30);
var shardingQ = shardingDb.GetIShardingQueryable<Base_UnitTest>()
.Where(where)
.OrderByDescending(x => x.Id)
.Skip(0)
.Take(30);

//先执行一次预热
q.ToList();
q.ToSharding().ToList();
shardingQ.ToList();

watch.Restart();
var list1 = q.ToList();
watch.Stop();
Console.WriteLine($"未分表耗时:{watch.ElapsedMilliseconds}ms");
watch.Restart();
var list2 = q.ToSharding().ToList();
var list2 = shardingQ.ToList();
watch.Stop();
Console.WriteLine($"分表后耗时:{watch.ElapsedMilliseconds}ms");

Console.WriteLine("完成");

Console.ReadLine();
}
}
}


```

分表Base_UnitTest_0-2各有100万数据,然后将这三张表的数据导入Base_UnitTest中(即Base_UnitTest表的数据与Base_UnitTest_0-2三张表总合数据一致)
Expand All @@ -272,84 +290,11 @@ namespace Demo.Performance

## 其它简单操作(非Sharing)
框架不仅支持Sharing,而且封装了常用数据库操作,使用比较简单
详细使用方式参考 [链接](https://github.com/Coldairarrow/EFCore.Sharding/blob/master/examples/Demo.DI/Program.cs)

# 常用配置
## 多主键支持
在实体类上加上EFCore.Sharding.DataAnnotations.Keys特性即可
自动建表时会自动创建主键
```c#
/// <summary>
/// 单元测试表
/// </summary>
[Table("Base_UnitTest")]
[Index(false, nameof(CreateTime))]
[Index(false, nameof(Age))]
[Keys(nameof(Id), nameof(UserName))]
public class Base_UnitTest
{
/// <summary>
/// 代理主键
/// </summary>
[Key, StringLength(50)]
public String Id { get; set; }

/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }

/// <summary>
/// 用户名
/// </summary>
public String UserName { get; set; }

/// <summary>
/// Age
/// </summary>
public Int32? Age { get; set; }
}

```
详细使用方式参考 [链接](https://github.com/Coldairarrow/EFCore.Sharding/blob/master/src/EFCore.Sharding.Tests/DbAccessor/DbAccessorTest.cs)

## 索引支持
在实体类上加上EFCore.Sharding.DataAnnotations.Index特性即可
可以设置多个Index特性
自动建表时会自动创建索引

```c#
/// <summary>
/// 单元测试表
/// </summary>
[Table("Base_UnitTest")]
[Index(false, nameof(CreateTime))]
[Index(false, nameof(Age))]
[Keys(nameof(Id), nameof(UserName))]
public class Base_UnitTest
{
/// <summary>
/// 代理主键
/// </summary>
[Key, StringLength(50)]
public String Id { get; set; }

/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }

/// <summary>
/// 用户名
/// </summary>
public String UserName { get; set; }

/// <summary>
/// Age
/// </summary>
public Int32? Age { get; set; }
}

```
# 高级配置
多主键、索引等高级配置请使用**IEntityTypeConfiguration**
参考[fluentApi](https://www.learnentityframeworkcore.com/configuration/fluent-api)

# 注意事项

Expand Down

0 comments on commit 90ff8c1

Please sign in to comment.