FreeSql (三十一)分区分表

分区

分区就是把一个数据表的文件和索引分散存储在不一样的物理文件中。把一张表的数据分红N多个区块,这些区块能够在同一个磁盘上,也能够在不一样的磁盘上,数据库不一样实现方式有所不一样。html

与分表不一样,一张大表进行分区后,他仍是一张表,不会变成二张表,可是他存放数据的区块变多了。分区的概念,我以为就想突破磁盘I/O瓶颈,想提升磁盘的读写能力,来增长数据库的性能。sql

分区实现是比较简单的,创建分区表,根建日常的表没什么区别,而且对开发代码端来讲是透明。数据库

postgresql10以上的自动分区分表功能:服务器

一、首先建立主分区表:并发

create table fenbiao(
id int,
year varchar
) partition by list(year)

这里设置的是根据year列进行数据分表;建立后使用navicat是看不到的;高并发

2.建立分表:post

create table fenbiao_2017 partition of fenbiao for values in ('2017');
create table fenbiao_2018 partition of fenbiao for values in ('2018');

这样这两天数据会依靠规则插入到不一样分表中,若是插入一条不符合规则的数据,则会报错误:no partition of relation "fenbiao" found for row.性能

分表

分表从表面意思上看呢,就是把一张表分红N多个小表,每个小表都是完正的一张表。分表后数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。ui

分表后单表的并发能力提升了,磁盘I/O性能也提升了。并发能力为何提升了呢,由于查寻一次所花的时间变短了,若是出现高并发的话,总表能够根据不一样 的查询,将并发压力分到不一样的小表里面。日志

分库分表

分库分表把本来存储于一个库的数据分块存储到多个库上,把本来存储于一个表的数据分块存储到多个表上。

数据库中的数据量不必定是可控的,在未进行分库分表的状况下,随着时间和业务的发展,库中的表会愈来愈多,表中的数据量也会愈来愈大,相应地,数据操做,增删改查的开销也会愈来愈大;另外,一台服务器的资源(CPU、磁盘、内存、IO等)是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

FreeSql.Repository 之分表

FreeSql 提供 AsTable 分表的基础方法,GuidRepository 做为分存式仓储将实现了分表与分库(不支持跨服务器分库)的封装。

var logRepository = fsql.GetGuidRepository<Log>(null, oldname => $"{oldname}_201903");

上面咱们获得一个日志仓储按年月分表,使用它 CURD 最终会操做 Log_201903 表。

注意事项:

  • 不能使用 CodeFirst 迁移分表,开发环境时仍然能够迁移 Log 表;
  • 不可在分表分库的实体类型中使用《延时加载》;

跨表查询

var sql = fsql.Select<User>()
    .AsTable((type, oldname) => "table_1")
    .AsTable((type, oldname) => "table_2")
    .AsTable((type, oldname) => "table_3")
    .ToSql(a => a.Id);

获得SQL:

select * from (SELECT a."Id" as1 FROM "table_1" a) ftb 
UNION ALL
select * from (SELECT a."Id" as1 FROM "table_2" a) ftb 
UNION ALL
select * from (SELECT a."Id" as1 FROM "table_3" a) ftb

多表查询:

var sql = fsql.Select<User>().LeftJoin<UserGroup>((a,b) => a.UserGroupId == b.Id)
    .AsTable((type, oldname) => oldname + "_1")
    .AsTable((type, oldname) => oldname + "_2")
    .AsTable((type, oldname) => oldname + "_3")
    .ToSql(a => a.Id);

期待更多发散。。。

巧用AsTable

var sql = fsql.Select<User>()
    .AsTable((a, b) => "(select * from tb_topic where clicks > 10)")
    .Page(1, 10).ToList()

系列文章导航