数据库开发规范

数据库
数据库开发规范
也可用于PostgreSQL以及兼容PG的数据库
通用命名规则
【强制】 本规则适用于所有对象名,包括:库名、表名、列名、函数名、视图名、序列号名、别名等。

【强制】 对象名务必只使用小写字母,下划线,数字,首字母使用小写字母,常规表禁止使用_打头。

【强制】 不使用双引号即"包围,除非必须包含大写字母或空格等特殊字符

【强制】 禁止使用SQL保留字,可以先查看保留关键字列表。

【强制】 库名、表名限制命名长度,建议表名及字段名字符总长度小于等于63。

【强制】 禁止出现美元符号,禁止使用中文。

【推荐】 对象按类别带上标识,表t_,视图v_,函数fun_,临时表以tmp_开头。

【推荐】 主键索引应以pk_开头, 唯一索引要以 uk_开头,普通索引要以 i_开头。

字段命名规范
【强制】设计时字段统一, varchar,TEXT字段以C_开头,int,numeric以N_开头,日期以D_开头,时间以DT_开头,数组以ARR_开头,JSONB字段以J_开头

设计规范
整体设计要求

【强制】 数据库应使用UTF8字符集,连接应指定UTF8字符集。

【强制】 数据库级别不设置默认值。

【强制】 表必须有主键或唯一约束。

【强制】 数据库不使用外键约束,建议在应用层解决。

【强制】 禁止使用触发器。触发器会提高系统的复杂度与维护成本。

【强制】 为防止数据汇总依赖数据库本身的特性,应进行业务数据的增量设计。

【强制】 业务表不允许存在逻辑删除标志位。

【强制】 业务表不做代码值,代码名称此类简单冗余。

【强制】 设计逻辑外键,主键和逻辑外键类型必须一致,且逻辑外键必须定义索引。

注:主键为VC32外键也为VC32,CHAR和VARCHAR属于不同的类型

【强制】 多表中的相同列,以及有JOIN需求的列,必须保证列名一致,数据类型一致。

【强制】 OLTP系统,任意表最大列数不能超过80。

【强制】 多级子表逻辑外键设计要求。

一级子表要有主表的逻辑外键

二级子表要有主表、一级子表逻辑外键

三级子表要有主表、一级子表、二级子表逻辑外键

依次类推

【强制】 超大表建议考虑拆表。

大表(业务数据预估超过500W)考虑拆表,视具体业务和架构师讨论决定
【强制】 使用分区表,建议使用pg12及以上版本,低版本更新和删除会扫描所有分区。

【强制】 同一表禁止双向复制。

【强制】 如果需要存储LOB类型结构化信息,应与业务数据分开,设计单独表存储;不宜在数据库中存储非结构化信息。

【强制】 无论是开发环境还是生产环境,应配置数据库连接池,并且不应使用数据库管理员权限用户(如sa)作为数据库连接池用户;数据库连接池应使用Druid,最小连接数宜设置为20、最大连接数宜设置为50,最小连接数和最大连接数的参数值不应相同。

【推荐】 pg使用JSONB类型存储JSON数据,因jsonb是先解析再存储,查询效率比json高。且jsonb支持许多额外的操作符。

【推荐】 pg建议使用default NULL而不用default ''以节省存储空间 。

【推荐】 pg建议使用ip4,ip4r,ip6,ip6r,ipaddress,iprange 来存储IP,IP范围;使用macaddr来存储MAC (Media Access Control) address。

精度设计要求
【强制】 UUID类型主外键,设置为VC32。

【强制】 数字原则上只有integer和numeric(20,4)。对于长度小于10位(不包括)的数值字段应使用integer类型;大于10位的数值字段应使用number或 numeric ;金额应以”元”为单位存储,使用number(20,4)存储。

【强制】 文件大小设置为numeric(20),单位为byte。

【强制】 金额,单位为元。设置为numeric(20,4)。

