一、成本水平分表概况
1、为什么需要水平分表
成本核算数据包括多种业务单据,经过多期账期后,数据量可能就很多了,当数据库表的数据量很大时,针对这个表的查询修改删除等操作时就会变得比较慢,常表现为查询成本报表慢,核算性能慢,期末结账慢等(例如从几亿的数据中,查询出单据编号为“XSCKD001”的单据)。
多个组织同时进行核算时,由于是针对同一个表做操作,很容易出现阻塞,死锁等问题,并发能力差。
2、水平分表能解决什么问题
单表数据变小,读写操作效率提高了;
查询一个组织期间数据范围变小,查询更快;
读写锁影响的数据量变小;
插入数据库需要重新建立索引的数据减少;
简单来说,查询成本的报表更快了,成本核算更快了,存货结账更快了。
3、适用水平分表场景
数据量比较大,或者说未来预见数据量会比较大(可以用单据量作为一个判断依据,如果核算总单据量在千万级别以上,可以认为是数据量比较大,或者现在一个期间的单据量达到百万级别)。
核算组织比较多,经常会多个组织同时并发核算。
如果业务数据量很少且组织单一,一个期间就几千或者几万的数据量,这种情况下就不建议做分表处理,因为分表前一般也没有性能问题。
4、水平分表维度规则
成本分表的存储结构,按“核算体系+核算组织+会计政策+年度+期间”来进行分割,也就是每个“核算体系+核算组织+会计政策+年度+期间”都会有自己独立的一套表。
5、适用版本
金蝶云星空 PT-146903 [8.0.0.202202] 构建号:8.0.144.1及其后续版本;
数据库:Oracle 11g及以上版本,SqlServer2014及以上版本。
6、注意事项
分表后如果需要反结账,请先确认反结账到的期间是否已经完成拆分,如果没有拆分,不能去反结账(后期会做反结账控制),否则会造成数据丢失。例如存货启用期间在2022年1期,当前期间2023年3期,拆表期间只选择拆了2023年1期到2023年3期的,此时如果反结账到2022年12期就会出现数据丢失问题。
二、怎样启用成本水平分表
1、发布菜单功能
此功能默认菜单未发布,可以在BOS IDE 中,设置菜单发布,具体操作路径:发布->成本管理->存货核算->初始化->启用成本拆分表->修改->勾选桌面端和浏览器选项。
2、打开启用成本拆分表菜单
如果已经登陆了系统,需要退出账号重新登陆下才能看到发布的菜单。
3、执行启用拆分表操作
启用后,会对历史期间的数据进行拆分升级数据。
此处有个开始会计年度和开始会计期间的参数可以选择,是用于如果历史期间数据很多,短时间拆分历史表升级的操作不能完成的情况下,可以选择最近一部分的数据升级,等空闲时间再继续升级以前期间的数据,如果历史期间不多或者历史数据量不是很大的期间下,可以不用管此参数,直接使用默认参数升级历史期间全部数据即可(例如使用存货系统已经3年了,并且每一期的数据量都非常大,如果一次性全部拆分升级历史数据的话,可能一天都执行不完,为避免影响业务系统使用,可以在夜晚闲时,拆分最近一年的数据,然后第二天晚上,又可以继续拆分前两年未升级的历史数据)。
4、等待升级历史数据
升级持续过程和待升级的历史数据量相关,执行拆分表操作后,耐心等待即可,拆分完成后,已启用拆分期间会显示已经完成拆分的期间,启用拆分表期间不能执行存货的出库成本核算、成本计算或者存货核算期末结账。
5、查看升级日志
升级过程中和升级完成后,都可以查看拆分结果,拆分日志中会记录对应期间的拆分情况已经每个表拆分的执行情况。
三、成本拆分表拓展功能
启用拆分表成功后,启用成本拆分表界面会有两个按钮“重建视图”和“升级拆分表主键”作为拓展功能。
1、重建视图
启用拆分表之后,原表已经不再使用,新的数据都到拆分表里面了。旧的视图也需要进行更新。重建视图追溯期间,默认是2期(假如当前期间是第10期,追溯区间是2期,就会重建第9期和第10期的新视图),点击“重建视图”,会把原视图删除,创建拆分表的最近期间的视图。重建视图追溯期间数值越大,重建视图的时间会越长。
此视图主要用于成本相关的列表查看,或者生成凭证时选单过滤及查看,包括材料费用分配结果(凭证),期初在产品成本调整(凭证),生产费用分配结果(凭证),完工成本结转,完工成本结转(数量金额式),如果没这方面的需求可以忽略此功能。
如果版本是PT-146926 [8.0.0.20220922]构建号:8.0.361.9及其后续补丁,可以忽略此功能,系统已经优化自动处理分表后的列表查看问题,不需要再手工执行重建视图)。
2、升级拆分表主键
拆分表的主键类型默认是int,如果数据量很大超出int范围(2147483647 ),int可能已经不够用了,点击“升级拆分表主键”就可以把int升级到bigint,解决上述问题。如果原表中还存在大量数据,升级过程可能会比较长,一般情况下无需关注此功能,如果当发现内码长度不够时,可以再来升级。
四、成本分表接口
如果存在二次开发成本相关功能,并且用到以前缀“T_HS”和“T_CB”开头的数据表,需要调整二开功能代码,此时的表启用分表后,是一个非固定名称的表,需要调用接口来获取对应的表,如果没有二开成本相关功能,此节内容可以忽略。
接口IFINSplitTableService,提供成本的拆分表管理的解决方案,当前接口开放在Kingdee.K3.BD.Contracts中。
获取接口示例:Kingdee.K3.BD.Contracts.ServiceFactory.GetService<IFINSplitTableService>(ctx)。
接口方法如下:
1、根据核算内码以及期初期末标志获取拆分表
string GetOnlyTargetTable(Context ctx, string sourceTableName, long acctgId, bool? isEnd = null)
ctx:上下文;
sourceTableName:原始表;
acctgId:核算内码,可以通过核算体系组织会计政策和年期获取,获取接口Kingdee.K3.FIN. ServiceHelper.CommonServiceHelper.GetAcctgId;
isEnd期初true/期末false,允许为NULL,当为NULL获取的是T_HS_OUTINSTOCKSEQ类似不存在期初期末拆分标志的数据表;
示例:获取余额表T_HS_INIVBALANCE的核算内码为100001期末拆分表
string splitTable = GetOnlyTargetTable(ctx,"T_HS_INIVBALANCE", 100001, true);
2、根据核算体系/核算组织/会计政策及年期获取拆分表
string GetOnlyTargetTable(Context ctx, string sourceTableName, long acctgSysId, long acctgOrgId, long acctgPolicyId, Tuple<int, int> yearPeriod, bool? isEnd = null)
ctx:上下文;
sourceTableName:原始表;
acctgSysId:核算体系内码;
acctgOrgId:核算组织内码;
acctgPolicyId:会计政策内码;
yearPeriod:年期;
isEnd:期初期末标志;
示例:
Tuple<int, int> tuplePeriod = new Tuple<int, int>(2018, 12);
string splitTable = GetOnlyTargetTable(ctx, "T_HS_INIVBALANCE", 1, 100002, 1, tuplePeriod, true);
string splitTable = GetOnlyTargetTable(ctx, "T_HS_OUTINSTOCKSEQ", 1, 100002, 1, Tuple.Create(2018, 12));
3、根据核算体系/核算组织/会计政策及某个期间段获取拆分表集合
List<string> GetOnlyTargetTable(Context ctx, string sourceTableName, long acctgSysId, long acctgOrgId, long acctgPolicyId, Tuple<int, int> startPeriod, Tuple<int, int> endPeriod, bool? isEnd = null)
ctx:上下文;
sourceTableName:原始表;
acctgSysId:核算体系内码;
acctgOrgId:核算组织内码;
acctgPolicyId:会计政策内码;
startPeriod:开始年期;
endPeriod:结束年期;
isEnd:期初期末标志;
示例:
Tuple<int, int> startPeriod = new Tuple<int, int>(2018, 10);
Tuple<int, int> endPeriod = new Tuple<int, int>(2018, 12);
List<string> splitTable = GetOnlyTargetTable(ctx, "T_HS_INIVBALANCE", 1, 100002, 1, startPeriod, endPeriod, true);
4、根据核算体系/核算组织/会计政策和某个期间段及过滤条件和查询字段获取拆分表拼接SQL集合
string GetTargetSqlString(Context ctx, string sourceTableName, long dimensionId, Tuple<int, int> startPeriod, Tuple<int, int> endPeriod, bool? isEnd = null, List<string> selectColumn = null, string whereStr = null)
ctx:上下文;
sourceTableName:原始表;
dimensionId:核算维度内码,由核算体系+核算组织+会计政策确定
startPeriod:开始年期;
endPeriod:结束年期;
isEnd:期初期末标志;
selectColumn :查询字段;
whereStr:过滤条件;
示例:
Tuple<int, int> startPeriod = new Tuple<int, int>(2018, 10);
Tuple<int, int> endPeriod = new Tuple<int, int>(2018, 12);
List<string> selectColumns = new List<string>();
selectColumns.Add("FID");
selectColumns.Add("FQTY");
selectColumns.Add("FAMOUNT");
string whereSql = " FDIMEENTRYID = 100002 ";
string splitTableSql = GetTargetSqlString(ctx, "T_HS_INIVBALANCE", 1, 100002, 1, startPeriod, endPeriod, isEnd: true, selectColumn: selectColumns, whereStr: whereSql);
5、更多接口
以上的几个接口一般二开获取数据表基本上就可以满足需求了,如果还需要更丰富的接口方法,可以在接口ICBSplitTableService中获取,此接口开放在Kingdee.K3.FIN.Contracts中,具体方法使用可以通过接口注释获取。
获取接口示例:
Kingdee.K3.FIN.Contracts.ServiceFactory.GetService<ICBSplitTableService>(ctx)。
6、成本数据表已拆分目录
如果在二次开发中使用到以下的表,在启用分表后,再直接使用表获取数据将获取不到了,需要使用上述接口获取。
原始表 | 分表依据字段 | 备注 |
T_CB_PROORDERINFO | FACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_CB_COSTCALEXPENSE | FOUTACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_CB_COSTCALEXPENSEDETAIL | FOUTACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_CB_COSTMATTERIAL | FOUTACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_CB_COSTMATTERIALDETAIL | FOUTACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_CB_COSTALLORESULTREC | FOUTACCTGID | 核算内码 |
T_CB_COSTALLORESULTRECEXP | FOUTACCTGID | 核算内码 |
T_CB_COSTALLORESULTSEND | FOUTACCTGID | 核算内码 |
T_CB_COSTALLORESULTSENDEXP | FOUTACCTGID | 核算内码 |
T_CB_COSTALLOPROREC | FOUTACCTGID | 核算内码 |
T_CB_COSTALLOPRORECEXP | FOUTACCTGID | 核算内码 |
T_CB_COSTALLOPROSEND | FOUTACCTGID | 核算内码 |
T_CB_COSTALLOPROSENDEXP | FOUTACCTGID | 核算内码 |
T_CB_EXPALLORESULTREC | FOUTACCTGID | 核算内码 |
T_CB_EXPALLORESULTSEND | FOUTACCTGID | 核算内码 |
T_CB_EXPALLOPROCESSREC | FOUTACCTGID | 核算内码 |
T_CB_EXPALLOPROCESSSEND | FOUTACCTGID | 核算内码 |
T_HS_INIVBALANCE | FID/FENDINITKEY | 核算内码/期初期末标志 |
T_HS_INIVBALANCEENTRY | FACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_HS_INIVBALANCEEXP | FACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_HS_INIVBALANCEEXPENTRY | FACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_HS_BALANCE | FID/FENDINITKEY | 核算内码/期初期末标志 |
T_HS_BALANCEENTRY | FACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_HS_BALANCEEXP | FACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_HS_BALANCEEXPENTRY | FACCTGID/FENDINITKEY | 核算内码/期初期末标志 |
T_HS_OUTINSTOCKSEQ | FACCTGID | 核算内码 |
T_HS_EXPENSES | FACCTGID | 核算内码 |
T_HS_ACCTGPROCESS | FACCTGID | 核算内码 |
T_HS_ACCTGPROCESSENTRY | FACCTGID | 核算内码 |
T_HS_EXPENSESPROCESS | FACCTGID | 核算内码 |
T_HS_OUTINSTOCKSEQ_LK | FACCTGID | 核算内码 |
T_HS_EXPENSES_LK | FACCTGID | 核算内码 |
推荐阅读