热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于数据库设计的建议和注意事项

本文提供了关于数据库设计的建议和注意事项,包括字段类型选择、命名规则、日期的加入、索引的使用、主键的选择、NULL处理、网络带宽消耗的减少、事务粒度的控制等方面的建议。同时还介绍了使用WindowFunctions进行数据处理的方法。通过遵循这些建议,可以提高数据库的性能和可维护性。

一、命名规范

1. DB object: database, schema, table, view, index, function, trigger等名称
(1) 建议使用小写字母、数字、下划线的组合
(2) 建议不使用双引号即"包围,除非必须包含大写字母或空格等特殊字符
(3) 长度不能超过63个字符
(4) 禁止使用 
SQL 关键字,例如 type, order 

2. table能包含的column数目,根据字段类型的不同,数目在 250 到 1600 之间

3. 临时或备份的DB object:table,view ,建议加上日期,table_xxx_20150826

4. index命名规则为表名_列名_idx,student_name_idx, 建议不显式给出index name,使用DBMS系统默认给出的index name, create index ON student (name);则默认给出student_name_idx

二、Column设计

1. 建议能用varchar(N) 就不用char(N),以利于节省存储空间

2. 建议能用varchar(N) 就不用text,varchar

3. 建议使用default NULL,而不用default '',以节省存储空间,

4. 建议使用ip4,ip4r,ip6,ip6r,ipaddress,iprange 来存储IP,IP范围;使用macaddr来存储MAC (Media Access Control) address

5. 建议使用timestamp with time zone(timestamptz),而不用timestamp without time zone,避免时间函数在对于不同时区的时间点返回值不同,也为业务国际化扫清障碍

6. 建议使用NUMERIC(precision, scale)来存储货币金额和其它要求精确计算的数值而不建议使用real, double precision

7. 建议使用hstore 来存储非结构化,key-value 键值型,对数不定的数据

8. 建议使用ltree 来存储 Top.中国.北京.天安门 这种树状层次结构 数据

9. 建议使用json 来存储JSON (Javascript Object Notation) data

10. 建议使用Geometric Types 结合PostGIS来实现地理信息数据存储及操作

11. 建议使用如下range类型代替字符串或多列来实现范围的存储

三、Constraints设计

1. 建议每个table都有主键;

2. 建议不要用有业务含义的名称作为主键,比如身份证或者国家名称,尽管其是unique

3. 建议主键的一步到位的写法:id serial primary key id bigserial primary key

四、Index设计

1. PostgreSQL 提供的index类型: B-tree, Hash, GiST (Generalized Search Tree), SP-GiST (space-partitioned GiST) and GIN (Generalized Inverted Index),目前不建议使用Hash, SP-GiST

2. 建议create 或 drop index ,加 CONCURRENTLY参数,这是个好习惯,达到与写入数据并发的效果

3. 建议对于频繁update, delete的包含于index 定义中的columntable, create index CONCURRENTLY , drop index CONCURRENTLY 的方式进行维护其对应index

4. 建议用unique index 代替unique constraints,便于后续维护

5. 建议不要建过多index,一般不要超过6个,核心table(产品,订单)可适当增加index个数

五、关于NULL

1. NULL 的判断:IS NULL IS NOT NULL

2. 注意boolean 类型取值 truefalse, NULL

3. 小心NOT IN 集合中带有NULL元素

postgres=# SELECT * FROM (VALUES(1),(2)) v(a) ; 
a
---
1
2
(2 rows)
postgres=# select 1 NOT IN (1, NULL);
?column?
----------
f
(1 row)
postgres=# select 2 NOT IN (1, NULL);
?column?
----------

(1 row)
postgres=# SELECT * FROM (VALUES(1),(2)) v(a) WHERE a NOT IN (1, NULL);
a
---
(0 rows)

可见,出现这种情况的根本原因在于SELECT只返回WHERE中判断条件结果为true的数据

4. 建议对字符串型NULL值处理后,进行 || 操作

