FreeSql (三十)分区分表

时间:2019-09-17
本文章向大家介绍FreeSql (三十)分区分表,主要包括FreeSql (三十)分区分表使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

分区

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

与分表不同,一张大表进行分区后,他还是一张表,不会变成二张表,但是他存放数据的区块变多了。分区的概念,我觉得就想突破磁盘I/O瓶颈,想提高磁盘的读写能力,来增加数据库的性能。

分区实现是比较简单的,建立分区表,根建平常的表没什么区别,并且对开发代码端来说是透明。

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

1、首先创建主分区表:

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

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

2.创建分表:

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多个小表,每一个小表都是完正的一张表。分表后数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。

分表后单表的并发能力提高了,磁盘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()

$flag 上一页 下一页