iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >PostgreSQL中如何使用数组
  • 511
分享到

PostgreSQL中如何使用数组

2024-04-02 19:04:59 511人浏览 安东尼
摘要

postgresql中如何使用数组,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。这种情况几星期前在Heap出现了。我们在Heap为每个跟踪

postgresql中如何使用数组,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

这种情况几星期前在Heap出现了。我们在Heap为每个跟踪用户维护一个事件数组,在这个数组中我们用一个hstore datum代表每个事件。我们有一个导入管道来追加新事件到对应的数组。为了使这一导入管道是幂等的,我们给每个事件设定一个event_id,我们通过一个功能函数重复运行我们的事件数组。如果我们要更新附加到事件的属性的话,我们只需使用相同的event_id转储一个新的事件到管道中。

所以,我们需要一个功能函数来处理hstores数组,并且,如果两个事件具有相同的event_id时应该使用数组中最近出现的那个。刚开始尝试这个函数是这样写的:
 

-- This is slow, and you don't want to use it!
--
-- Filter an array of events such that there is only one event with each event_id.
-- When more than one event with the same event_id is present, take the latest one.
CREATE OR REPLACE FUNCTioN dedupe_events_1(events HSTORE[]) RETURNS HSTORE[] AS $$
 SELECT array_agg(event)
 FROM (
  -- Filter for rank = 1, i.e. select the latest event for any collisions on event_id.
  SELECT event
  FROM (
   -- Rank elements with the same event_id by position in the array, descending.

这个查询在拥有2.4GHz的i7CPU及16GB Ram的Macbook pro上测得,运行脚本为:https://GISt.GitHub.com/drob/9180760。


在这边究竟发生了什么呢? 关键在于Postgresql存贮了一个系列的hstores作为数组的值, 而不是指向值的指针. 一个包含了三个hstores的数组看起来像

{“event_id=>1,data=>foo”, “event_id=>2,data=>bar”, “event_id=>3,data=>baz”}

相反的是

{[pointer], [pointer], [pointer]}

对于那些长度不一的变量, 举个例子. hstores, JSON blobs, varchars,或者是 text fields, PostgreSQL 必须去找到每一个变量的长度. 对于evaluateevents[2], PostgreSQL 解析从左侧读取的事件直到读取到第二次读取的数据. 然后就是 forevents[3], 她再一次的从第一个索引处开始扫描,直到读到第三次的数据! 所以, evaluatingevents[sub]是 O(sub), 并且 evaluatingevents[sub]对于在数组中的每一个索引都是 O(N2), N是数组的长度.

PostgreSQL能得到更加恰当的解析结果,  它可以在这样的情况下分析该数组一次. 真正的答案是可变长度的元素与指针来实现,以数组的值, 以至于,我们总能够处理 evaluateevents[i]在不变的时间内.


即便如此,我们也不应该让PostgreSQL来处理,因为这不是一个地道的查询。除了generate_subscripts我们可以用unnest,它解析数组并返回一组条目。这样一来,我们就不需要在数组中显式加入索引了。
 

-- Filter an array of events such that there is only one event with each event_id.
-- When more than one event with the same event_id, is present, take the latest one.
CREATE OR REPLACE FUNCTION dedupe_events_2(events HSTORE[]) RETURNS HSTORE[] AS $$
 SELECT array_agg(event)
 FROM (
  -- Filter for rank = 1, i.e. select the latest event for any collisions on event_id.
  SELECT event
  FROM (
   -- Rank elements with the same event_id by position in the array, descending.
   SELECT event, row_number AS index, rank()
   OVER (PARTITION BY (event -> 'event_id')::BIGINT ORDER BY row_number DESC)
   FROM (
    -- Use unnest instead of generate_subscripts to turn an array into a set.
    SELECT event, row_number()
    OVER (ORDER BY event -> 'time')
    FROM unnest(events) AS event
   ) unnested_data
  ) deduped_events
  WHERE rank = 1
  ORDER BY index ASC
 ) to_agg;
$$ LANGUAGE SQL IMMUTABLE;

结果是有效的,它花费的时间跟输入数组的大小呈线性关系。对于100K个元素的输入它需要大约半秒,而之前的实现需要40秒。

这实现了我们的需求:

  •     一次解析数组,不需要unnest。

  •     按event_id划分。

  •     对每个event_id采用最新出现的。

  •     按输入索引排序

教训:如果你需要访问PostgreSQL数组的特定位置,考虑使用unnest代替。 

   SELECT events[sub] AS event, sub, rank()
   OVER (PARTITION BY (events[sub] -> 'event_id')::BIGINT ORDER BY sub DESC)
   FROM generate_subscripts(events, 1) AS sub
  ) deduped_events
  WHERE rank = 1
  ORDER BY sub ASC
 ) to_agg;
