Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rtpfL-000COV-2h for pgsql-general@arkaria.postgresql.org; Mon, 08 Apr 2024 14:08:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rtpfI-007B3w-MO for pgsql-general@arkaria.postgresql.org; Mon, 08 Apr 2024 14:08:04 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rtpfH-007B3f-9o for pgsql-general@lists.postgresql.org; Mon, 08 Apr 2024 14:08:04 +0000 Received: from fhigh7-smtp.messagingengine.com ([103.168.172.158]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rtpfC-001a2A-Ov for pgsql-general@lists.postgresql.org; Mon, 08 Apr 2024 14:08:02 +0000 Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailfhigh.nyi.internal (Postfix) with ESMTP id 6C08A114014B for ; Mon, 8 Apr 2024 10:07:56 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Mon, 08 Apr 2024 10:07:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= joshtriplett.org; h=cc:content-type:content-type:date:date:from :from:in-reply-to:message-id:mime-version:reply-to:subject :subject:to:to; s=fm1; t=1712585276; x=1712671676; bh=7mlMZYdfOo akFmVy+tcZ6GqJPMFaP0ZhcVt5vhqgnPQ=; b=ZZKReCpt0xvfBKdLvA3T9HN4vG 0+XaKbiVqqLBbBY/GSzHXAtNq8NW9hGeGjH2mEhmC+eQZ5aWY+sOjotKMr9+pVVT HLiHPmWA54Kn3CS59BYULr4zHAIwwEPd6g0sHRhx3iE/UrUT8h8Fv7BVSPc/0ffz bvc/1f4Daqua2ok8tgPdNoiEqF5t3YDGedU2yUJ5gSBjyt9ybQl1nd+WM27YzFLo gcum0V7dS2Q61rH5YJdDt4BTkVt5g0ChLBqUSPmK0Eh426eW+0ABKxNP4cvAPZEc dxPc62MTHgD8h+5L16pUFekoF9UQcx4QlA8vc1vYnUaSZBon4Exjr/43MDVw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:message-id :mime-version:reply-to:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1712585276; x=1712671676; bh=7mlMZYdfOoakFmVy+tcZ6GqJPMFaP0ZhcVt 5vhqgnPQ=; b=RhZu8VcCMT8bLjvYV4vGI8prHWhIeF0pvy0i9VdGoRyZ7Cm7ZKO JN7ej9uASSio3eUXfrJYxEChTj8sMIN8ck+iwyXbCDkRHEA7s/+ajHpCX2eUOWPE VAbk9+Q4UR3JYOLwT2rYzddMhAZzLTekaLXFs416cdWh1SrtHrccQfciX8CrZ1Qb T6IfFUhD1BVFrUgGC3G+UNgq3KuLOp4T3Lbm+NyEKJOzUR3YaU3pDrWovRtfEw+b Khf7uOYLtDl14y42TXkkzTrWEdKIc2ywSjvGwHL8r2XJbT59ZcFMjLypqLepSvBB tVbJtgBNk+R+fDs/TObMLSdXKtnSlu5wFRA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrudegiedgjedvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpeffhffvuffkgggtugesthdtredttd dtvdenucfhrhhomheplfhoshhhucfvrhhiphhlvghtthcuoehjohhshhesjhhoshhhthhr ihhplhgvthhtrdhorhhgqeenucggtffrrghtthgvrhhnpeelleeggedtjeejfeeuvddufe eggfektdefkeehveeuvedvvdfhgeffgfdvgfffkeenucevlhhushhtvghrufhiiigvpedt necurfgrrhgrmhepmhgrihhlfhhrohhmpehjohhshhesjhhoshhhthhrihhplhgvthhtrd horhhg X-ME-Proxy: Feedback-ID: i83e94755:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Mon, 8 Apr 2024 10:07:55 -0400 (EDT) Date: Mon, 8 Apr 2024 15:07:54 +0100 From: Josh Triplett To: pgsql-general@lists.postgresql.org Subject: Storing and comparing columns of cryptographic hashes? Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk I'm planning to store cryptographic hashes (BLAKE3) in a column of a postgresql table. I'm going to be doing a large number of operations of roughly this form: - Receive a large number of hashes via a web API call. - Check which hashes aren't already in the database. - Send back a bitmap to the user of which hashes they need to send. - Receive data from the user corresponding to those hashes. - Store the data (not in postgresql). - Add the new hashes to the database, along with a tiny value indicating what group of objects they were stored in. A few questions: - Is there a way to tell postgresql "this column contains cryptographic hashes, so you can do hash joins using any subset of the bits, without having to hash them again"? If not, should there be? - Is `bit(256)` the right type to use to store 32-byte hash values with no additional overhead? - What would be the simplest way, given an input array of hashes (which I may have to pass in as an array and use `unnest`), to filter out all the values that already exist, *and* generate a corresponding bitmap in the same order for present/not-present for the entire array (to send back to the user)? Filtering seems easy enough, but generating the bitmap less so. - Does it make more sense to store the values as one row per value, or as one row per group of values? I know that postgresql can store an entire array in one column; could that efficiently support operations like "tell me which of these objects don't exist in any array in this column" or "for all of these objects, tell me all the group-id values for rows containing them"? Thank you, Josh Triplett