pg数据库json数据类型_PostgreSQL与开发者起舞—让数据库更好服务于开发

写在前面的话:本文内容有对应50分钟视频讲解,有兴趣可以访问PG与开发者共舞。

很多数据库的对比的活动都是基于数据库本身的一些的底层的功能以及纯数据库方面的对比,等等。更多方面数据库是要为应用来服务的,而生产应用的大部分都是与程序员有关的,怎么服务于程序员,提高程序员的舒适感,也是一个重要的话题,提高了程序员的工作效率,减少代码量,将逻辑下移,减少程序中的BUG,这是一个数据库可以做到的,不是每个企业都是互联网企业,不是每个业务都是高并发的业务,我们有大量复杂业务,如果将业务逻辑全部都在程序端实现,势必会增加程序员的劳动力,开发周期延长,后续的程序的灵活性也会受到部分限制。

b52989160fefb14d38f64d3ecce4d601.png

所以这次的课,主要是面对程序员,服务于程序员,有一部分老板也可能对降低成本,尤其是开发的成本很感兴趣,另外可能也有部分纯软件开发企业会对后续软件的维护,尤其是数据库的维护,感兴趣,因为复杂的数据库高可用结构,尤其分库分表,限制了纯开发企业的开发软件的方式和后期与签约企业的运维维护方面的难度。

那么下面我们就从几点来阐述,PG到底和开发者是一个什么关系,到底开发者在使用PG 能不能得到好处的问题。

9a345c10af1ca3fdac50f7e111b8850c.png

以下单纯以服务于开发人员和客户的观点进行本次课程的阐述,并且会辅以一些例子来说明。

582ab07bd082ba1e3fbfbbac1027672c.png

我相信在看到上面的图上的文字,有一部分非互联网的开发人员,已经坐不住的,但实际上是这样的,互联网企业使用的数据库的要求很多,当然这也是由于数据库的原理造成的问题,但需要开发人员来买单。

在软件开发中,最让开发人员头疼的问题之一,就是字段的预留的大小的问题,某些大型的软件开发企业和互联网企业,在使用开源数据库中大多都会遇到这个问题,因为某些开源数据库的字段大小,与字段扩展和系统的性能是有"绑定“的关系, 有的时候都要进行一番“辩论”。所以每次开发和DBA之间的冲突就因为某些问题开始产生矛盾。互相都不理解,软件开发不理解对方为什么要严格的去扣一个字段的大小,254和512有差吗,如果以后扩展,还要麻烦,我为什么不能使用更大的字段,并且后续的开发中某些系统的对接表还要记住之间的字段大小匹配,我太难了,DBA方也有自己的理由,明明如果你使用了特别大的字段后,系统的性能会明显下降,为了系统性能我要求难道不对吗,后续你要扩展,我还要冒着风险给你加字段扩展字段,我容易吗?

所以矛盾就产生了,并且来来回回的审核和修改,让开发人员浪费时,DBA的时间也就这样浪费了,互相的成本都很大。

PostgreSQL 在这方面和其他的开源数据库不太一样,甚至和商业数据库也不大一样,他的宽容度和包容度都比较大,在设计和开发软件的时候,不需要那么用力,我们以 postgresql 11 作为我们的例子,这是PG11版本中tip,由于原理的原因,在PG 中text 和 varchar之间是没有什么性能的差别的。(当然如果你往一个字段里面放置几十MB ,上百MB的情况,另当别论),所以在字段大小设计方面的问题的矛盾点就被化解了。

891499b22e4961e1d54e5ea085a85d85.png

我们下面看一下一个建表的语句,

535044f33d49730c9e16c5d144d3ab4a.png

下面是从pg_admin中导出的语句

c6f8d71ee5eb5377964bbe172ab9497e.png

其实也是听到一个声音,就是PG在某些方面不如别的数据库在语句的写法上宽泛,实际上第一张图是手写的,如果不和你说明估计也不大能分的很清楚与某些其他数据库建表语句的明显区别,PG对语句的兼容性并不低,下图是从PG_ADMIN导出的语句,最终实际的PG标准的语句是这样的,这也明显的看出, PG的包容性。

