您当前的位置:首页 > 电脑百科 > 数据库 > 百科

数据库规范开发使用规范

时间:2023-01-17 14:45:23  来源:今日头条  作者:时空过客vicyuppie

1 概述

1.1 目的

鉴于以往各方在数据库设计和使用方面的经验总结,本规范的以下内容是为了保证数据库设计及使用的质量,规范数据库设计及使用习惯,从而提高程序开发效率,提升平台服务质量。长期坚持并严格遵守规范,从长远来看,于公于私都是双赢的事情。

1.2 适用范围

  • 程序开发人员
  • 数据库开发人员
  • 其他需要使用数据库的人员

1.3 现有数据库的问题

目前数据库中存在的问题:

  • 分库太多,没有明确的分库标准,随意性太大
  • 重复设计相同业务性质的表
  • 表名及字段名没有遵循统一规范的命名规范
  • 核心业务的操作日志记录不全
  • 枚举字段没有码表
  • 大表需要分表
  • 字段数据类型很多没有遵循最小原则

1.4 概念说明

  • 范式:关系数据库中,设计表的时候,字段间关系要满足的不同程度的要求。各范式满足:5NF⊂4NF⊂BCNF⊂3NF⊂2NF⊂1NF。目前数据库设计满足3NF即可。
  • 反范式:指的是通过增加冗余或重复的数据来提高数据库的读性能

l 强制: 必须遵守。

l 推荐: 最佳实践,建议遵守。

l 参考: 可选遵守。

2 数据库设计规范

2.1 总体目标

数据库设计总体目标:

      • 规范性:数据库表设计总体遵循3NF,减少不必要的冗余;
      • 高效性:兼顾范式与反范式,平衡读写矛盾。
      • 紧凑性:表结构宽度适中,数据冷热分离,数据类型简单化、最小化,提高空间和资源利用率
      • 易用性:结构严谨,逻辑清晰,使用方便,容易理解。
      • 安全性:合理分配权限,严格控制数据库连接,安全合规使用数据库。

2.2 设计规范

2.2.1 表设计规范

  • 【强制】如无必要,建表时一律采用Innodb存储引擎
  • 【强制】表名不使用复数名词。
  • 【强制】每个innodb表必须有主键,主键字段建议使用BIGINT类型,自增,步长为1。
  • 【强制】表中的行记录超过1000万,要采用分表策略,控制单表容量在百万级别。
  • 【推荐】数据一旦落库,禁止物理删除,通过控制IS_DELETE字段进行逻辑删除
  • 【强制】每个表必须具备以下字段:

`CREATE_TIME` datetime NOT NULL COMMENT '创建时间'

`CREATE_ACCT_ID` bigint(20) NOT NULL COMMENT '创建人账户ID'

`UPDATE_TIME` datetime NOT NULL COMMENT '更新时间'

` UPDATE_ACCT_ID` bigint(20) NOT NULL COMMENT '更新人账户ID'

  • 【强制】一个表中的字段不要太多,不要超过80个。如果表的宽度过大应考虑冷热数据分离,减小表的宽度。
  • 【推荐】谨慎使用分区表。
  • 【推荐】平衡范式与反范式

在平衡范式与反范式的过程中,应当考虑数据在业务场景中的使用方式,对于访问频次高而修改频次很低的数据,设计过程中可以考虑反范式处理,但禁止冗余varchar 超长字段,更不能是 text 字段。对于修改频次高而访问频次很低的数据,设计过程中应当遵循3NF。数据库表的整体设计还是以3NF为基础,然后再根据整个应用系统的需要反范式化数据。