$$ LANGUAGE SQL IMMUTABLE;

这样奏效,但大输入是性能下降了。这是二次的,在输入数组有100K各元素时它需要大约40秒!

PostgreSQL中如何使用数组

这个查询在拥有2.4GHz的i7CPU及16GB Ram的macbook pro上测得,运行脚本为:Https://gist.github.com/drob/9180760。


在这边究竟发生了什么呢? 关键在于PostgreSQL存贮了一个系列的hstores作为数组的值, 而不是指向值的指针. 一个包含了三个hstores的数组看起来像

{“event_id=>1,data=>foo”, “event_id=>2,data=>bar”, “event_id=>3,data=>baz”}

相反的是

{[pointer], [pointer], [pointer]}

对于那些长度不一的变量, 举个例子. hstores, json blobs, varchars,或者是 text fields, PostgreSQL 必须去找到每一个变量的长度. 对于evaluateevents[2], PostgreSQL 解析从左侧读取的事件直到读取到第二次读取的数据. 然后就是 forevents[3], 她再一次的从第一个索引处开始扫描,直到读到第三次的数据! 所以, evaluatingevents[sub]是 O(sub), 并且 evaluatingevents[sub]对于在数组中的每一个索引都是 O(N2), N是数组的长度.

PostgreSQL能得到更加恰当的解析结果,  它可以在这样的情况下分析该数组一次. 真正的答案是可变长度的元素与指针来实现,以数组的值, 以至于,我们总能够处理 evaluateevents[i]在不变的时间内.


即便如此,我们也不应该让PostgreSQL来处理,因为这不是一个地道的查询。除了generate_subscripts我们可以用unnest,它解析数组并返回一组条目。这样一来,我们就不需要在数组中显式加入索引了。
 

-- Filter an array of events such that there is only one event with each event_id.
-- When more than one event with the same event_id, is present, take the latest one.
CREATE OR REPLACE FUNCTION dedupe_events_2(events HSTORE[]) RETURNS HSTORE[] AS $$
 SELECT array_agg(event)
 FROM (
  -- Filter for rank = 1, i.e. select the latest event for any collisions on event_id.
  SELECT event
  FROM (
   -- Rank elements with the same event_id by position in the array, descending.
   SELECT event, row_number AS index, rank()
   OVER (PARTITION BY (event -> 'event_id')::BIGINT ORDER BY row_number DESC)
   FROM (
    -- Use unnest instead of generate_subscripts to turn an array into a set.
    SELECT event, row_number()
    OVER (ORDER BY event -> 'time')
    FROM unnest(events) AS event
   ) unnested_data
  ) deduped_events
  WHERE rank = 1
  ORDER BY index ASC
 ) to_agg;
$$ LANGUAGE SQL IMMUTABLE;

结果是有效的,它花费的时间跟输入数组的大小呈线性关系。对于100K个元素的输入它需要大约半秒,而之前的实现需要40秒。

这实现了我们的需求:

  •     一次解析数组,不需要unnest。

  •     按event_id划分。

  •     对每个event_id采用最新出现的。

  •     按输入索引排序。

关于PostgreSQL中如何使用数组问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网数据库频道了解更多相关知识。

您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL中如何使用数组