说完PG的包容性,下面就的继续说PG的多态性,这个问题其实要从PG支持的数据类型来开始,PG支持的数据类型是相当的多。其中必然要谈的是一个种特殊的PG的数据类型 hstore

63ae6ffa9ab5cdf28f7a4c3947e72500.png

insert into hstore_test (id,name,history) values (1,'postgresql','from => "IBM_Research",origination => "inges",time => "1970"')

可以看到与JSON 格式对比,hstore 在处理比较随意的数据上。

SELECT name, history->'from' as history FROM hstore_test WHERE history->'origination' = 'inges';

b93f607929b8f13c3d2a0ee5513f43a8.png

这样的数据的处理方式,在实际的应用中是很有意义的,例如项目不稳定,客户经常没有准主意,一会一变,等等这样的情况,开发人员都可以用这样的模式来设计初期的项目中的数据存储,并且这样的的数据也可以保证系统的性能和查询的。不会对开发人员有过高的要求和特殊的规定。

其实这样的设计是一个数据库包容能力和多态性的一种体现,完全为项目和应用以及程序员的便利性去考虑,这也是一个数据库中适应结构化和半结构化数据,完全面向应用,降低开发的难度和成本做出的最大的诚意

除此以外,PG对于程序员在模糊查询中的诚意也是满满的,我们都知道在开发一些系统中,用户的挑剔和项目经理以及需求经理对于开发人员来说,奇葩的需求,天天有,例如客户对一个系统中用户的留言点评,想进行一个查询,每天都要有,根据几个关键词来进行查找客户是否有不满意,或者意见的情况,当然这些词也是变化的,模糊查询中最让人讨厌的就是两边都是

%% 百分号。而PG 对于这样的情况是可以走索引进行查询的。那我们将这一块的内容和下边的索引的内容进行一个合并,通过两个例子来讲一讲。

5c812dfb8331eae1b40c8a0a22fd8bd9.png

结合上面的查询,开发人员对于索引的支持也是关心的,因可能由于某些逻辑或前期设计的问题,造成我们的数据表必须要有大量的索引来解决部分查询性能问题,例如某些表中的数据的一列只有几种类型,或者我们的表的数据量比较大,最后造成索引和表都特别大的情况,本身就带来性能问题

PG 本身在设计上,就考虑了这点,索引的类型很多, B-tree, Hash, GiST, SP-GiST, GIN and BRIN, 这里大部分数据库除了b-tree索引类型以外,其他的类型的索引是不支持,或许这里面的 GIST GIN Brin 等索引的类型大部分没有用过PG的人也是第一次听说。

那我们就来挑两个索引来说说 GIN 和 BRIN 索引,这两种索引都是有针对性的

1 模糊查询

我们先建立一个函数用来生成随机的数据

create or replace function gen_hanzi(int) returns text as $$ declare res text; begin if $1 >=1 then select string_agg(chr(19968+(random()*20901)::int), '') into res from generate_series(1,$1); return res; end if; return null; end; $$ language plpgsql strict;

insert into text_search (address) select gen_hanzi(10) from generate_series(1,1000000);

97abc38ec31825742680117b6241c48c.png

插入200万条数据,随机产生汉字。

create index CONCURRENTLY idx_ts_address on text_search using gin (address gin_trgm_ops);

创建相关GIN 索引来应用trgm 函数

812f11ba62211b95afd4f8ba424b8139.png
2b38de7b88c8ba69b4438a4c6fd72690.png

通过上面的操作,我想大家已经对于PG的 GIN 索引在模糊查询中的实力有所了解,这也是四大数据库中,其他的数据库都不能快速简便解决的问题,所以开发人员如果遇到这样的需求,在头痛的时候,可以问自己一句,为什么没有用PG,浪费本应该节省下的时间和成本。因为其他的数据库要做这样的事情,是需要其他的附加的其他的数据库来完成,例如ES, 这样的情况为了一个字段,一个奇葩需求而要付出的代价就被PG 轻松的化解了。