2.2.2 字段设计规范

      • 【强制】使用能正确存储和表示数据的最小类型。如果不确定需要什么数据类型,则选择不会超出范围的最小类型。
      • 【强制】要使用更简单的数据类型。如,相比字符串整数在比较的时候代价更小。
      • 【强制】如无特殊需求,字段要在SQL建表脚本中要明确定义为 NOT NULL。
      • 【强制】所有存储字符的字段使用varchar(n)类型,且使用utf8mb4_bin让存储内容大小写敏感。
      • 【强制】自增主键除了处理主从关系外不要在业务场景中使用,以防sql注入,应该增加唯一键字段来满足需求。
      • 【强制】表间建立关系的字段,比如主从表的主外键,字段数据类型及长度要完全一致且名称一样。
      • 【强制】禁止使用set,enum, boolean类型,应用tinyint类型来替代。
      • 【强制】状态字段也用tinyint类型来表示。
      • 【强制】数据库中所有布尔性质的字段数值0表示为假,数值1表示为真。
      • 【强制】统一使用datetime类型存储时间,禁止使用字符串存储日期型的数据。
      • 【强制】财务的相关金额使用decimal(m,n)类型。
      • 【强制】禁止使用二进制类型(tinyblob,blob,mediumblob,longblob)保存大文本、图片和文件,应使用其他方式存储,如文件系统,数据库只保存其地址信息。
      • 【强制】尽量不要使用TEXT数据类型,MySQL的varchar类型支持65535字节,满足大多数场景。如必须使用,建议把TEXT列分离到单独的扩展表中。
      • 【强制】禁止使用float、double类型。
      • 【推荐】凡是可能被索引的字段,必须定义为NOT NULL

2.2.3 其他设计规范

Mysql中键包括primary key, unique key, foreign key 等,是数据库的物理结构,有两方面的用途:一是约束,侧重于数据库的完整性约束,二是索引,用于优化查询。换言之,每个键除了规范约束的功能,同时也有索引的功能。

键和索引设计要遵循如下原则:

      • 【强制】每个Innodb 表必须有一个主键。
      • 【强制】禁止在数据库中设计外键约束,外键约束在程序层面实现。
      • 【强制】禁止在区分度很差的字段上建索引。
      • 【参考】尽可能避免使用复合键。
      • 【参考】一个表中组合主键的字段个数尽可能少。
      • 【参考】对于索引选择性高的列使用B-Tree索引。
      • 【参考】HASH索引只适用于相等比较。
      • 【推荐】避免在WHERE条件中将字段用于表达式或函数中,这样不会在该列上使用索引。
      • 【推荐】建组合索引的时候,区分度最高的在最左边。
      • 【推荐】防止因字段类型不同造成的隐式转换,导致索引失效。
      • 【推荐】不要索引大型字段(有很多字符的字段)。
      • 【推荐】在常用的小型表中不必要建立索引。
      • 【推荐】每张表的索引数量不超过5个。

2.3 命名规范

2.3.1 总则

      • 【强制】所有命名采用26个英文大小写字母和0-9这十个自然数,以下划线_分割。不能出现其他字符(注释除外);
      • 【强制】禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,所以字段名称需要慎重考虑。
      • 【强制】名称长度不超过64个字符,尽量控制在30个字符以内;
      • 【强制】实际名称尽量描述实体的内容,由英文单词、单词组合或单词缩写组成,不要以数字和_开头;
      • 【强制】名称不能与SQL关键字相同;
      • 【强制】对象名称尽量短;
      • 【强制】所有命名要以见名知意为准则;

2.3.2 数据库命名

数据库名称以小写英文字母和数字命名,以下划线_分割,名称要涵盖主要的业务职能,长度不要超过10个字符。

2.3.3 表命名

<项目名称>_<模块名称>_<表名称>

表名称要以小写英文字母和数字命名,以下划线_分割,能简单描述该表的基本职能,表名不使用复数名词。

项目名称要简短,最好用字母缩写。

模块名称要简要,可以用缩写,可以用核心词拼接。

2.3.4 字段命名

字段名称以大写英文字母和数字命名,以下划线_分割,字段名称及其注释要指明业务含义,做到用词准确,表达无歧义。

2.3.5 其他命名

      • 唯一键

UK_<构成主键的字段名称>

      • 索引

IDX_<构成索引的字段名称>

3 SQL开发规范

3.1 脚本编写规范:

  • 【强制】禁止超过三个表的关联join ,禁止跨库做关联join。
  • 【强制】在表查询中,禁止使用 * 作为查询的字段列表,必须明确指定所需字段。
  • 【强制】查询脚本中,必须为每个表提供别名,每个字段前必须显式指定表的别名前缀,如SELECT a.COL1,a.COL2,b. COL1,b.COL2 FROM tab1 a join tab2 b on a.COL1 = b.COL1;
  • 【强制】INSERT插入语句必须有字段列表且包含该表所有NOT NULL字段,禁止使用default。如:
INSERT INTO `goods`.`goods_info`(`GOODS_ID`, `ITEM_ID`, `SOURCE_TYPE`, `PUBLISH_POSITION`, `STORE_ID`, `SELLER_GOODS_ID`, `SELLER_SNAPSHOT_GOODS_ID`, `CHANNEL_ID`, `AVAILABLE_STOCK`, `DAILY_CAPACITY`, `MIN_PURCHASE_NUM`, `MATERIAL_ID`, `MATERIAL_CODE`, `MATERIAL_SNAPSHOT_ID`, `SALE_CNT`, `UNIT_PRICE`, `SUPPLY_PRICE`, `STATUS`, `SALE_STATUS`, `STOP_SALE_REASON`, `MOD_TIME`, `MOD_ACCT_ID`, `CREATE_TIME`, `CREATE_ACCT_ID`, `AppROVE_TIME`, `APPROVE_ACCT_ID`, `APPROVE_DESC`, `WARNING_NUM`, `UNQUALIFIED_STOCK`, `PLATFORM_UNQUALIFIED_STOCK`, `PLATFORM_QUALIFIED_STOCK`, `WMS_STOCK`) VALUES (100000000, 100000000, 1, 0, NULL, 100000000, 100000000, 1, 963329.000, NULL, NULL, 17, '1', 17, 420524.000, NULL, 89.04, 1, 1, NULL, '2021-02-02 09:22:34', 100011805, '2018-06-22 14:36:35', 302, NULL, NULL, NULL, 1.000, 0.000, 0.000, 830955.000, 0.000);
  • 【推荐】Sql脚本中每个表名之前要指定所在库,如:库名.表名。

3.2 WHERE条件规范:

  • 【强制】禁止sql脚本中出现数据类型的隐式转换。
  • 【强制】对同一列对象进行or 判断时,使用in 替代or;不同字段的值进行or判断是,用UNION ALL替代or。
  • 【强制】禁止在WHERE 从句中对列进行函数转换和计算。
  • 【推荐】避免WHERE条件中使用左模糊或者全模糊。
  • 【推荐】控制全表扫描范围,控制在30%左右。

3.3 脚本使用行为规范:

  • 【强制】程序里不允许出现DELETE * FROM 表名;TRUNCATE TABLE 表名;DROP TABLE 表名;DROP DATABASE库名;等高危操作。
  • 【强制】在确定无重复值时使用UNION ALL而非UNION,UNION会去重,代价高。
  • 【强制】超过100万行数据的批量操作(update,delete,insert),分多次进行。
  • 【推荐】Insert操作优先选择批量插入,但VALUES的个数应在500个以内。
  • 【强制】禁止在数据库中存储明文密码。
  • 【强制】禁止使用order by rand() 进行随机排序。
  • 【强制】避免使用子查询,可以把子查询优化为join关联操作。
  • 【推荐】连表join查询的时候,将过滤后结果集较小的表作为驱动表。
  • 【推荐】表之间的关联条件放到JOIN… ON里面而不是WHERE子句里面。
  • 【推荐】禁止单条SQL语句同时更新多个表。
  • 【推荐】分组,排序,集合是比较复杂的运算,应避免使用。

减少或避免使用临时表。当ORDER BY子句和GROUP BY子句同时出现且字段列表不同则会自动创建临时表;当ORDER BY子句或GROUP BY子句的字段列表中的字段超出驱动表,则自动创建临时表。

减少或避免排序,如无法避免,尽量在索引列中完成排序。

避免HAVING子句,尽量将条件放到WHERE子句中。

  • 【推荐】排序字段尽量选择驱动表的字段,否则排序无法利用索引。
  • 【参考】不要使用count(列名)或count(常量)来替代count(*),count(*)是SQL 92定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。