postgres=# select NULL||'PostgreSQL'; 
?column?
----------

(1 row)
postgres=# select coalesce(NULL,'')||'PostgreSQL';
?column?
------------
PostgreSQL
(1 row)


5. 建议对hstore 类型进行处理后,进行 || 操作,避免被NULL吃掉

postgres=# select  NULL::hstore || ('key=>value') ; 
?column?
----------

(1 row)
postgres=# select coalesce(NULL::hstore, hstore(array[]::varchar[])) || ('key=>value') ;
?column?
----------------
"key"=>"value"
(1 row)
postgres=# select coalesce(NULL::hstore,''::hstore) || ('key=>value') ;
?column?
----------------
"key"=>"value"
(1 row)


六、其他注意事项

1. 建议对DB object 尤其是COLUMN COMMENT,便于后续维护

2. 建议非必须时避免select *,只取所需字段,以减少网络带宽消耗,避免表结构变更对程序的影响

3. 建议update 时尽量做 <> 判断,比如update table_a set column_b = c where column_b <> c

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

5. 建议向大sizetableadd column时,将 alter table t add column col datatype not null default xxx;分解为如下,避免填充default值导致的过长时间锁表

alter table t add column col datatype ; 
alter table t alter column col set default xxx;
update t set column = default where id = 1;
..................
update t set column = default where id = N;
------此处,可以用先进的\watch来刷------即
update table t set column= DEFAULT where id in ( select id from t where column is null limit 1000 ) ; \watch 3
alter table t alter column col set not null;

6. 建议执行DDL,比如CRAETE,DROP,ALTER 不要显式的开transaction, 因为加lockmode非常高,极易产生deadlock

7. 建议复杂的统计查询可以尝试窗口函数 Window Functions

8. 建议发给PostgrSQL DBA review 及 执行的SQL,无论是使用pgadmin这种图形化工具,还是pg_dump 这种命令行工具生成的SQL,都去掉注释(--之后的部分),双引号"及alter owner等冗余或不应该带到线上生产的dev/beta DB中的信息


推荐阅读
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • PostgreSQL13.1中文手册 ... [详细]
  • MySQL 数据库基础学习 一、SQL的作用及分类 二、数据类型 三、存储引擎  (建库建表、数据插入等))
    MySQL 数据库基础学习 一、SQL的作用及分类 二、数据类型 三、存储引擎 (建库建表、数据插入等)) ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 本文介绍了如何使用PHP代码将表格导出为UTF8格式的Excel文件。首先,需要连接到数据库并获取表格的列名。然后,设置文件名和文件指针,并将内容写入文件。最后,设置响应头部,将文件作为附件下载。 ... [详细]
  • 知识图谱表示概念:知识图谱是由一些相互连接的实体和他们的属性构成的。换句话说,知识图谱是由一条条知识组成,每条知识表示为一个SPO三元组(Subject-Predicate-Obj ... [详细]
  • mysql自动打开文件_让docker中的mysql启动时自动执行sql文件
    本文提要本文目的不仅仅是创建一个MySQL的镜像,而是在其基础上再实现启动过程中自动导入数据及数据库用户的权限设置,并且在新创建出来的容器里自动启动My ... [详细]
  • 1Oracle三层权限体系【复习】1、Oracle的权限体系划分为三个层次 ... [详细]
  • MySQL锁--(深入浅出读书笔记)
    MySQL锁的概述1.针对不同的引擎,采用不同的锁机制;(表锁,页面锁,行锁)myisam和memory存储引擎:表级锁;BOB存储引擎:页面锁,表级 ... [详细]
  • TableAPI报一下异常:FieldtypesofqueryresultandregisteredTableSink
    报错信息如下:Exceptioninthread“main”org.apache.flink.table.api.ValidationException:Fieldtypesofq ... [详细]
  • java开发公众号,java自学网公众号
    本文目录一览:1、JAVA微信公众号开发回复消息能回复多条吗?具体怎么代码实现? ... [详细]
author-avatar
陈杰铭雅意
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有