当然这还不是最神奇的,我们还有一些应用,表的数据量很大,同时也要建立索引,而索引随着表的变大,就会变得越来越大,这就是b+tree的问题,而PG中的BRIN索引就是为了解决这样的问题而来的,怎么能更减小索引,并且与btree 的性能相近,与范围查询配合效果是很不错的.

我们用一个例子来证明一下

CREATE TABLE testtab (id int NOT NULL PRIMARY KEY,date TIMESTAMP NOT NULL, level INTEGER, msg TEXT)

INSERT INTO testtab (id, date, level, msg) SELECT g, CURRENT_TIMESTAMP + ( g || 'minute' ) :: interval, random() * 6, md5(g::text)

FROM generate_series(1,8000000) as g;

497a314a700d6da17dfca803369838c3.png

create index CONCURRENTLY idx_tss_brin on testtab using brin (date);

create index CONCURRENTLY idx_tss_btree on testtab (date);

97591c34ca63d4ba32fb5e2eb8cfa7e5.png
2d0e2d5126b450ba185e83f3e95e3491.png

在创建表和索引后,我们对比同样的功能,两个索引的大小相比,BTREE 是171MB 而 BRIN 索引只有 64kb.

这时估计很多人都会想,那效果一定大打折扣。那我们来看看,到底查询的性能会不会因为不同的索引而造成查询的性能特别大的差距。

explain analyze select * from public.testtab where date between '2020-03-23 06:15:01.41099' and '2020-03-23 06:19:01.41099';

00219dd21ac33bc1ca709b034cfdcaee.png
9152d55ebfd4c4a1785a9de849e07d13.png

通过上面两个查询的对比,实际上差距并不是很大,相对于他们的索引的大小来说。所以如果一个表中有很多范围类型的查询,就可以采取brin方式的索引,来降低大表对索引的空间的占用。

Brin索引,BRIN代表Block Range Index,BRIN是为处理非常大的表而设计,用一种块的概念,块范围是表中物理上相邻的一组页,对于每个块范围,索引将存储一些摘要信息。

BRIN索引可以通过常规的位图索引扫描来满足查询,索引所存储的摘要信息与查询条件一致,则返回每个范围内所有页面中的所有元组。查询执行程序负责重新检查这些元组,并丢弃那些不匹配查询条件的元组——换句话说,这些索引是有损的。由于BRIN索引非常小,与顺序扫描相比,扫描索引只增加了很少的开销,但是可以避免扫描已知不包含匹配元组的表的大部分数据。

说完索引,我们在来说说PG中的继承表,继承表这个概念我个人没有再ORACLE , SQL SERVER ,MYSQL ,或者其他类似 MONGODB 中听说过,当然也可能是我比较孤陋寡闻。PG的继承表是一种在开发中很有用的技术,举例,我们的开发中已经有一张很大的数量表,其中已经有一些信息,但这些信息是主营业务的,同时随着业务的发展,我们又有了一些其他的业务,虽然是其他的业务,但这些业务大部分是主营业务的扩展,需求方要求开发,那你要在这个业务中继续开发,如果有这样的要求,就一定会要你进行原表的信息添加,也就是加字段,这就要产生一个问题,字段添加在原表,这并不是每个开发愿意做的事情,尤其是高级的开发,一张表本身在设计初期其实已经根据当时的情况作了规划,怎么能在不影响原有的规划,并且又能继承原表的字段,产生一张新表,并在此基础上进行字段的添加修改,或者随着业务的变化,很可能会将这段抹去,这都是继承表能给开发者的恩赐。

43751ea4009db1df28a197fb3d58dadd.png
7f355fc355dcc485bdd4e7590a781ef8.png

通过上图来看,实际上继承表的设计是很有意思的,如果在发散性的思维,可能会创造出更多的用法.

最后不同的程序员在以前使用不同的数据库,例如ORACLE MYSQL 或者SQL SERVER ,尤其某些程序员在使用完ORACLE 后,在使用其他的数据库时会产生一些疑问,别的数据库是instance 下有数据库,而ORACLE 是instance 下都是表,通过schema(用户)来对表进行访问的控制。