本文链接: https://www.lsjlt.com/news/56975.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PostgreSQL中如何使用数组
    PostgreSQL中如何使用数组,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。这种情况几星期前在Heap出现了。我们在Heap为每个跟踪...
    99+
    2024-04-02
  • 如何使用PostgreSQL的数组类型
    这篇文章主要介绍“如何使用PostgreSQL的数组类型”,在日常操作中,相信很多人在如何使用PostgreSQL的数组类型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何...
    99+
    2024-04-02
  • PostgreSQL 中sum()函数如何使用
    这篇文章将为大家详细讲解有关PostgreSQL 中sum()函数如何使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。PostgreSQL的SUM函数用来...
    99+
    2024-04-02
  • PostgreSQL中如何使用jsonb数据类型
    PostgreSQL中如何使用jsonb数据类型,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。PostgreSQL 9.4 正在加载一项新...
    99+
    2024-04-02
  • PostgreSQL中如何使用Lateral类型
    这篇文章给大家介绍PostgreSQL中如何使用Lateral类型,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。PostgreSQL 9.3 用了一种新的联合类型! Lateral联合...
    99+
    2024-04-02
  • PostgreSQL中Insert语句如何使用
    PostgreSQL中Insert语句如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、源码解读standard_pl...
    99+
    2024-04-02
  • PostgreSQL中如何使用create database创建数据库
    这篇文章将为大家详细讲解有关PostgreSQL中如何使用create database创建数据库,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、create database语法格式CREATE&nb...
    99+
    2023-06-14
  • PHP中如何使用数组函数
    PHP中如何使用数组函数,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。array_multisort()对多个数组或多维数组进行排序可以用来一次对多个数组进行排序或者根据某一维...
    99+
    2023-06-17
  • Bash中如何使用Windows数组?
    在 Bash是一个非常流行的Unix shell,它提供了一种简单而强大的方式来管理和处理Unix系统中的各种任务。然而,在使用Bash时,你可能会遇到一些需要与Windows系统进行交互的情况。这时候,你需要使用Windows数组来处理数...
    99+
    2023-10-29
    数组 bash windows
  • Bash中如何使用PHP数组?
    在Bash中,使用PHP数组可以让我们更方便地处理数据。PHP数组在Bash中的使用方法也非常简单,本文将为您介绍如何在Bash中使用PHP数组。 一、定义PHP数组 定义PHP数组需要使用括号,例如: my_array=(1 2 3 4...
    99+
    2023-10-29
    数组 bash windows
  • Java IDE中如何使用数组?
    在Java编程中,数组是一种非常重要的数据结构。它可以存储一组相同类型的数据,而且我们可以使用下标来访问数组中的元素。在Java IDE中,使用数组也非常简单,我们可以通过一些快捷键或者菜单来创建、修改和使用数组。 创建数组 在Java ...
    99+
    2023-09-19
    ide 数组 npm
  • 如何在Debian中安装并使用PostgreSQL数据库
    在Debian中安装并使用PostgreSQL数据库的步骤如下: 更新系统软件包列表: sudo apt update 安装...
    99+
    2024-04-02
  • PostgreSQL 10中如何使用分区表
    本篇文章给大家分享的是有关PostgreSQL 10中如何使用分区表,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。分区介绍PostgreSQL...
    99+
    2024-04-02
  • PostgreSQL中如何使用日期类型
    PostgreSQL中如何使用日期类型,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。当前时间/日期/时间戳获取当前时间的方式有...
    99+
    2024-04-02
  • Python 函数中如何使用 Linux 数组?
    在 Linux 系统中,数组是一种非常常见的数据类型。它可以用来存储一系列相关的元素,并且可以轻松地对这些元素进行操作。在 Python 函数中,使用 Linux 数组可以让我们更方便地操作和处理数据。 在本文中,我们将探讨如何在 Pyt...
    99+
    2023-07-20
    函数 linux 数组
  • PostgreSQL命令如何使用
    这篇文章给大家介绍PostgreSQL命令如何使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。创建一个简单的购物清单首先,输入 psql 命令进入数据库,然后用下面的命令创建一个表:...
    99+
    2024-04-02
  • 如何在 PHP 中使用 Bash 数组?
    在 PHP 开发中,我们常常需要借助 Bash 数组来存储和操作数据。Bash 数组是一种能够同时存储多个值的数据结构,它能够更加高效地处理一些复杂的数据操作。在本文中,我们将详细介绍如何在 PHP 中使用 Bash 数组,帮助您更好地理解...
    99+
    2023-09-23
    http 数组 bash
  • 如何在JavaScript数组中使用reduce
    如何在JavaScript数组中使用reduce?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。JavaScript的特点1.JavaScript主要用来向HTM...
    99+
    2023-06-14
  • Python中二维数组如何使用
    本篇文章给大家分享的是有关Python中二维数组如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Python中没有数组的数据结构,但列表很像数组,如:a=[0,1,2]这...
    99+
    2023-06-17
  • C++中如何使用二维数组
    C++中如何使用二维数组,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。C++二维数组new应用方式一:A (*ga)[n] = new&nbs...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作