【强制】 使用varchar(N),不使用char(N),有利于节省空间。

【强制】 VC精度控制,推荐只有32/100/300/600/900五种精度。文本字段设计要求,主键VC32、单值代码VC100、其他文本按长度应设计为VC300、VC600、VC900,超出VC900范围应采用TEXT类型。

【强制】 名称汉字设置为VC300。

【强制】 外部存储文件的文件显示名称、文件名设置为VC300,存储路径设置为VC600。

【强制】 没有精度要求的,不要写精度:int/date/datetime/text等。

【强制】 timestamp类型精度设置为3。

和java程序数据类型精度保持一致
【强制】 密码不用二进制类型,用16进制字符串。

业务设计要求
【强制】 多表中同含义字段,名称、类型、精度必须统一。

【强制】 字段名称、字段中文描述、说明含义必须一致。

索引规范
【强制】 禁止在大字段上面建立索引,btree索引字段不建议超过2000字节,如果有超过2000字节的字段需要建索引,建议使用函数索引(例如哈希值索引),或者使用分词索引。

【强制】 明确空值排序规则

如在可空列上有排序需求,需要在查询与索引中明确指定NULLS FIRST还是NULLS LAST。
注意,DESC排序的默认规则是NULLS FIRST,即空值会出现在排序的最前面,通常这不是期望行为。
索引的排序条件必须与查询匹配,如:create index on tbl (id desc nulls last);
【强制】 禁止对数据库同一字段建立多个相同类型的索引

【推荐】 pg利用部分索引,对于固定条件的查询,可以使用部分索引,减少索引的大小,同时提升查询效率。

select * from tbl where id=1 and col=?;– 其中id=1为固定的条件
create index idx on tbl (col) where id=1;
【推荐】 pg利用函数索引,对于经常使用表达式作为查询条件的语句,可以使用表达式或函数索引加速查询。

select * from test where exp(xxx);

create index on test ( exp(xxx) );

【推荐】 pg利用范围索引,对于值与堆表的存储顺序线性相关且不经常更新的数据,如果通常的查询为范围查询,建议使用BRIN索引。

【推荐】 当用户有prefix或者suffix的模糊查询需求时,pg可以使用索引,或反转索引来提升查询效率

【推荐】 pg10以前不建议使用Hash索引

【推荐】 建议用unique index代替unique constraints,便于后续维护,constraints不能使用CONCURRENTLY

【推荐】 建议不要建过多index,一般不要超过6个,核心table可适当增加index个数

其他
【推荐】 pg不建议使用public schema(不同业务共享的对象可以使用public schema),应该为每个应用分配对应的schema。

【参考】 pg对于频繁更新的表,建议建表时指定表的fillfactor=80,每页预留15%的空间给HOT更新使用。

SQL规范
【强制】 INSERT语句必须要穷举所有插入的字段名称

【强制】 数据行删除/更新使用delete/update时,必须带上WHERE子句

【强制】 禁止使用SELECT *查询,应穷举所有要查询的字段名

【强制】 不要使用count(列名)或count(常量)来代替count(*)

【强制】 SQL脚本应使用in来处理的情况,in里面的枚举个数不应超过100。

【强制】 新立项的OLTP产品/ 项目中, SQL长度限制原则为: 90%的SQL长度<=500字符; SQL最大长度不应超过1K。

【强制】 SQL中的变量应使用绑定变量(prepareStatement),避免SQL注入,并且提高数据库执行的效率。

【强制】 一般页面的SQL请求个数应在10之内,首页、统计页等页面的SQL请求个数应在50以内。

【强制】 不应在循环中执行查询(select)语句,应统一查询出来后处理;宜避免在循环中调用第三方接口。

【强制】 抽样查询禁止使用ORDER BY random(),abase建议使用tablesample system/tablesample bernoulli

【强制】 禁止使用=NULL/!=NULL,不是标准语法,判空写法为IS NULL/IS NOT NULL。