而PG 则是两种习惯都适应,你可以在PG数据库里面使用类似ORACLE 的schema 的经验来访问表,规划表,同时更可以使用MYSQL 熟悉的方式,将不同的表放置不同的数据库来进行分割。所以对于大部分程序要都是友好的。最后要阐述的是没有一种数据库在当今可以霸占一个企业,一个企业使用 N种数据库是很平常的事情。所以运维人员也需要有包容的心态来面对越来越多的曾经不熟悉的数据库的加入,增加企业的竞争力,降低成本。

本文对应视频讲解,点击浏览

以上内容由东方瑞通资深讲师 Austin原创,13年专业DBA经验,曾任互联网金融公司Senior DBA、500强制药企业Senior DBA,精通Mysql、PostgreSQL、Mongo DB、SQLServer。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/573460.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统启动 之 Linux系统启动概述(2)

博客:http://blog.csdn.net/younger_china/article/details/51615916 Linu系统启动是一个”冗长乏味”的过程,那么我们现就需要去经历一下这个冗长乏味的生活。我们按照如下流程来分析: 1. 史前时代:BIOS 计算机在上电那一刻几乎是毫无用处的…

python 全文搜索 句子_python新玩法:用python进行文章摘要拿取,只需要一行代码

前言今天为大家介绍一个python算法TextRank,实现从长篇中快速抽取精准摘要。TextRank是一种基于图形的文本处理排序算法。PageRank通常用作其底层的图排序模型。当然,其他的图排序模型也可以与之结合。TextRank算法不需要深入的语言和专业知识,因为它是一…

Django小项目简单BBS论坛

开发一个简单的BBS论坛项目需求:1 整体参考“抽屉新热榜” + “虎嗅网” 2 实现不同论坛版块 3 帖子列表展示 4 帖子评论数、点赞数展示 5 在线用户展示 6 允许登录用户发贴、评论、点赞 7 允许上传文件 8 帖子可被置顶 9 可进行多级评论知识必备&#x…

时间转年月日_编程中常见的时间格式

时间格式前端和后端时经常会遇到各种各样的时间格式,这些格式在编写程序的时候都需要去使用不同的处理方式,这里集中写一下。先说一下各种不同的时间格式。类型名格式说明ISO 8601一般:2020-12-05T05:33:19Z 东八区:2004-05-03T17…

外星人台式机无盘服务器,可以拎走的“台式机” Alienware Area-51m评测

Alienware外星人这个品牌曾经一度是游戏笔记本领域的执牛耳者,自从1996年创立以来,品牌宗旨就是提供最强的PC性能,最有个性的设计和最好的服务。凭借着强悍的配置、创新的黑科技和酷炫的灯效,其一度是业内高端和高品质的代名词。但…

法流程图_世界五大学习方法之西蒙学习法

世界五大学习方法之西蒙学习法摘要:西蒙学习法为6个月可以掌握任何一门学问,它的本质是广义动量定理。广义动量定理通过调整力量、方向、作用点和时间来增加成果。西蒙学习法使用了降低问题难度方法中的一种:拆分。本节分为四个部分&#xff…

生成word_Word如何生成目录?3个步骤轻松掌握!

在使用Word编写长篇文档时,我们经常会给内容生成一个目录,有了目录,无论是阅读还是查找内容,都非常方便。Word生成目录是一项核心功能,这是每个使用Word的人,必须要掌握的一项技巧。如果你还不会这项技巧&a…

启动go服务_内网穿透工具 FRP公网服务端、内网客户端快速配置文件说明

内网穿透工具 FRP 公网服务端、内网客户端 frps.ini 、frpc.ini 配置文件常用设置展示及说明公网服务端 frps.ini 配置文件常用设置公网服务端配置文件:frps.ini[common]bind_port 7000# vhost_http_port 参数来设置 HTTP 访问端口,此处示例&#xff1a…

设置dns_2019让你的网速飞起来,你需要……设置正确DNS服务篇

有时候上网明明网络连接正常,但网页访问却很慢?平时会不会经常听到一些老司机说,网络很慢啊可以修改一下DNS啊!什么是DNS?又为什么会对网速产生影响呢?跟着小编的教程一起来学习一下吧~PART 1 什么是DNS&am…

