开发者社区> 刘悦的技术博客> 正文

心动不如行动,基于Docker安装关系型数据库PostgrelSQL替代Mysql

简介: 最近“全栈数据库”的概念甚嚣尘上,主角就是PostgrelSQL,它最近这几年的技术发展不可谓不猛,覆盖OLTP、OLAP、NoSQL、搜索、图像等应用场景,实实在在的全栈性发展。帮助公司解决了数据孤岛、数据平台多、同步一致性、延迟,软硬件成本增加等业务痛点,在互联网、金融、物联网、传统企业等领域得到了广泛的应用。PostgreSQL的应用场景丰富,不亚于商用数据库Oracle,常被业界称为“开源界的Oracle”。
+关注继续查看

最近“全栈数据库”的概念甚嚣尘上,主角就是PostgrelSQL,它最近这几年的技术发展不可谓不猛,覆盖OLTP、OLAP、NoSQL、搜索、图像等应用场景,实实在在的全栈性发展。帮助公司解决了数据孤岛、数据平台多、同步一致性、延迟,软硬件成本增加等业务痛点,在互联网、金融、物联网、传统企业等领域得到了广泛的应用。PostgreSQL的应用场景丰富,不亚于商用数据库Oracle,常被业界称为“开源界的Oracle”。

至于Mysql大家都很熟悉,很多公司因为人才储备和数据量大的原因,一般是Hadoop+Mysql的模式,Hadoop计算大量原始数据,然后按维度汇总后的展示数据存储在Mysql上,但是Mysql也有很多的“坑”:比如著名的Emoji表情坑,由此引申出来的utf8mb4的坑(隐式类型转换陷阱),性能低到发指的悲观锁机制,不支持多表单序列中取 id,不支持over子句,几乎没有性能可言的子查询........有点罄竹难书的意思,更多的“罪行”详见:见鬼的选择:Mysql。而这些问题,在PostgrelSQL中得到了改善,本次我们在Win10平台利用Docker安装PostgrelSQL,并且初步感受一下它的魅力。

第一步当然是安装Docker,不熟悉的同学请参照:win10系统下把玩折腾DockerToolBox以及更换国内镜像源(各种神坑)

随后拉取镜像,这里我们选择相对稳定的PostgrelSQL11.1。

docker pull postgres:11.1

拉取成功后,输入命令查看镜像

docker images

可以看到,它的镜像非常小,大概300m左右,比Mysql小很多。

然后我们就可以将容器启动了,输入命令

docker run -d --name dev-postgres -e POSTGRES_PASSWORD=root -p 6432:5432 postgres:11.1

这里POSTGRES\_PASSWORD是PostgrelSQL的用户密码,自己制定一个就可以了,默认端口号是5432,由于笔者的宿主机上已经安装好一个PostgrelSQL服务端,所以这里通过端口映射改成了6432。

输入命令

docker ps

来查看容器运行状态

没有问题,现在我们进入命令行操作一下。

docker exec -it dev-postgres bash

psql -h localhost -U postgres

这样就可以进入容器内部的命令行,在命令行输入PostgrelSQL的命令\l 就可以查看数据库列表。

建立数据库

CREATE DATABASE mytest;

使用数据库

\c mytest

建立一张表

CREATE TABLE "public"."article" (  
    "id" int4 NOT NULL,  
    "content" text,  
    PRIMARY KEY ("id")  
)  
WITH (OIDS=FALSE);

列出所有表

\d

如果不习惯使用命令行,也可以用可视化工具来进行链接,比如Navicat

注意默认用户是postgres,值得一提的是,使用navicat无法像Mysql一样手动设置属性自增长(auto-increment),PostgrelSQL使用的是序列的形式来实现自增长:

CREATE SEQUENCE serial START 1;

这里创建好的序列是从1开始计数。

随后,将需要设置的字段的默认值设为序列增长即可

ALTER TABLE "public"."article" ALTER COLUMN "id" SET DEFAULT nextval('serial');

可以使用utf-8编码轻松存储Emoji

over子句的应用,假设我们有一个员工薪资的表(部门、员工id,工资):

postgres=# d empsal   
          Table "public.empsal"  
 Column  |       Type        | Modifiers   
---------+-------------------+-----------  
 depname | character varying |   
 empno   | integer           |   
 salary  | integer           |

有一些数据:

postgres=# select * from empsal ;  
  depname  | empno | salary   
-----------+-------+--------  
 develop   |    11 |   5200  
 develop   |     7 |   4200  
 develop   |     9 |   4500  
 develop   |     8 |   6000  
 develop   |    10 |   5200  
 personnel |     5 |   3500  
 personnel |     2 |   3900  
 sales     |     3 |   4800  
 sales     |     1 |   5000  
 sales     |     4 |   4800  
(10 rows)

现在我想将每一个员工的工资与他所在部门的平均工资做个比较,怎么做?其实这也是leetcode原题,用mysql只能用子查询,而用PostgrelSQL该查询可以很容易的实现

SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsal;

查询结果:

depname  | empno | salary |          avg            
-----------+-------+--------+-----------------------  
 develop   |    11 |   5200 | 5020.0000000000000000  
 develop   |     7 |   4200 | 5020.0000000000000000  
 develop   |     9 |   4500 | 5020.0000000000000000  
 develop   |     8 |   6000 | 5020.0000000000000000  
 develop   |    10 |   5200 | 5020.0000000000000000  
 personnel |     5 |   3500 | 3700.0000000000000000  
 personnel |     2 |   3900 | 3700.0000000000000000  
 sales     |     3 |   4800 | 4866.6666666666666667  
 sales     |     1 |   5000 | 4866.6666666666666667  
 sales     |     4 |   4800 | 4866.6666666666666667  
(10 rows)

可以看到,这个查询中,聚合函数avg的含义没有变,仍然是求平均值。但和普通的聚合函数不同的是,它不再对表中所有的salary求平均值,而是针对同一个部门(PARTITION BY指定的depname)内的salary求平均值,而且得到的结果由同一个部门内的所有行共享,并没有将这些行合并,这就大大简化了sql的复杂度,同时也能很方便的解决 "每组取 top k" 的这类问题。

使用容器启动数据库会有个问题,就是每次容器停止,数据就会丢失,所有我们可以用docker的挂载命令将数据存在宿主机中,这样就可以持久化保存数据:

docker run -d --name dev-postgres -e POSTGRES_PASSWORD=root -e PGDATA=/var/lib/postgresql/data/pgdata  
    -v /custom/mount:/var/lib/postgresql/data  -p 6432:5432 postgres:11.1

如果你不习惯navicat这样的桌面可视化工具,也可以使用类似pgadmin4这样的网页端工具

$ docker pull dpage/pgadmin4  
$ docker run    
    -p 80:80   
    -e 'PGADMIN_DEFAULT_EMAIL=user@domain.local'   
    -e 'PGADMIN_DEFAULT_PASSWORD=SuperSecret'   
    --name dev-pgadmin    
    -d dpage/pgadmin4

也可以使用Python和PostgrelSQL进行交互,安装三方库:

pip3 isntall psycopg2
import psycopg2  
  
import psycopg2.extras  
  
conn = psycopg2.connect(host='localhost', port=6432, user='postgres', password='root', database='mytest')  
  
  
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)   
  
cursor.execute('SELECT * FROM article WHERE id = 1;')  
  
result = cursor.fetchone()  
  
print(result)

就可以查询出数据了

结语:如果对Mysql足够熟悉,那么上手PostgrelSQL并不是一件难事,自从MySQL被Oracle收购的那一刻起,它就已经不是开源软件的最佳选择了。所以,不要固执的拒绝时代浪潮,拥抱未来,拥抱PostgrelSQL吧。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
运维 ---Docker部署mysql后使用Navicat尝试连接遇到1251报错问题的解决方法
运维 ---Docker部署mysql后使用Navicat尝试连接遇到1251报错问题的解决方法
29 0
Docker 安装 Mysql 主从
Docker 安装 Mysql 主从
16 0
Redis|Linux版安装|非关系型数据库
Redis|Linux版安装|非关系型数据库
32 0
Redis|Window版安装|非关系型数据库
Redis|Window版安装|非关系型数据库
30 0
什么是非关系型数据库,Redis概述、安装及部署Redis群集(下)
什么是非关系型数据库,Redis概述、安装及部署Redis群集(下)
49 0
什么是非关系型数据库,Redis概述、安装及部署Redis群集(上)
什么是非关系型数据库,Redis概述、安装及部署Redis群集(上)
68 0
关系型数据库MySQL简介 以及 如何进入MySQL的客户端
关系型数据库MySQL简介 以及 如何进入MySQL的客户端
64 0
初识MySQL,关系型和非关系型数据库的区别
初识MySQL,关系型和非关系型数据库的区别
33 0
为更强大而生的开源关系型数据库来了!阿里云RDS for MySQL 8.0 上线!
阿里云RDS for MySQL 8.0上线,使得阿里云成为紧跟社区步伐,发布MySQL最新版本的云厂商。RDS for MySQL 8.0 产品是阿里云推出的 MySQL 系列云产品之一,使用完全兼容 MySQL 8.0 的阿里云 AliSQL 8.0 分支,除了官方在 MySQL 8.0 推出的全新功能外,AliSQL 沉淀了许多在 Alibaba 集团电商业务和云上几十万客户在使用 MySQL 过程中遇到的问题和需求,以此来加固AliSQL, 提升 AliSQL 的性能和稳定性。
368 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
让 MySQL 原生分布式触手可及
立即下载
好的 MySQL 兼容可以做到什么程度
立即下载
云数据库RDS MySQL从入门到高阶
立即下载