说明: count( * ) 会统计值为 NULL 的行,而count(列名)不会统计此列为 NULL 值的行。

  • 【参考】count(distinct col) 计算该列除NULL之外的不重复行数,注意count(distinct col 1, col 2 ) 如果其中一列全为 NULL ,那么即使另一列有不同的值,也返回为 0。
  • 【参考】当某一列的值全是NULL时,count(col) 的返回结果为0,sum(col)的返回结果为NULL。
  • 【强制】禁止使用存储过程,存储过程难以调试和扩展,移植性差。
  • 【强制】禁止使用触发器。
  • 【强制】数据订正(特别是删除、修改记录操作)时,要先 select ,避免出现误删除,确认无误才能执行更新语句。
  • 【推荐】利用延迟关联或者子查询优化超多分页场景。MySQL 并不是跳过OFFSE行,而是取 OFFSET + N 行,然后返回放弃前OFFSE行,返回N行,那当OFFSET特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过特定阈值的页数进行SQL改写。

正例:先快速定位需要获取的 id 段,然后再关联:

SELECT a.* FROM 表 1 a, (SELECT id FROM表1 WHERE条件 LIMIT OFFSET, N) b where a.id=b.id;

  • 【推荐】 SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts最好。

说明:1 )consts 单表中最多只有一个匹配行 ( 主键或者唯一索引 ) ,在优化阶段即可读取到数据。2 )ref 指的是使用普通的索引 (normal index) 。3 )range 对索引进行范围检索。

反例: explain 表的结果, type = index ,索引物理文件全扫描,速度非常慢,这个 index 级别比较 range 还低,与全表扫描相差不多。

4 数据库帐号使用规范

  • 【强制】对于连接数据库账号,遵循权限最小原则。
  • 【强制】禁止给程序使用的账号授予super 权限。
  • 【强制】禁止除生产服务器之外的环境连接生产数据库。
  • 【强制】禁止私自导出、传播生产数据。