5 随窗口改变大小_C4D默认界面两个关于坐标轴的窗口有什么区别

前言在一开始学习C4D的时候,就有这个疑问,为什么明明物体的属性都有了一个坐标属性的窗口了,还要有一个和坐标相关的窗口在默认的界面呢,后边在使用的过程中才慢慢理解了额外的坐标管理器窗口的作用,这一篇文章我们来看…

MySQL数据查询新人须知

MySQL 是一个开放源码的小型关系型数据库管理系统。 针对不同的用户,MySQL 一共分为两个不同的版本: MySQL Community Server(社区版服务器)。 MySQL Enterprise Server(企业版服务器)。 目前 Internet …

(硬 核)Navicat for MySQL 介 绍( 入 门 须 知 )

Navicat for MySQL 是一款流行的 MySQL 图形化管理工具以下是 Navicat for MySQL 工作界面使用 Navicat for MySQL 连接 MySQL 服务器鼠标左键单击“连接”按钮,出现“新建连接”窗口。分别输入连接名、MySQL 服务器主机地址、服务 端口号、用户名和密码&#xff0c…

小明一家过桥_【练习】用python解决小明一家过桥问题

import randomlist1[] #存放所有遍历的结果#等待过桥的人员bridge1{小明:1,弟弟:3,爸爸:6,妈妈:8,爷爷:12}#过桥后的人员bridge2{}#判断未过桥的人是否空了(全部过完后,程序停止,看总共用了多长时间)len1len(bridge1)print(len1)#while True:print(初始情…

WGZX:javaScript 学习心得--1

标签: javascriptiframedreamweaver浏览器htmltable2008-09-11 10:50 1071人阅读 评论(0) 收藏 举报分类:UI(21) 1,document.getElementById方法只能获取到一个对象,即使有多个同名的对象,也只取…

PHP----练习-----新闻管理----增删改查

练习-----新闻管理 题目要求如下&#xff1a; 做法&#xff1a; 【1】建数据库 【2】封装类文件--------DBDA.class.php 1 <?php2 class DBDA3 {4 public $fuwuqi"localhost"; //服务器地址5 public $yonghuming"root";//用户名6 public …

mysql query cache 关闭_为什么要关闭MySQL query cache-Fun言

MySQL的query cache大部分情况下其实只是鸡肋而已&#xff0c;建议全面禁用。当然了&#xff0c;或许在你的场景下还是挺好的&#xff0c;还能发挥作用&#xff0c;那就继续使用吧&#xff0c;把本文当做参考就好。不过&#xff0c;可能有的人人为只需要把 query_cache_size 大…

Java 基础之java运算符

运算符&#xff0c;顾名思义就是用于计算的符号。按功能分为&#xff1a;赋值运算符、算术运算符、关系运算符和逻辑运算符按操作数的个数分类&#xff1a;单目运算符、双目运算符、三目运算符运算符的目&#xff1a;运算符能连接操作数的个数称为运算符的目运算符的优先级&…

直流电机调速仿真作业

本次调速仿真采用PID调节。首先要确定PID中的各项设计参数&#xff0c;仿真过程中采用临界比例度法确定了大概的Kp值。在若干次调整的过程中&#xff0c;发现加入微分环节后调整时间略有上升&#xff0c;故采用PI调节。调整参数确定为Kp75,Ki22。控制器部分的程序如下图所示。原…

Java运算符优先级和表达式及数据类型转换

计算机程序在处理数据时会进行大量的计算&#xff0c;而数据的运算则需要借助运算符和表达式来完成。表达式是指由操作数和运算符组成的用于完成某种运算功能的语句子表达式Y X * ( Z 10 ) 表达式 其中Y、X、Z、10 称为操作数&#xff0c;、*、 称为运算符。 在…

Bugtags 2016-06-16 更新内容

增加版本管理功能 随着版本的增多&#xff0c;有些历史的版本不再使用&#xff0c;可将这些版本隐藏起来。操作步骤如下&#xff1a;点击设置 - 版本管理&#xff08;管理员可见&#xff09;- 取消勾选需要隐藏的版本即可。隐藏版本后&#xff0c;版本筛选中将不会显示&#xf…