【强制】 分页查询语句全部都需要带有排序条件,且排序的字段需要唯一,除非业务方明确要求不要使用任何排序来随机展示数据

【强制】 在函数中,或程序中,不要使用count(*)判断是否有数据,很慢。 建议的方法是limit 1

【推荐】 建议将单个事务的多条SQL操作、分解、拆分,或者不放在一个事务里,让每个事务的粒度尽可能小,尽量lock少的资源,避免lock、deadlock的产生

【推荐】 如果需要清除全表数据,建议使用truncate删除所有的行,但使用ARRS需要注意truncate不记录事务日志

【推荐】 建议复杂的统计查询可以尝试窗口函数Window Functions

【推荐】 相同字段的OR条件,建议使用IN代替

【推荐】不同字段的OR条件如果字段都有独立索引可以走索引,sybase建议使用UNION ALL代替

【推荐】 不建议使用NOT IN,建议使用NOT EXISTS

【推荐】 尽量避免在SELECT子句中使用子查询,替换为连接查询

【推荐】 应按照业务需要使用事务,同时应保持事务简短,避免大事务

【推荐】 SQL 语句尽可能避免超过 4 张表以上的联合复杂查询

【推荐】 应该尽量在业务层面避免死锁的产生,避免多个线程处理同一条数据

【推荐】 应尽量避免在 where 子句中使用!=或<>,not操作符,否则将引擎放弃使用索引而进行全表扫描。

管理规范
【强制】 关注备份

每日全量备份,重要数据做实时增量备份,和异地备份,定期做备份还原验证
【强制】禁用trust认证

生产环境禁止在pg_hba.conf中配置trust认证(trust标识不需要密码就可以登陆,即使密码是错误的)
低版本建议使用md5,推荐使用scram-sha-256
【强制】 关注年龄

abase关注数据库与表的年龄,避免事物ID回卷。
【强制】 关注老化与膨胀

关注表与索引的膨胀率,避免性能劣化。
【强制】 关注复制延迟

监控复制延迟,使用复制槽时更必须十分留意。
【强制】 遵循最小权限原则

【强制】 并发地创建与删除索引

建议create或 drop index时、加 CONCURRENTLY参数,达到与写入数据并发的效果

对于生产表,必须使用CREATE INDEX CONCURRENTLY并发创建索引。

【强制】 审慎地进行模式变更

添加新列时必须使用不带默认值的语法,避免全表重写
变更类型时,必要时应当重建所有依赖该类型的函数。
【推荐】 切分大批量操作

大批量写入操作应当切分为小批量进行,避免一次产生大量WAL。
【推荐】 加速数据加载
先加载数据后创建索引

【推荐】 线上表结构的变更包括添加字段,索引操作在业务低峰期进行。

附:SQL查询优化
在书写sql的过程中,可谓百花争鸣。虽然最后都得到了相同的结果集但过程不一样,效率也不一样。为了避免这种情况所以制定一个sql书写规范

1.count问题、去除多余的外层嵌套count(*)

select count (*)
FROM
(SELECT aj.C_BH,aj.C_AH,aj.C_BQJG,aj.N_ZZM,aj.N_XFBGLX,aj.N_CBR,aj.C_ZMZS,aj.C_DSR
FROM
T_XS_AJ aj
WHERE
aj.N_XFBGLX IN (1, 2)
AND aj.N_SPCX = 12
AND aj.N_CBR = 157286789
AND aj.DT_FASJ IS NOT NULL
AND aj.N_AJJZJD = 10
) t_19b4ae3444
从执行计划来看数据库会自动提升子查询,效率上没有差别

2.严禁使用select * 形式的语句

select xtgn.* from DB_ZXXT…T_XTGN xtgn where xtgn.N_FY = 1;
消耗更多的CPU和io以及网络带宽资源
无法使用覆盖索引
可减少表结构变更带来的影响
必须指出select的具体字段、如select col1,col2,…from table1 where …;
3.统一使用select count(*)