Tags:   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
16个Redis常见使用场景总结
来源:blog.csdn.net/qq_39938758/article/details/105577370目录 缓存 数据共享分布式 分布式锁 全局ID 计数器 限流 位统计 购物车 用户消息时间线timeline 消息...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
一篇文章教会你使用Python中三种简单的函数
所谓函数,就是指:把某些特定功能的代码组成为一个整体,这个整体就叫做函数。一、函数简介所谓函数,就是指:把某些特定功能的代码组成为一个整体,这个整体就叫做函数。二、函数定义...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
聊聊Rust里面的数据类型
嘿,朋友们!今天我们来聊聊Rust里面的数据类型。你知道吗?Rust的数据类型可是很重要的哦,它们帮助我们定义变量和函数可以处理什么样的数据。基本数据类型首先,让我们来看看Rust提...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
C++中的外部模板及其在当前编译文件中的实例化
在C++中,模板是一种泛型编程的工具,它允许程序员以一种类型无关的方式编写代码。然而,模板的一个常见问题是它们会导致编译时间增加,特别是在大型项目中,当多个源文件包含相同的...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
一篇文章带你了解Python的分布式进程接口
在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上。一、前言在Thread和Process中,应当优...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
网络安全行业的春天何时来?
2023年下半年开始,网络安全从业人员都感受到了网安行业的寒冬,但是其实前奏并不是此刻,只是涉及到大量裁员关乎自身而人人感同身受。从近五年各个网络安全上市公司财报可以发现...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
Linux获取Redis 性能指标方法
一、监控指标&Oslash; 性能指标:Performance&Oslash; 内存指标: Memory&Oslash; 基本活动指标:Basic activity&Oslash; 持久性指标: Persistence&Oslash; 错误指标:Error二、监...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
Redis与缓存一致性问题
缓存一致性问题是在使用缓存系统,如Redis时经常遇到的问题。当数据在原始数据源(如数据库)中发生变化时,如何确保缓存中的数据与数据源保持一致,是开发者需要关注的关键问题。一...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
10余所高校公布强基计划,今年有哪些变化?
今天,中国人民大学、中国农业大学、复旦大学、武汉大学、山东大学、吉林大学、重庆大学、大连理工大学发布了2024年强基计划招生简章。目前,已有10余所高校发布了招生简章。它...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
腾讯首款自研 Switch 游戏上线:《腾讯扣叮-编程第一课》
IT之家 4 月 11 日消息,腾讯 Nintendo Switch 今日官宣,Nintendo Switch 趣味编程学习软件 &mdash;&mdash;《腾讯扣叮-编程第一课》已于今日上架 Nintendo e 商店,建议零售价 4...【详细内容】
2024-04-11  Search:   点击:(2)  评论:(0)  加入收藏
▌简易百科推荐
向量数据库落地实践
本文基于京东内部向量数据库vearch进行实践。Vearch 是对大规模深度学习向量进行高性能相似搜索的弹性分布式系统。详见: https://github.com/vearch/zh_docs/blob/v3.3.X/do...【详细内容】
2024-04-03  京东云开发者    Tags:向量数据库   点击:(5)  评论:(0)  加入收藏
原来 SQL 函数是可以内联的!
介绍在某些情况下,SQL 函数(即指定LANGUAGE SQL)会将其函数体内联到调用它的查询中,而不是直接调用。这可以带来显著的性能提升,因为函数体可以暴露给调用查询的规划器,从而规划器...【详细内容】
2024-04-03  红石PG  微信公众号  Tags:SQL 函数   点击:(4)  评论:(0)  加入收藏
如何正确选择NoSQL数据库
译者 | 陈峻审校 | 重楼Allied Market Research最近发布的一份报告指出,业界对于NoSQL数据库的需求正在持续上升。2022年,全球NoSQL市场的销售额已达73亿美元,预计到2032年将达...【详细内容】
2024-03-28    51CTO  Tags:NoSQL   点击:(14)  评论:(0)  加入收藏
为什么数据库连接池不采用 IO 多路复用?
这是一个非常好的问题。IO多路复用被视为是非常好的性能助力器。但是一般我们在使用DB时,还是经常性采用c3p0,tomcat connection pool等技术来与DB连接,哪怕整个程序已经变成以...【详细内容】
2024-03-27  dbaplus社群    Tags:数据库连接池   点击:(13)  评论:(0)  加入收藏
八个常见的数据可视化错误以及如何避免它们
在当今以数据驱动为主导的世界里,清晰且具有洞察力的数据可视化至关重要。然而,在创建数据可视化时很容易犯错误,这可能导致对数据的错误解读。本文将探讨一些常见的糟糕数据可...【详细内容】
2024-03-26  DeepHub IMBA  微信公众号  Tags:数据可视化   点击:(7)  评论:(0)  加入收藏
到底有没有必要分库分表,如何考量的
关于是否需要进行分库分表,可以根据以下考量因素来决定: 数据量和负载:如果数据量巨大且负载压力较大,单一库单一表可能无法满足性能需求,考虑分库分表。 数据增长:预估数据增长...【详细内容】
2024-03-20  码上遇见你  微信公众号  Tags:分库分表   点击:(15)  评论:(0)  加入收藏
在 SQL 中写了 in 和 not in,技术总监说要炒了我……
WHY?IN 和 NOT IN 是比较常用的关键字,为什么要尽量避免呢?1、效率低项目中遇到这么个情况:t1表 和 t2表 都是150w条数据,600M的样子,都不算大。但是这样一句查询 &darr;select *...【详细内容】
2024-03-18  dbaplus社群    Tags:SQL   点击:(6)  评论:(0)  加入收藏
应对慢SQL的致胜法宝:7大实例剖析+优化原则
大促备战,最大的隐患项之一就是慢SQL,对于服务平稳运行带来的破坏性最大,也是日常工作中经常带来整个应用抖动的最大隐患,在日常开发中如何避免出现慢SQL,出现了慢SQL应该按照什...【详细内容】
2024-03-14  京东云开发者    Tags:慢SQL   点击:(5)  评论:(0)  加入收藏
过去一年,我看到了数据库领域的十大发展趋势
作者 | 朱洁策划 | 李冬梅过去一年,行业信心跌至冰点2022 年中,红衫的一篇《适应与忍耐》的报告,对公司经营提出了预警,让各个公司保持现金流,重整团队,想办法增加盈利。这篇报告...【详细内容】
2024-03-12    InfoQ  Tags:数据库   点击:(27)  评论:(0)  加入收藏
SQL优化的七个方法,你会哪个?
一、插入数据优化 普通插入:在平时我们执行insert语句的时候,可能都是一条一条数据插入进去的,就像下面这样。INSERT INTO `department` VALUES(1, &#39;研发部(RD)&#39;, &#39...【详细内容】
2024-03-07  程序员恰恰  微信公众号  Tags:SQL优化   点击:(20)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条