Detailed explanation of PostgreSQL array type usage

Detailed explanation of PostgreSQL array type usage

Maybe you are not familiar with PostgreSQL, a relational database, because most people are most familiar with MySQL, and the company uses MySQL the most.

Let's first PGbriefly introduce the PostgreSQL database (hereinafter referred to as), and then have the opportunity to write a separate article dedicated to pgSql

The World's Most Advanced Open Source Relational Database

This is the PGofficial website's introduction to itself, yes, you read that right, "the most advanced open source relational database in the world". In a sentence that seriously violated China's advertising law, the last technology that dared to clamor was PHP, "the best language in the world", and then this sentence has become the most well-known stalk in the code farming community, and it exists in all kinds of jokes.

However PG, I did not receive any criticism or ridicule for such blatant boasting. In fact, whether in the pragmatic code farmer or in the academic world who pay attention to rules and regulations, people PGare all praised and PGfully worthy of this sentence . words.

Listed below are some of the features of PostgreSQL

  • PostgreSQL is a very full-featured relational database developed by the Department of Computer Science at the University of California

  • The PostgreSQL open source protocol is a BSD-like protocol. It is a very friendly protocol. There is no risk whether it is for commercial use or personal use, or to modify the code and then name it and sell it for money.

  • There are many data types supported by PostgreSQL. In addition to the commonly used ones, there are also 枚举类型, 几何类型, UUID类型 , , json类型, 数组类型etc. Among them, it 数组类型is also the purpose of this article to introduce the use of array types.

  • When PostgreSQL was established, the target database was the Oracledatabase , and all the functions and performance of PostgreSQL are very strong.

  • PostgreSQL executes complex SQL better than MySql

    ................................

还有很多的特性,这里只简单的写几个,上面的几个特点也是我非常在意的,之所 www.helloworld.net 此次改版把Mysql换成了PostgreSQL ,就是有这些原因。

之前很多人问过,hellworld开发者社区 改版用到了哪些技术栈,其中之一,就是把 Mysql 换成了 PostgreSQL

在改版的过程中,所有的表全部重新设计,这对于后端来说,是一个极其需要勇气的决定,好在我们坚持下来了

在改的过程中,其中有这样一个场景:

一篇博客,有多个标签 ,比如 一个博客,有多线程, 并发 , 线程池 这三个标签

对于这样的需求,我们可以分析一下

  • 一篇博客,有多个标签
  • 一个标签,也可有对应多篇博客

这样就形成了 多对多 的关系,建表的话,就会有一张关联表,大部分会想到这样建表

博客表: blog

标签表: tag

标签博客表: tag_blog

其中各表的字段,如下(简单起见,只列出最少的列):

blog 表:

  • id 数字类型,博客的 id, 自增长的主键
  • title 字符串类型,博客的标题

tag表:

  • id 数字类型, 标签的 id , 自增长的主键
  • name 字符串类型,标签的名字

tag_blog

  • id 数字类型, 自增长的主键
  • tag_id 标签 id (对应 tag 表中的 id )
  • blog_id 博客id (对应 blog 表中的 id )

上面这个博客标签需求,需要 3 张表,我们知道,PostgreSQL 的列的类型是支持数组类型

我们是不是可以优化一下上面的需求,把 3 张表变成 1 张表

只保留一张 blog 表,在 blog 表中增加一列 tags , 类似就是 text[ ]

新的博客表字段如下:

blog表:

  • id 数字类型(bigint),博客的 id, 自增长的主键
  • title 字符串类型(text ),博客的标题
  • tags 字符串数组类型(text[ ] )

为了方便大家测试,建表SQL 如下

CREATE TABLE IF NOT EXISTS public.blog
(
    id bigint NOT NULL DEFAULT nextval('blog_id_seq'::regclass),
    title text COLLATE pg_catalog."default",
    tags text[] COLLATE pg_catalog."default",
    CONSTRAINT blog_pkey PRIMARY KEY (id)
)

TABLESPACE pg_default;

ALTER TABLE IF EXISTS public.blog
    OWNER to postgres;
复制代码

下面我们针对 tags 字段作一些基本操作

数组类型的基本操作

1 查询

现在表中没有数据,我们查询一下看看

select * from blog
复制代码

结果如下: image-20221021201052272

2 插入数据

插入一条记录,标题是 www.helloworld.net , 对应的标签有3个,分别是 helloworld , 技术 , 社区

insert into blog (title,tags) values('www.helloworld.net','{"helloworld","技术","社区"}')
复制代码

再次查询

select * from blog
复制代码

结果如下: image-20221021201706232

可以看到,已经有了一条数据了,tags 数组里面有3个元素,分别是 helloworld , 技术 , 社区

我们再次插入两条数据,方便我们测试

insert into blog (title,tags) values('www.juejin.im','{"掘金","技术","开发者"}');
insert into blog (title,tags) values('www.oschina.net','{"开源中国","oschina","开源"}');
复制代码

查询结果如下:

image-20221021202041981

3 条件查询

3.1 查询标签中有 技术标签的博客,语法 select * from blog where 'xx' = any(数组字段)

sql 语句如下

select * from blog where '技术'= any(tags)
复制代码

查询结果如下:

image-20221021202412709

3.2 查询标签中有 helloworld标签或者有 开源中国标签的博客

sql语句如下:

select * from blog where 'helloworld'= any(tags) or '开源中国' = any(tags)
复制代码

结果如下: image-20221021203227244

4 更新

4.1 更新标签的名称

我们将 id = 1 的记录的 tags 数组中, 社区改成开发者社区

注意:pg中数组类型,索引是从 1 开始,我们将 id = 1 的记录,社区元素索引为3,修改语法为: update 表名 set 字段[index] = 'xx' where id=1

sql如下:

update blog set tags[3] = '开发者社区' where id=1 
复制代码

再次查询,结果如下:

image-20221021203813747

可以发现,通过 tags[3] = '开发者社区' ,成功的把 社区修改成了 开发者社区

4.2 添加一个标签

我们把 id=1 的记录,标签再增加一个 程序员标签

可以使用PostgreSQL的 array_append 函数

使用方法如下:

sql写法如下:

update blog set tags = array_append(tags, '程序员'::text) where id=1
复制代码

再次查询结果如下:

image-20221021204437307

5 删除

我们删除标签

把 id= 3 的记录中的标签,删除开源

sql如下:

update blog set tags = array_remove(tags, '开源'::text) where id=3
复制代码

执行后,再次查询,如下:

image-20221021204731808

总结

以上就是关于 PostgreSQL 的数组类型的常见的用法,至于其它的用法,大家可以看一下官方文档,再结合本例的SQL写法

应该很容易就能掌握

以上的需求,其实实际应用中并不是适合用数组类型解决,数组适合的场景,操作,交互不多,不太重要,可以用

helloworld开发者社区在改版的过程中,数据库虽然换成了 PostgreSQL ,但是博客的标签这块需求,并没有用这种方式

此例只是方便说明用法,具体实际中怎么用,大家还需要结合自己的业务需求,灵活选择

如果觉得上面的文章对你有帮助,那么我的一点付出是值得的,方便的话,也可以给个关注,谢谢 ^_^

Guess you like

Origin juejin.im/post/7157973007380529166