不使用select count(1),select count(0),select count(col),select count(c_bh)
4.禁止隐含的数据类型转换

string类型传入了int类型或者numberic和int类型相加
SELECT COUNT(*) n_scs,c_ss_wg FROM wgxt.t_sc_sx WHERE c_sfyx=1 GROUP BY c_ss_wg;
c_sfyx为varcahr类型
5.禁止在where条件中添加1=1,1=2这种表达式作为部分条件

LEFT JOIN db_rmtj.t_tjgzgl gl ON tcgz.c_bh = gl.c_gzbh
WHERE 1 = 1 AND t1.c_pdm = ‘1301’
6.禁止在where子句中对列进行计算、数据库函数、计算表达式等放置在等号右边

from t1 where c1/3>10;可写成from t1 where c1>30
7.update语句禁止更新主键字段

update table set c_bh =‘123’,n_ly=2 where c_bh = ‘123’
如果再gp中c_bh作为分布键,该语句会报错。
8.插入需要指定列名insert into table values(?,?,?)
必须指出具体对应的列、即insert into table (col1,col2…) values (?,?.)
Inert into db_zxzhld.t_zhld_db values (…
解读:容易在增加或删除字段后出现程序bug
9.字段取别名使用as,而非空格

from db_zxzhld.t_zhld_db as db
10.连接多个表时,请使用表的别名并把前缀用于每个列上,这样可以减少解析时间,并且减少列歧义引起的语法错误。

11.建议在sql中使用多行注释、单行注释后期在排查sql问题时不知道那部分sql是已经注释的、建议使用/ /。

ajxx.c_ajbh=zbaj.c_ajbh --)res --WHERE res.c_bh is null or (res.c_bh is not null AND res.c_ajbh is null)
12.or和and共同使用时建议多打一对括号、默认and优先级高于or

tydftftjl0_.DT_KSSJ<=‘07/19/2017 16:25:00.000’ and
tydftftjl0_.DT_JSSJ>‘07/19/2017 16:25:00.000’ or
tydftftjl0_.DT_KSSJ<‘07/19/2017 16:30:00.000’ and
tydftftjl0_.DT_JSSJ>=‘07/19/2017 16:30:00.000’ or
tydftftjl0_.DT_KSSJ>‘07/19/2017 16:25:00.000’ and
tydftftjl0_.DT_JSSJ<‘07/19/2017 16:30:00.000’
13.建议使用预编译语句进行数据库操作
好处:只传参数,比传递SQL语句更高效
相同语句可以一次解析,多次使用,提高处理效率
如果用户需要在插入数据和,删除数据前,或者修改数据后马上拿到插入或被删除或修改后的数据,建议使用RETURNING子句,减少数据库交互次数。
– returning后面可以返回 * 、指定某几个字段 或者 主键等
– 插入,返回n_id
db_sqlfx=# insert into test(n_id) values(1) RETURNING n_id;
insert into test(n_id) values(1) RETURNING *;
– 更新
update test set c_name= ‘李四’ where n_id = 1 RETURNING n_id;

– 删除
delete from test where n_id = 1 RETURNING n_id;
15.abase推荐使用UPSERT简化逻辑

upsert语法类似于oracle的merge语法,数据不存在则插入,存在则更新

–查看n_id=2的这条数据
db_sqlfx=# select * from test where n_id = 2;

–不做任何操作,也不会报错
db_sqlfx=# insert into test(n_id,c_name) values(2,‘lisi’) on conflict(n_id) do nothing;
–如果删除主键
db_sqlfx=# alter table test drop constraint test_pkey;
ALTER TABLE
db_sqlfx=# insert into test(n_id,c_name) values(2,‘lisi’) on conflict(n_id) do update set c_name = ‘lisi’ where test.n_id = 2;
错误: 没有匹配ON CONFLICT说明的唯一或者排除约束
注意:conflict(n_id)中n_id必须有唯一索引

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/17084.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

