PostgreSQL数据库一些tricks
PostgreSQL自带Pgadmin客户端,可用于访问本地和远程PG库,一些tricks如下:
1、联合查询
- SELECT * FROM table1 INNER JOIN table2 ON table1.id=table2.id
- # 其中table1,table2还可以分别用SQL选择如
- SELECT * FROM (SELECT * FROM table1 where num1=2 limit 10 offset 0) a INNER JOIN (SELECT * FROM table2 where num2=4) b ON a.id=b.id
2、索引
- # 查看pg库某表table1是否使用索引
- SELECT * FROM pg_indexes WHERE tablename='table1'
- # 对table1的某一列或者几列创建索引
- CREATE INDEX table1_index ON table1(num1, num2) # table_index为建立的索引名称
- # 删除索引
- DROP INDEX table1_index
2.1 复合索引
多列复合索引的创建建议:
1、离散查询条件(例如 等值)的列放在最前面,如果一个复合查询中有多个等值查询的列,尽量将选择性好(count(distinct) 值多的)的放在前面。
2、离散查询条件(例如 多值)的列放在后面,如果一个复合查询中有多个多值查询的列,尽量将选择性好(count(distinct) 值多的)的放在前面。
3、连续查询条件(例如 范围查询)的列放在最后面,如果一个复合查询中有多个多值查询的列,尽量将输入范围条件返回结果集少的列放前面,提高筛选效率(同时也减少索引扫描的范围)。
4、如果返回的结果集非常大(或者说条件命中率很高),并且属于流式返回(或需要高效率优先返回前面几条记录),同时有排序输出的需求。建议按排序键建立索引。
3、try...except的使用
Postgres数据库中,同一事务中如果某次数据库操作中出错的话,那这个事务以后的数据库都会出错。
即
- 连接OPEN。
- try {
- try {
- 数据库操作A。
- } catch (Exception e) {
- log.error("do something");
- }
- 数据库操作B。 //此次数据操作有可能出现上面的错误。
- 事务提交commit。
- } catch (Exception ex) {
- 事务回滚rollback。
- } finally {
- 关闭连接。
- }
和
- 连接OPEN。
- try {
- 数据库操作A。
- 数据库操作B。
- 事务提交commit。
- } catch (Exception ex) {
- 数据库操作C。 //此次数据操作有可能出现上面的错误。
- 事务提交commit。
- } finally {
- 关闭连接。
- }
以上两种方式都会有问题
我们可以在某个操作出错后加入事务提交或者回滚
- try {
- 数据库操作A。
- } catch (Exception e) {
- 事务回滚或者提交;
- log.error("do something");
- }
- 数据库操作B。
- -----------------------------------------------------
- } catch (Exception ex) {
- 事务回滚或者提交;
- 数据库操作C。
- 事务提交commit。
- } finally {
- 关闭连接。
- }
4、数据库清理
4.1 日常清理(VACUUM;)
日常清理(VACUUM;),因为有大量的更新(update)"删除(delete)操作,会有大量的空间需要释放。
每日执行一次VACUUM,每周访问量低的时候执行VACUUM FULL;
- 语法结构;
- VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ]
- VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]
- FULL ------选择"完全"清理,这样可以恢复更多的空间, 但是花的时间更多并且在表上施加了排它锁。
- FREEZE ---------选择激进的元组"冻结"。
- VERBOSE --------- 为每个表打印一份详细的清理工作报告。
- ANALYZE --------- 更新用于优化器的统计信息,以决定执行查询的最有效方法。
- table ------- 要清理的表的名称(可以有模式修饰)。缺省时是当前数据库中的所有表。
- column ---------要分析的具体的列/字段名称。缺省是所有列/字段。
4.2 重建索引(REINDEX)
- 语法
- REINDEX { INDEX | TABLE | DATABASE | SYSTEM } name [ FORCE ]
描述
REINDEX命令用来重建索引。旧的索引将被删除,重新读取索引的父表中的数据来重建索引。REINDEX命令不支持并发创建索引的功能。在下面的情况下,应该重建索引:
(1)一个索引中的数据已被破坏,包含非法的数据。软件错误和硬件问题都会导致索引被损坏。
(2)索引中包含许多空的或者几乎是空的数据页。应该重建索引,回收物理存储空间。
(3)该变了索引的存储参数fillfactor的值,只有重建索引,新的参数值才能完全生效。
(4)使用CREATE INDEX CONCURRENTLY命令创建索引时遇到错误,留下一个非法的索引。
例子
(1)重建索引my_index:REINDEX INDEX my_index;
(2)重建表my_table 上的所有索引:REINDEX TABLE my_table;
(3)重建数据库中的所有索引:REINDEX DATABASE broken_db;
5、数据库、表大小查找
- # 表空间查找
- select pg_table_size('tablename')
- # 以kb、M、G等单位显示
- select pg_size_pretty(pg_table_size('tablename'))
- # 数据库查找
- select pg_database_size('database_name')
- # 查找所有数据库大小
- select pg_database.datname, pg_database_size(pg_database.datname) as size from pg_database
6、批量插入
当数据量比较大时,比如过亿的数据量要插入到数据库中,有几个策略可以提升速度:
(1)创建unlogged的表,相当于内存表。
- create unlogged table
unlogged table 的几个特点:
1、unlogged table不记录wal日志,写入速度快,备库无数据,只有结构。
2、当数据库crash后,数据库重启时自动清空unlogged table的数据。
3、正常关闭数据库,再启动时,unlogged table有数据。
4、unlogged table通常用于中间结果,频繁变更的会话数据
(2)多次insert后)再commit
比如设置500次insert后再进行一次commit
(3)开启多线程或者多进程
7、数据表字段改变数据类型
最近公司存数据遇到一个问题,给id 设为serial自增,后来发现不够用了,达到了2147483647顶峰值。当初没有考虑到这个问题,应该最初建表的时候设为bigserial就足够了,看看官网给的数据类型:
Name | Storage Size | Description | Range |
---|---|---|---|
smallint | 2 bytes | small-range integer | -32768 to +32767 |
integer | 4 bytes | typical choice for integer | -2147483648 to +2147483647 |
bigint | 8 bytes | large-range integer | -9223372036854775808 to 9223372036854775807 |
decimal | variable | user-specified precision, exact | up to 131072 digits before the decimal point; up to 16383 digits after the decimal point |
numeric | variable | user-specified precision, exact | up to 131072 digits before the decimal point; up to 16383 digits after the decimal point |
real | 4 bytes | variable-precision, inexact | 6 decimal digits precision |
double precision | 8 bytes | variable-precision, inexact | 15 decimal digits precision |
serial | 4 bytes | autoincrementing integer | 1 to 2147483647 |
bigserial | 8 bytes | large autoincrementing integer | 1 to 9223372036854775807 |
因为给id设为主键,让它自增,其实建表时serial相当于将id设为int类型,然后会新建一个sequence,对于postgresql9.6以及更早的版本,这个sequence会以bigint建表,10.0以后的版本,sequence也是int类型,即自增数据列表为1-2147483647. 不清楚可以查询一下。
` 假设建表如下:
- create table student(
- id serial PRIMARY KEY NOT NULL,
- name varchar(50)
- )
则同时会给建一个名为student_id_seq的序列表,还可以查看数据类型
- select * from student_id_seq
结果中会显示sequence的数据类型,确定是int还是bigint。
如果版本在9.6以前,只需要更改id的数据类型为bigint即可
- alter table student alter id type bigint
如果版本在10.0以后,sequence数据类型也需要更改
- alter sequence student_id_seq as bigint;
- alter table student alter id type bigint;
这样在查看数据类型,id就变味bigserial了
8、主键自增序列初始值设定
pg数据库当设定主键自增时,不管是serial还是bigserial,默认都是从1开始计数的。可是如果要指定从某个数开始计数该怎么办呢。比如从10000开始
实现起来也很简单,假设建好一张表tablename为student,主键为number_id, 要求默认从10000开始计数。则可以用以下命令实现
- # SQL命令为
- select setval('tablename_pkname_seq',10000,false);
- # 我们这里即为
- select setval('student_number_id_seq',10000,false);
9、创建数据库表时给字段添加注释
不像mysql可以直接在创建表定义字段时直接加注释,pg数据库则是在创建后用 comment on column 命令注释。
- create table example(
- date_id int not null,
- company_id bigint not null,
- staff_id bigint not null)
- comment on column example.date_id is '日期';
- comment on column example.company_id is '公司id';
- comment on column example.staff_id is '员工id';
PostgreSQL数据库一些tricks的更多相关文章
- ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库
前段时间在园子里看到了小蝶惊鸿 发布的有关绿色版的Linux.NET——“Jws.Mono”.由于我对.Net程序跑在Linux上非常感兴趣,自己也看了一些有关mono的资料,但是一直没有时间抽出时间 ...
- PostgreSQL介绍以及如何开发框架中使用PostgreSQL数据库
最近准备下PostgreSQL数据库开发的相关知识,本文把总结的PPT内容通过博客记录分享,本随笔的主要内容是介绍PostgreSQL数据库的基础信息,以及如何在我们的开发框架中使用PostgreSQ ...
- TPC-H生成.tbl文件导入postgresql数据库的坑
数据库project好好的不用主流的MySQL和Microsoft server而要求用听都没听过的postgresql (当然,可能你三个都没听过) 这里的坑主要是把生成的那八张.tbl的表导入pg ...
- PowerDesigner反向工程PostgreSQL数据库
1. 环境准备: a) 安装PowerDesigner,以PowerDesigner15.1为例 b) 安装java jdk,以jdk-7-windows-i586为例 ...
- 视频教程--ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库
说好的给园子里的朋友们录制与<ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库> 这篇博客相对应的视频,由于一个月一来没有时 ...
- Enterprise Architect的共享Respository设置,postgresql数据库
Enterprise Architect有一个很实用的共享,在设计UML图的时候,可以连接到一个数据库服务器,将所有的画图数据共享在上面,所有连到这个server的人,都可以看到 别人的图,图中的元素 ...
- PostgreSQL数据库基本配置
一.安装 首先安装PostgreSQL客户端: sudo apt-get install postgresql-client 然后,安装PostgreSQL服务器: sudo apt-get inst ...
- C#访问PostGreSQL数据库的方法 http://www.jb51.net/article/35643.htm
这次的项目中的一个环节要求我把PostGreSQL数据取出来,然后放到SqlServer里,再去处理分析. http://www.jb51.net/article/35643.htm - 我对Post ...
- C#访问postgresql数据库
最近开始做C#的DotNet的工作,因为对PostgreSQL数据库比较有兴趣,所以自己研究了一下如何访问PostgreSQL的 数据库的问题. 1.为了访问PostgreSQL数据库,需要从pgfo ...
随机推荐
- 【consul】使用学习
[consul]使用学习 转载:https://www.cnblogs.com/yangchongxing/p/10653791.html 1.下载 consul https://www.consul ...
- 【Java Web开发学习】Spring发布RMI服务
[Java 远程服务]Spring发布RMI服务 转载:https://www.cnblogs.com/yangchongxing/p/9084066.html RmiServiceExporter可 ...
- 【TCP/IP网络编程】:04基于TCP的服务器端/客户端
摘要:结合前面所讲述的知识,本篇文章主要介绍了简单服务器端和客户端实现的框架流程及相关函数接口. 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字(本 ...
- centos7 启动停止命令
apache启动systemctl start httpd停止systemctl stop httpd重启systemctl restart httpd mysql启动systemctl start ...
- OSU!
OSU! 首先,由题可知,本题是个期望题,根据期望的套路,定义f[x]为x前的答案,所以最终答案就是f[n] f[x]表示前x期望答案,即每一段的长度立方和的期望(一定要清楚) 但是三次方不好算,由于 ...
- ansible部署Tomcat
首先要准备的环境就是免密登录 这是要在ansible-playbook中所写的内容---- hosts: tomcat tasks: - name: 关闭防火墙 service: name ...
- 使用 Vue + TypeScript 时项目中常用的装饰器
目录 一.@Component 装饰器 1)父组件 2)子组件 二. @Emit 装饰器 1)父组件 2)子组件 三. @Model 装饰器 1)父组件 2)子组件 四. @Prop 装饰器 1)父组 ...
- CCF-CSP题解 201712-3 Crontab
做完一定要仔仔细细地看一遍题目再交,之后发现坑点只能追悔莫及.比如这次"英文缩写(不区分大小写)"\(OwQ\). 给定多个周期性执行的任务,每个任务调度执行有时间的要求.求给定时 ...
- JS 正则表达式^$详解,脱字符^与美元符$同时写表示什么意思?
壹 ❀ 引 对于初学正则的同学来说,^$这两个看似简单的字符却在使用中总让匹配结果超出我们的预期,^什么时候表示行首什么时候表示反义?^ $两个一起写表示什么含义?今天我们就来详细聊聊这两个字符. ...
- Client error attempting to change layout margins of a private view
从 iOS 11 开始,UINavigationBar 使用了自动布局,左右两边的按钮到屏幕之间会有 16 或 20 的边距. 为了避免点击到间距的空白处没有响应,通常做法是:定义一个 UINavig ...