找回密码
 立即注册

QQ登录

只需一步,快速开始

mucai 悬赏达人认证 活字格认证

高级会员

71

主题

358

帖子

1235

积分

高级会员

积分
1235

微信认证勋章悬赏达人活字格认证

mucai 悬赏达人认证 活字格认证
高级会员   /  发表于:2020-7-12 18:38  /   查看:21240  /  回复:41
本帖最后由 mucai 于 2021-7-2 12:00 编辑

来自学习和实操后的总结,有说得不对的,或者遗漏的,大家留言补充。希望这个贴子,能成为活字格老铁们使用外联库的一个指南。PS即使你不打算使用外联库,里面的一些方法,也值得看一看!

一、库表规划
1、系统表:如组织架构、用户、角色、权限等。活字格内置在sqlite中,无法直连,可通过视图方式读取出来
2、词典表dictionary:辅助填报的列表信息,如行政区域、男女、学历、岗位、合同类型、商品类别等。其中数据量多、结构比较独特或需要中台设定的,单独做表,如行政区域表(记录多)、商品类别(中台设定)等,其它放在通用词典表,做一些表设计,我一般是设置类别字段、属性字段(固定参/可变参,2020-9-5改、排序字段、图片字段、三个字符字段,三个小数字段。
3、业务表business:记录业务的发生,这是使用最多的表
4、当前表current:存放当前值/累计值或档案类,如当前库存、累计销售、商品档案等
5、期末表end:存放某个时期的期末结存数,如月末库存
6、期间表period:存放某个时期内的发生值,如月销售统计


二、建表
1、表命名:目前我使用的表命令方法:模块英文标识_表主名使用驼峰法,如hr_employee,hr_employeeFamily(9月5日改)
2、视图命名:模块英文标识v_视图的作用(2020-9-5改)
3、函数命名:模块英文标识p_函数的作用(2020-9-5改
4、表名/字段长度:虽然mssql可以128个字符,但还是建议在64个以内
5、字段名全部用英文,字段全部用小写英文字母,字母开头,不同单词用_连接,不用复词,即使是内置的sqlite,也建议用英文名
6、表/字段设计时,尽可能都加注释,我会把字段注释全部入到表注释那里,省时间。如果字段有固定参的,最好也把固定参定上(2020-9-5改)
7、临时表,使用内置的sqlite表,可以提升效率,特别是进行中间计算或笛卡尔积时,能极大的提升效率,注意,是极大!
8、在活字格内先建表,然后在数据库IDE中设计表。这样会在前面几个字段自动建立ID(默认主键)、FGC_CreateDate、FGC_LastModifier、FGC_LastModifyDate、FGC_Creator、FGC_Rowversion、FGC_UpdateHelp字段。主键、并发、权限问题一次性解决。PS.自建字段千万不要去动,另外,外联表的字段设计不要在活字格里弄,因为数据类型有限。

三、字段
1、mysql里能用char,就不用vchar,mssql也一样。另外,mssql里,如果有中文就用nchar和nvarchar,纯英文和数字,那就用char和varchar
2、vchar不超过5000,如果超过,用text,并独立出一张表,用主键对应
3、tinyint-255,smallint-65535,int-42.9亿,bigint-最大,实际使用时再放大几个零
4、小数类型,如果是金融类的一定要用decimal(18,2),float(7位)和double(15位)自己选择。(2020-9-5改)
5、是否字段用is_,如果是表现已经状态,如is_deleted,1表示已删除
6、数据表虽然有二进制字段,但活字格的图片和附件都是以字符串形式记录地址,以防万一,在mssql里我都直接用nvarchar(max)来
7、表名、字段名、字段类型真得非常重要,在生产环境中,基本上没有机会可以更改,对有长度的字段类型,还是要留有余量

8、(2020-7-20新增)一张表只能有一个timestamp时间戳类型,如果你给活字格修改数据表的权限,活字格会自动帮你建一个,那是用来防止并发脏读的。重复一次,活字格自动建的几个字段,不要去改动,包括字段类型也不要去动!
9、(2020-7-30新增)SQL数据库的日期,一般有date、datetime、datetime2三种,活字格的日期对应的是datetime。之前,为了省资源,将日期设为了date,但期间出现的几次时间字段的数据库报错。出现几次后,发现了规律,就是数据库连接断开,重新连的时候,活字格会把date字段识别为文本,这样就会出现报错。所以,建议外联数据库的日期还是设置为datetime,时间则设置为time(7,0),和活字格的机制保持一致!

四、主键/外键
1、主键最好只用自然主键,不要和业务关联,比如活字格自动新建的ID字段,同时尽量避免用联合主键
2、外键使用比较讲究,先说逻辑外键,就是活字格中设置关联字段,但不设置联级约束,就是逻辑外键(在活字格里不能设置外联表的联级约束,需要在数据库IDE中设置),逻辑外键可以随意用。但联级约束外键要慎用,因为每次增改删都会触发联级查询,会影响效率。阿里的开发手册干脆就直接干掉联级外键了。
3、如果一定要用联级外键,注意以下几点:(1)引用列并不一定非要主键,但必须是唯一列;(2)外键列与引用列的数据类型/字符集/校对规则要一致;(3)外键列和引用列都必须建索引;(4)外键列引用多个列的,列顺序要一致;(5)大对象字段不要用做引用列;(6)外键命名在库里要唯一,命名规则fk_本表名_引用表名_on_引用字段,表名的模块缩写和结尾标识去掉;(6)如果子表弄了触发器,外键联级更新是不会触发的,所以这种情况不要用;(7)不再支持分区表了,所以有计划用分区表的,不要用外键;(8)高并发更新表情况下,一定一定要避免使用联级外键
4、虽然阿里不建议用联级外键,但在非常严格要求主子表一致性、表结构简单、并发不高、查询数据量不高时,可以用一下。其它情况,需要联级约束的,最好在前端通过设计来实现
5、身份证号、银行账号、社保账号之类敏感的字段,不要做主键或外键

五、索引
1、索引命名:主键索引pk_表名_字段名,表名的模块缩写和结尾标识去掉,唯一索引uk_,普通索引idx_。如果你选择在活字格中建外联表,会自动建立一个ID的索引(主键自动建索引),最好按规则改一下名。注:索引需要在数据表IDE中建,活字格中建不了
2、业务上具有唯一特性的字段,即使是多个字段的组合,如果要建立索引,则必须建成唯一索引
3、索引如果不确定要用,可以先不设置,后期进行sql优化时再使用。一般建在多表联接用的关联字段以及查询频率较高的条件字段上。
4、vchar索引,如果比较长,需要注意。一般20长度已经能覆盖90%的查询判断, 可以用count(distinct left(列名, 索引长度))和count(*)的来测试决定,设置方式column_name(length)
5、where和orderby有索引字段,且该字段在复合索引中时,将该字段放在复合索引最后
6、建组合索引的时候,区分度最高的在最左边。如where a=? and b=? ,如果 a 列几乎接近于唯一值,那么只需要单建a列 索引即可
7、存在非等号和等号混合时,在建索引时,请把等号条件的列前置。如:where c>? and d=? 那么即使 c 的区分度更高,也必须把 d 放在索引的最前列,即索引 idx_d_c
8、不要索引常用的小型表
9、查看select是否使用了索引、使用了哪个索引,可以使用用执行计划(EXPLAIN,在IDE中使用)查询结果,看key和key_len两项

10、(2020-08-07)mssql设置为主键和唯一键的,会自动建索引,不需要另外建;mysql的唯一键,是通过建立唯一性的索引来设置,主键也会自动建索引;

六、其它
1、join不要超过3个表,join字段数据类型必须一致。多表关联查询时,保证被关联的字段需要有索引。
2、查询先快速定位需要获取的 id 段,然后再关联,如:SELECT a.* FROM 表 1 a, (select id from 表 1 where 条件 LIMIT 100000,20 ) b where a.id=b.id
3、如果对字符编码和引擎不熟悉,反正看到UTF8、innodb的字眼,选它就对
4、反范式:字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:(1)不是频繁修改的字段;(2)不是 varchar 超长字段,更不能是 text 字段;(3)不是唯一索引的字段。举个例子就明白:商品类目名称使用频率高,字段长度短,名称基本一不变,可在相关联的表中冗余存储类目名称,避免关联查询。看了一个测试,150万的数据,一个35秒,一个几秒,惊呆了
5、通常数据库优化的方向:(1)服务器硬件(三大件);(2)服务器布置环境(比如你用mysql,就一定不能在windows环境里);(3)SQL本身优化;(4)反范式;(5)索引优化。查一下关键词“慢查询”、“慢sql”、“perl”。
6、阿里开发手册是禁止使用存储过程的,认为存储过程难以调试和扩展,更没有移植性。但也有人认为可以使用,比如一些常用的关联表功能组,还是可以封装。但原则是前后端设计能解决的,就不要用存储过程,特别是现在有了服务端命令,应该可以尽量避免使用
7、设计视图要从业务出发,视图和业务建立一对一的关系,不要因为想让一个视图为多个业务服务,而放进不需要的语句、表和字段。视图不要嵌套视图,效率会被大大影响,和join一样,也不要超过3个表。太复杂的,可以考虑走存储过程,效率会更高。活字格中不能直接建立外联表的视图,需要在数据库IDE中建立,导入时需要选择主键,SQL里视图是没有主键概念的,但既然它让你设,你就设一个吧,据说能提高性能。而且,如果你不设,表名旁边的图标会显示为和普通表一样,而且不是视图特有的图标,完美主义者的我,是不能容忍这种事情的
8、关于外联表选mssql还是mysql,如果活字格服务端和数据库在同一个服务器,还是自己安装数据库,就用mssql,大多数人推荐2008R2和2012,我已经升级到2012。这种情况选mssql的原因,一是阿里云和腾讯云亲测都可以安装使用,盗不盗版,如果不是做公有云布置,估计也没啥问题,二是windows环境还是用mssql,而且活字格是.net的,属于一家人;三是你自己下载安装的mysql和腾讯云提供给你的mysql是不一样的,自己安装的话,最好不选mysql。如果是使用阿里云或腾讯云的云数据库,那就选 mysql,一是更便宜,二是他们都做了优化,也有很多优化工具可以使用,比如前面的慢sql,不比mssql差。
9、数据库IDE,因为计划只用sqlserver,所以改用原生的IDE,SQLserver同一个安装包,安装时只选IDE就可以,可网上搜教程(2020-9-5改)
10、最后说说,我对选内置数据库还是外联数据库的看法。既然写了这么多外联数据库的东西,自然我的选择是外联数据库了。选什么不重要,重要的是为什么选?所以简单说一下原因:(1)百度sqlite,出现最多的关键词,是轻型、嵌入、桌面、不需要配置安装,然后sqlite支持高并发的读,但不支持高并发的写,等等,我们是要用活字格来做企业业务应用的,而且是web应用,你会觉得sqlite的特点和需求吻合吗?;(2)上面说了很多数据库优化的东西,无论是mssql还是mysql,都有非常多的优化教程、方法和工具,阿里云和腾讯云也都有提供专门的数据库优化工作和方案,我认为在数据量到百万甚至是几十万级的时候,性能上的表现一定会突出出来,而sqlite的优化空间太小;(3)接触到外联数据库,我才打开了一个新的窗口,才能写以上的东西。我相信很多用内置库的老铁们,表名字段名还是用中文吧,你不用外联库,你就根本不会关注到这些东西;(4)外联mysql和mssql都可以直联,这样可以方便的相互窜门,而sqlite虽然是活字格内置的,但却不能直连。
PS:虽然我选择了外联数据库,但我仍然会经常用到内置库,比如前面说的,在一些临时表和中间表的使用上,我基本上都是用sqlite,很多情况下,执行效率比外联表高很多,这样你的外联库看上去也清爽些。所以,活字格的内置库用sqlite我觉得挺好的,内置和外联,相互补充。另外,新接触低代码系统的老铁们,进入门槛也大大降低了~~~

11、(2020-8-2新增)看了几篇关于mysql和mssql安全性能的比较,以及云开发中云函数可以外接mysql,再加上两者云数据库相关两三倍的价格,心血来潮,花了一天时间捣鼓mysql,结果踩了坑。测试的环境,包括(1)使用腾讯云数据库mysql,与安装活字格的腾讯云服务器在一个私有网络内连结;(2)直接在安装活字格安装腾讯云服务器上自建mysql。原来环境是在腾讯云服务器中自建mssql。结果两个mysql环境效率,都比mssql环境,低了2倍左右。这个结果,不能说mysql的执行效率比mssql低,但至少可以下结论:活字格中,使用mssql比使用mysql的效率更高。所以使用外联数据库,还是好好把mssql用好。附两个测试点:(1)页面表格500行数据,使用提交表格命令,mssql>2-3分钟左右,mysql>6-8分钟
(2)页面两个表格,根据单元格值变化执行查询命令,mssql>1秒左右,mysql>3-5秒


12、(2020-8-2新增)另外,也总结一下使用mysql的注意事项:
(1)字符集选择utf8或utf8mb4,腾讯云官方是建议直接用uft8mb4,能支持表情字符,因为很多人的微信名会用表情字符。这两种字符集,排序规则都用general_ci。这个和mssql不一样,在mssql里,没有字符集的选择,是通过选择排序规则来选择的,选Chinese_PRC_CI_AS(不区分大小写、区分重音、不区分假名类型、不区分宽度
(2)是否,用tinyint(1)
(3)补充一下几个小数float、double和decimal的应用,三个精度依次提升,但效率也依次降低,和前文说的有不一样的地方。A、金融相关的,一定用decimal,大小一般设置为(18,2),不用decimal,会遇到浮点不等情况;B、float效率最快,但只有7个有效位,比如你设置为(7,4)的话,最多只能表示***.****, 一些参数型、百分率的字段我会用到;C、double翻一倍,15个有效位
(4)mysql的数据类型更少,比如没有nvarchar(max)、varchar(max)这样的,所以在mysql里,长文本要用text
(5)活字格的图片和附件转到mysql,是用varchar(500),多附件这种,可能会遇到字符长度不够的情况,如果预计不够,会要改一下。不过至今我还是没搞清楚,究竟varchar最长可以放多少个字符,找资料,有说255的
(5)mysql里没有设置唯一键的地方,是通过建唯一索引来设置唯一键,索引类型一般选unique或normal(index),索引方法一般BTREE。主键会自动建一个索引

13、(2021-6-6)2021年的第一补:
(1)如果没有使用过sql的窗口函数,那赶紧了解一下。最近一次项目,在做移动统计时,先是用嵌套循环实现,结果要十几分钟,肯定不行。后来想到用sql的窗口函数,NND,瞬间完成。窗口函数,是个好东西。

14、(2021-7-2)补充:关于内置数据库与外部数据库选择问题的新思考。
几个前提:
(1)内置数据库只支持sqlite的现状,短期内估计不会变化
(2)同服务器内(活字格服务器和外联数据库安装在同一个服务器内),内置的sqlite数据库的计算效率远大于外联数据库,无论是mysql还是sqlserver。(这个结论,仅在一般服务器配置下得出,比如腾讯云的2核8G,带宽不限。测试的情况包括:大数据加载、数据导入、递归计算、笛卡尔集计算、复杂的数据库服务端命令等,差异有时会到几秒到十几秒。外联数据库用存储过程,另当别论。服务器配置高,可以差异会少一些,没试过)
(3)同服务器跨应用,内置数据库sqlite无法相互访问,造成数据割裂。(sqlite是随应用的)
(4)服务端命令可以解决之前很多只能依靠存储过程解决的问题,等服务端命令可以执行sql的时候,这个会有更大的空间
基于以上原因,如果是中小类型应用,服务器预算又不是特别高的,建议考虑sqlite。如果使用sqlite的话,就要解决跨应用处理数据的问题。目前有两个方案可以考虑:
方案1:全部应用都使用sqlite,跨应用时,通过服务端命令+webapi来处理数据,如果要用到webapi,门槛高很多,需要的技术栈为低于入门一些的C#和JS(ES5部分)
方案2:主应用使用sqlite,次应用使用mysql或sqlserver,主应用通过外联数据库来处理次应用的数据,如果次应用需要调用主应用数据,则使用服务端命令。



image.png816791992.png

评分

参与人数 9金币 +1000 满意度 +40 收起 理由
Eunky + 5
13794930121 + 5
sz_xd + 5
phoben + 5
孤狼 + 5
sonic + 5
vickdracula + 5
Simon.hu + 1000 赞一个!
1818himis + 5 很给力!

查看全部评分

41 个回复

倒序浏览
xiaoz悬赏达人认证 活字格认证
金牌服务用户   /  发表于:2020-7-12 19:29:36
沙发
先去收藏夹吃灰
回复 使用道具 举报
unimaallan
金牌服务用户   /  发表于:2020-7-13 09:01:42
板凳
先收藏
回复 使用道具 举报
谢厅讲师达人认证 悬赏达人认证 活字格认证
金牌服务用户   /  发表于:2020-7-13 09:46:17
地板
mark
回复 使用道具 举报
白菜贝贝悬赏达人认证 活字格认证
银牌会员   /  发表于:2020-7-13 13:56:16
5#
赶紧过来收藏,虽然没看懂
回复 使用道具 举报
hubei333
高级会员   /  发表于:2020-7-13 18:38:28
6#
一定要收藏,也在考虑尝试外联数据库
回复 使用道具 举报
qq8009活字格认证
银牌会员   /  发表于:2020-7-13 20:19:57
7#
支持一个, 已经是外联数据库了
回复 使用道具 举报
tzeggtang
中级会员   /  发表于:2020-7-14 10:52:22
8#
一直在使用外联表,就是不规范。好好学学楼主的。
回复 使用道具 举报
amtath悬赏达人认证 活字格认证
论坛元老   /  发表于:2020-7-14 16:02:16
9#
回复 使用道具 举报
WangZhiQing
高级会员   /  发表于:2020-7-15 12:27:09
10#
先收藏,真用心
回复 使用道具 举报
12345下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部