芯片设计企业的IT支撑点

对于一个芯片设计企业&#xff0c;需要怎么样的IT支撑&#xff0c;这看起来并不是那么重要&#xff0c;并不影响芯片企业是否取得成功&#xff0c;但真正进入这个行业&#xff0c;你会发现&#xff0c;这里还是有一些门道的。 实际上&#xff0c;芯片设计企业对于IT的依赖很重&…

生成对抗网络入门:Mnist手写数字生成

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 理论基础 生成对抗网络(Generative Adversarial Networks,GAN)是近年来深度学习领域的一个热点方向。 GAN并不指代某一个具体的神经网络&#xff0c;而是指一类基于博弈思想而设计的神经网络。…

22.4、Web应用漏洞分析与防护

目录 Web应用安全概述DWASP Top 10Web应用漏洞防护 - 跨站脚本攻击XSSWeb应用漏洞防护 - SQL注入Web应用漏洞防护 - 文件上传漏洞Web应用漏洞防护 - 跨站脚本攻击XSS Web应用安全概述 技术安全漏洞&#xff0c;主要是因为技术处理不当而产生的安全隐患&#xff0c;比如SQL注入…

软件的生命周期和需求

什么是软件的生命周期? 定义(描述) --> 创建 --> 使用 --> 销毁 (这一整个过程就是事物的生命周期) 生命周期 那么软件的生命周期又分为哪些呢? 一共分为十步: 可行性研究: 通过分析软件开发要求,确定软件项目的性质、目标和规模,得出可行性研究报告,如果可行性研…

深入理解DeepSeek与企业实践(二):32B多卡推理的原理、硬件散热与性能实测

前言 在《深入理解 DeepSeek 与企业实践&#xff08;一&#xff09;&#xff1a;蒸馏、部署与评测》文章中&#xff0c;我们详细介绍了深度模型的蒸馏、量化技术&#xff0c;以及 7B 模型的部署基础&#xff0c;通常单张 GPU 显存即可满足7B模型完整参数的运行需求。然而&…

Java 字符编码与解码:深入理解 Charset 类

目录 引言 一、什么是字符集&#xff08;Charset&#xff09;&#xff1f; 二、Charset 类的核心功能 1. 获取字符集实例 2. 编码与解码 示例1&#xff1a;字符串转字节数组 示例2&#xff1a;处理不同字符集的乱码问题 3. 字符集检测与支持 三、Charset 类的常用方法…

Redis7.0八种数据结构底层原理

