sharding-core icon indicating copy to clipboard operation
sharding-core copied to clipboard

按需自动建分表

Open Im-Kevin opened this issue 3 years ago • 33 comments

我现在有个需求,需要按小时建表,但是又不是说建满24小时,大概其中有10个小时是有数据的,其他时间都是没数据的,所有想在新增的时候处理如果没有表则建表,查询的时候就直接跳过

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

可以的我晚上写一个路由,大概是不是分表按小时后缀,没表创建表,查询跳过什么意思不太清楚什么意思

xuejmnet avatar May 10 '22 10:05 xuejmnet

@Im-Kevin 再说下你是mysql还是sqlserver

xuejmnet avatar May 10 '22 10:05 xuejmnet

mysql

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

就比如我查询9号10号的数据,那么每天10个小时有数据,就是只有20个表,剩下28个小时都是没有对应的表的,那么实际查询应该只是查询了20个表

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

我们这个只有白天才有数据的,晚上是不会有数据插入的

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

这种如果创建那28个空表,查询效率就会受到一定的影响

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

可以的

xuejmnet avatar May 10 '22 10:05 xuejmnet

好的,感谢

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

这边建议是升级到新版本就版本建表是阻塞的并且有点小bug

xuejmnet avatar May 10 '22 10:05 xuejmnet

好的,新版本建表不阻塞?那其他数据怎么办

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

只是建表方法不阻塞原先需要模型从建新版本不需要了所以不会阻塞性能更好

xuejmnet avatar May 10 '22 10:05 xuejmnet

不是很理解

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

原先是这样的,首先efcore没有提供创建指定表的功能,只是提供了创建所有表的功能,但如果已存在就会报错,原先的处理是先获取当前efcore的模型缓存锁,然后把所有模型都删除掉只要我需要创建表的模型,然后创建完表后把整个模型删除,不然当前efcore模型只有一张表了。现在是创建dbcontext然后这个dbcontext的模型不写入模型缓存,也就是说不需要lock模型锁,然后和上述一样移除掉别的表剩一张我要的模型然后建表,因为模型独立不缓存所以不会影响别的dbcpntext下的模型自然而然不需要lock所以是无锁

xuejmnet avatar May 10 '22 10:05 xuejmnet

明白了,感谢解惑

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

原先是操作全局模型,lock,移除所有模型保留一个模型,调用创建所有表的方法,移除模型,释放锁

现在是独立创建dbcontext使用独立模型,然后设置模型不需要缓存,移除模型保留一个,创建所有表,释放dbcontext就可以了因为独立模型不会缓存

xuejmnet avatar May 10 '22 10:05 xuejmnet

Im-Kevin avatar May 10 '22 10:05 Im-Kevin

@Im-Kevin 源码已经上传 image

xuejmnet avatar May 10 '22 13:05 xuejmnet

Sample.AutoCreateIfPersent,通过对路由值的获取进行判断是否需要创建表,来达到功能实现

xuejmnet avatar May 10 '22 13:05 xuejmnet

启动程序后运行两个控制器方法就可以看到了 image

xuejmnet avatar May 10 '22 13:05 xuejmnet

@Im-Kevin 这个逻辑会有一个严重的漏洞当然也不能算是漏洞,如果这个时间是你自己创建的那么没关系,如果是别人创建的会有一个问题就是我可以随便填写然后他就会顺便创建表,如果你用的是创建时间后台赋值的那就没问题,哪怕是并发一个小时也就一张表按需创建,GetAllTails是启动的时候会被调用一次用来告知框架当前对象有多少表后缀了,当然你也可以自行持久化比如redis或者文件,我采用的是最简单最有效的根据ado.net自行查询当前数据库表名称后进行返回,但是这里有个小小的bug这边判断是StartWith如果你有这样的表名可能并不是很适用最好把下划线(分表连接器)也带上判断

xuejmnet avatar May 10 '22 13:05 xuejmnet

RouteWithValue这个路由方法是插入和修改都会经过的方法,所以在这边判断最合适

xuejmnet avatar May 10 '22 13:05 xuejmnet

image

我看了下之前我写的多字段分表你使用的这个雪花id解析这边获取当月第一天用了datetime.now其实是不正确的应该用雪花id解析出来的时间而不是datetime.now虽然大部分情况下都不会有问题但是极限下会有问题

xuejmnet avatar May 10 '22 14:05 xuejmnet

好的,感谢 这个雪花ID的问题我今天也发现了,我已经改成按小时的了

Im-Kevin avatar May 10 '22 14:05 Im-Kevin

@Im-Kevin 不知道这个路由是不是你要的

xuejmnet avatar May 11 '22 01:05 xuejmnet

这个是分表下是这样的,如果你是分表+分库的话最好参考 创建数据库 因为分库会涉及多个数据源,demo是仅分表的情况下考虑只用了默认的数据源DefaultDataSourceName

xuejmnet avatar May 11 '22 07:05 xuejmnet

好的,我看看先

Im-Kevin avatar May 11 '22 10:05 Im-Kevin

大佬,问你一个跟这个项目没关的问题,有没有什么工具可以实时监控并发是否已经超出服务器的能力了

Im-Kevin avatar May 12 '22 06:05 Im-Kevin

这个只能靠监控工具,但是我对这方面相对研究的很少所以可能帮不了你

xuejmnet avatar May 12 '22 06:05 xuejmnet

好的,那我再想想

Im-Kevin avatar May 12 '22 06:05 Im-Kevin

image

xuejmnet avatar May 17 '22 09:05 xuejmnet