原文转载自「刘悦的技术博客」https://v3u.cn/a_id_171
最近“全栈数据库”的概念甚嚣尘上,配角就是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 bashpsql -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吧。
原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_171