导读 本文介绍redis应用数据结构与物理存储结构,共八种应用数据结构和 一. 内部数据结构 1. sds sds是redis自己设计的字符串结构有以下特点: jemalloc内存管理预分配冗余空间二进制安全(c原生使用\0作为结尾标识,所以无法直接存储\0)动态计数类型(根据字符串长度动态选择…

本地Deepseek-r1:7b模型集成到Google网页中对话

本地Deepseek-r1:7b网页对话 基于上一篇本地部署的Deepseek-r1:7b&#xff0c;使用黑窗口对话不方便&#xff0c;现在将本地模型通过插件集成到Google浏览器中 安装Google插件 在Chrome应用商店中搜索page assis 直接添加至Chrome 修改一下语言 RAG设置本地运行的模型&#…

【设计模式】【行为型模式】观察者模式(Observer)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 欢迎点赞、收藏、关注&#xff0c;跟上我的更新节奏 &#x1f3b5; 当你的天空突…

gitlab Webhook 配置jenkins时“触发远程构建 (例如,使用脚本)”报错

报错信息&#xff1a; <html> <head> <meta http-equiv"Content-Type" content"text/html;charsetISO-8859-1"/> <title>Error 403 No valid crumb was included in the request</title> </head> <body><h2…

AI赋能前端开发:薪资潜力无限的未来

在当今竞争激烈的就业市场&#xff0c;掌握AI写代码工具等AI技能已经成为许多专业人士提升竞争力的关键。尤其在快速发展的前端开发领域&#xff0c;AI的应用更是日新月异&#xff0c;为开发者带来了前所未有的机遇。高薪职位对熟练掌握AI技术的前端开发者的需求与日俱增&#…

外包干了4年,技术退步太明显了。。。。。

先说一下自己的情况&#xff0c;本科生生&#xff0c;20年通过校招进入武汉某软件公司&#xff0c;干了差不多4年的功能测试&#xff0c;今年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能…

平面与平面相交算法杂谈

1.前言 空间平面方程&#xff1a; 空间两平面如果不平行&#xff0c;那么一定相交于一条空间直线&#xff0c; 空间平面求交有多种方法&#xff0c;本文进行相关讨论。 2.讨论 可以联立方程组求解&#xff0c;共有3个变量&#xff0c;2个方程&#xff0c;而所求直线有1个变量…

【状态空间方程】对于状态空间方程矩阵D≠0时的状态反馈与滑模控制

又到新的一年啦&#xff0c;2025新年快乐~。前几个月都没更新&#xff0c;主要还是因为不能把项目上的私密工作写进去&#xff0c;所以暂时没啥可写的。最近在山里实习&#xff0c;突然想起年前遗留了个问题一直没解决&#xff0c;没想到这两天在deepseek的加持下很快解决了&am…

LearningFlow:大语言模型城市驾驶的自动化策略学习工作流程

25年1月来自香港科技大学广州分校的论文“LearningFlow: Automated Policy Learning Workflow for Urban Driving with Large Language Models”。 强化学习 (RL) 的最新进展表明其在自动驾驶领域具有巨大潜力。尽管前景光明&#xff0c;但诸如手动设计奖励函数和复杂环境中的…

大语言模型多代理协作(MACNET)

大语言模型多代理协作(MACNET) Scaling Large-Language-Model-based Multi-Agent Collaboration 提出多智能体协作网络(MACNET),以探究多智能体协作中增加智能体数量是否存在类似神经缩放定律的规律。研究发现了小世界协作现象和协作缩放定律,为LLM系统资源预测和优化…

【OpenCV】双目相机计算深度图和点云

双目相机计算深度图的基本原理是通过两台相机从不同角度拍摄同一场景&#xff0c;然后利用视差来计算物体的距离。本文的Python实现示例&#xff0c;使用OpenCV库来处理图像和计算深度图。 1、数据集介绍 Mobile stereo datasets由Pan Guanghan、Sun Tiansheng、Toby Weed和D…

PT8032 3 通道触摸 IC

1. 概述 PT8032 是一款电容式触摸控制 ASIC &#xff0c;支持 3 通道触摸输入 ,2 线 BCD 码输出。具有低功耗、 高抗干扰、宽工作电压范围、高穿透力的突出优势。 2. 主要特性 工作电压范围&#xff1a; 2.4~5.5V 待机电流约 9uAV DD5V&CMOD10nF 3 通道触…

像指针操作、像函数操作的类

像指针一样的类。把一个类设计成像一个指针。什么操作符运用到指针上&#xff1f; 使用标准库的时候&#xff0c;里面有个很重要的东西叫容器。容器本身一定带着迭代器。迭代器作为另外一种智能指针。迭代器指向容器里的一个元素。迭代器用来遍历容器。 _list_iterator是链表迭…

Pikachu–XXE漏洞

Pikachu–XXE漏洞 一、XML基础概念 XML文档结构由XML声明&#xff0c;DTD(文档类型定义)&#xff0c;文档元素三部分构成&#xff01; #XML是可扩展标记语言(Extensible Markup Language),是设计用来进行数据的传输与存储。 #eg: <!--XML声明--><!--指明XML文档的版…