From f1313598c31b86c5d5b168223b4e9bac4559efa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E5=B9=BF=E7=AB=A0?= Date: Tue, 21 Dec 2021 18:44:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20'=E6=8A=80=E6=9C=AF?= =?UTF-8?q?=E8=A7=84=E8=8C=83/=E6=95=B0=E6=8D=AE=E5=BA=93=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E8=A7=84=E8=8C=83=5Fv1.0.4.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加索引规范,表列选择 --- 技术规范/数据库设计规范_v1.0.4.md | 70 ++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/技术规范/数据库设计规范_v1.0.4.md b/技术规范/数据库设计规范_v1.0.4.md index 1197002..98add42 100644 --- a/技术规范/数据库设计规范_v1.0.4.md +++ b/技术规范/数据库设计规范_v1.0.4.md @@ -163,6 +163,7 @@ ENTITY 表示业务实体名称,可以根据需要有多个单词组成(1-3 视图的命名以V_开头 ##### Ø规范:视图其它命名规范 + 参考表的命名规范 ##### Ø建议:视图的列名 @@ -170,6 +171,9 @@ ENTITY 表示业务实体名称,可以根据需要有多个单词组成(1-3 一般与基表一致,但是根据需要可以与基表的列名不同。 +## 索引命名规范 +##### Ø规范:前缀规范 +索引的命名以IDX_开头,中间接表名,后面接字段名,如:IDX_TRENTBASE_PRIPID # 基本设计规范 @@ -286,3 +290,69 @@ DDL定义必须符合本设计规范,通过脚本校验工具(规避关键 > 1. 表内的每一个记录都只能被表达一次; > 2. 表内的每一个记录都应该被唯一的标识(有唯一键); > 3. 表内不应该存储依赖于其他键的非键信息。 + + +# 表的优化与列类的选择 +总结:数据库优化无非就两个方面:“空间换时间,时间换空间”。几十年前内存比较小,那个时候写程序就是一个字节一个字节的扣,看谁用的内存少, 现在硬件都是廉价的,1T的固态加上上百G的内存都不算什么,所以现在都是什么东西都是往内存一扔,如,以前有1G的文本,要统计数量,这个在现在就比较落伍了,直接往内存一扔,暴力统计下就可以了。第三点就是磁盘上多费点,换取时间的取胜。 + +1、定长与变长分离 +如:id int,占4个字节,char(4)占4和字符长度,也是定长。 + +即每一单元的值的字节是固定的 +核心且常用字段,宜建成定长,放在一张表 +如:用户姓名,等级是常用的,放在一张表里面,而E-mail,电话这些信息要点进去才能看,可以放在另外一张表 + + +而varchar,text,blob这种变长字段,合适存放一张表,并用主键和核心表关联起来 + +2、常用字段和不常用字段要分离 +需要结合网站具体的业务来分析,分析字段的查询场景,查询频率低的字段,拆分出来。 + +3、在一对多需要关联统计的字段上,添加冗余字段,用于统计分析 +数据库设计一般有范式,范式越高,表就拆分的越细,但是这样设计不好,我们在设计中一般是反范式。 +比如论坛,栏目,下面有个统计今日发文的数量,一般是 两表联合查询,这样比较消耗资源,我们可以添加一个【数量】的字段,每次发文就加1,每天清零,这样增加速度 + +列类型的选择 +1、字段类型的优先级: +整型>date,time>char>varchar>text +列的特点分析: +1>整型:定长,没有国家、地区之分,没有字符集的差异 +比如:tinyint 1,2,3,4,5 <----> char(1) a,b,c,d,e +从空间上,都是占用1个字节,但是 order by 排序,前者快 +原因:后者需要考虑字符集与校对集(排序规则、大小写) +比如【 a B c D】 我们正常来说排序就是【 a B c D】 ,但是计算机是【 B D a c】 + +2>time定长,运算快,节省空间,考虑失去,写sql时不方便 where>'2005-10-12' +3>enum 能起约束表值的目的,内部用整数型来存储,单与char联查时,内部要经历串与值的转化 +4>char 定长, 考虑字符集和排序,校对集 +5>varchar,不定长,要考虑字符集的转换与排序时的校对集,速度慢 +6>text 等大字段 无法使用内存临时表(排序操作只能在磁盘上进行) + +以性别为例: +char(1),3个字长字节 +enum('男','女') //内部转成数字来存,多了一个转换过程 +tingint ,//0 1 2//定长字节 + +2、够就行,不要慷慨 +原因:大的字段浪费内存,影响速度 +以年龄为例tinyint unsigned not null,可以存储255岁,足够,用int浪费了3个字节 +以varchar(100),varchar(300)存储相同的内容,单在表联查时,varchar(300)要花更多内存 + + +3、尽量避免使用NULL()--mysql数据库的 +原因:NULL,不利于索引,要用特殊的字节来标注; +在磁盘上占据的空间其实更大(mysql5.7已对null做了改进,但查询还是不便) + +# 索引 +数据库查询只会用到一个索引 + +1、在where 条件常用的列上,都加上索引 +例:where id=3 and price>100 //查询栏目3,价格为100元以上的商品 +误:id上和price上都加上索引 +答:只能用上id或price索引,因为是独立的索引,同时只能用上1个 + +2、在多列上建立索引后,查询哪个列,索引都将发生作用 +误:多列索引上,索引发挥作用,需要满足左前提要求 + +# 表更新 +1、所有的执行语句必须加上事务,确定没有问题才能提交,更新数据范围不能超过100列,如果超过这个数,就必须DBA联系处理 \ No newline at end of file