Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nK0ZB-0008VL-Sx for pgsql-sql@arkaria.postgresql.org; Tue, 15 Feb 2022 16:20:38 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nK0ZA-00071p-HA for pgsql-sql@arkaria.postgresql.org; Tue, 15 Feb 2022 16:20:36 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nK0ZA-00070g-5F for pgsql-sql@lists.postgresql.org; Tue, 15 Feb 2022 16:20:36 +0000 Received: from premium22-1.web-hosting.com ([68.65.122.103]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nK0Z2-0006Ul-1e for pgsql-sql@lists.postgresql.org; Tue, 15 Feb 2022 16:20:35 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=misuse.org; s=default; h=Content-Type:Cc:To:Subject:Message-ID:Date:From:In-Reply-To: References:MIME-Version:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=hf25XxemO+LvyTb0pkYTf0tAyGy3VX9CAiodT49iHlo=; b=MoNF+Mf+IZ7/Ha93dnXbC0I4EI LEew4ZX3c9g37k6+izikSjXhteBGiEMqj5WB8gUCPeu/EUitOo7WQZ78JvmuWoYzk2SPJdPTvcbm2 bqOJlRq3q7ac6XzoRtNDnkpYj4iI1OzyWGR35KHNPfz/8RtAoOG+LLuBQgoflha19mnXV649YSWEZ 0FmqDXE+KohC997OBVuWhXhN4NQrJ91tpy68hBuBPzzbcktHjaGXkt6QZoQENqgMGmPdC4YQfBZYn 92I3BECfIzHlsQN3so4Svhg0AN1JjWbrq86IgUVHYYb9i4Q+0tvsX+JYosHn7s5TbAq9WQ3jp7inF K4iLqbPQ==; Received: from mail-qt1-f179.google.com ([209.85.160.179]:37826) by premium22.web-hosting.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1nK0Ys-00AH69-LC for pgsql-sql@lists.postgresql.org; Tue, 15 Feb 2022 11:20:25 -0500 Received: by mail-qt1-f179.google.com with SMTP id ca12so1349053qtb.4 for ; Tue, 15 Feb 2022 08:20:18 -0800 (PST) X-Gm-Message-State: AOAM531s61BFOBlasPuOkI0yLCn0eXzCsS88P2hCyaagtjGA4adFGd3p vR4j5Kyy92cFdveNeJlTl6kdN0mSBq9jdqyZyww= X-Google-Smtp-Source: ABdhPJzN0n24a7jhZrzj9YuAtBkDixXF6iEEucQ9Ps8uHS4UwOPJxCHuYdCgz1iUnuVWI2knDty2GHFj7StI0z27Po0= X-Received: by 2002:ac8:5c14:: with SMTP id i20mr3191304qti.397.1644942017680; Tue, 15 Feb 2022 08:20:17 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Steve Midgley Date: Tue, 15 Feb 2022 08:20:07 -0800 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: Storing thousands of csv files in postgresql To: Ion Alberdi Cc: pgsql-sql Content-Type: multipart/alternative; boundary="000000000000a3dd6505d810e8e6" X-OutGoing-Spam-Status: No, score=4.9 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - premium22.web-hosting.com X-AntiAbuse: Original Domain - lists.postgresql.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - misuse.org X-Get-Message-Sender-Via: premium22.web-hosting.com: authenticated_id: science@misuse.org X-Authenticated-Sender: premium22.web-hosting.com: science@misuse.org X-Source: X-Source-Args: X-Source-Dir: X-From-Rewrite: unmodified, already matched List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000a3dd6505d810e8e6 Content-Type: text/plain; charset="UTF-8" On Tue, Feb 15, 2022 at 12:15 AM Ion Alberdi wrote: > Hello to all, > > One of the use cases we need to implement requires > storing and query-ing thousands (and more as the product grows) of csv > files > that have different schema-s (by schema we mean column names and their > type). > > These csv would then need to be maintained with operations like: > - add column, > - add row, > - delete row, > - read: filter/sort/paginate, > - write: edit column values. > > Let's assume that we store the definition of each schema in a dedicated > table, > with the schema defined in a json column. With this schema we'll be able > translate the read/write/update queries to these imported csv files into > related SQL queries. > > The remaining question is how to store the data of each file in the DB. > > As suggested by https://www.postgresql.org/docs/10/sql-copy.html there is > a way to import a csv in its own table. By using this approach for each > csv-s we see: > > Pros: > - All postgresql types available: > https://www.postgresql.org/docs/9.5/datatype.html, > - Constraints on columns, among others unicity constraints, > that makes the DB guarantee rows will not duplicated (relevant to the > add row use case), > - Debuggability: enables using standard SQL to browse csv data, > - Can reuse existing libraries to generate dynamic SQL queries [1] > > Cons: > - Need to have as many tables as different schemas. > > Another solution could consist of implementing a document store in > postgresql, > by storing all columns of a row in a single jsonb column. > > Pros: > - Single table to store all different imported csv-s. > > Cons: > - Less types available > https://www.postgresql.org/docs/9.4/datatype-json.html, > - No constraint on columns, (no unicity or data validation constraints > that should be delegated to the application), > - Ramp-up on json* functions, (and I wonder whether there are libraries > to safely generate dynamic SQL queries on json columns), > (- Debuggability: this is not such a big con as json_to_record enables > going back to a standard SQL experience) > > Based on this first pro/con list, we're wondering about the scalability > limits faced by postgresql instances getting more tables in a given DB. > > Browsing the web, we saw two main issues: > - One related to the OS "you may see some performance degradation > associated > with databases containing many tables. PostgreSQL may use a large number > of > files for storing the table data, and performance may suffer if the > operating > system does not cope well with many files in a single directory." [1] > - Related to that, the fact that some operations like autovacuum are O(N) > on number of tables [3] > > On the other hand, reading timescaledb's architecture > https://docs.timescale.com/timescaledb/latest/overview/core-concepts/hypertables-and-chunks/#partitioning-in-hypertables-with-chunks > "Each chunk is implemented using a standard database table." > it seems that their platform took such a direction, which may have proved > the scalability of such an approach. > > My question is thus the following: > how many of such tables can a single postgresql instance handle without > trouble [4]? > > Any challenge/addition to the pro/cons list described above would be very > welcome too. > > Given that no matter what answer the community can give you about the number of tables per DB is reasonable, if your project is successful, you'll probably exceed that limit eventually. Why not plan for federation at the start (a little, at low cost) by including the PG server URL and DB name where the CSV is stored in your CSV table schema store? That way, for now, you just store CSVs in the current PG server/DB, and should it get overwhelmed, it's relatively easy to just point accessors to a different server and/or DB in the future for some CSV resources? The main upfront increased cost is that you'll need to solve for credential management for the various PG servers. If you're in AWS, "Secrets Manager" would work - but there are lots of equivalent solutions out there. FWIW, I think your analysis of the pros and cons of tables vs documents is excellent but slightly incomplete. In my experience with document DB, I only postpone all the downsides, in order to get the immediate benefits (kind of like a "sugar high"). Eventually you have to solve for everything you solve for with the table-based solution. You just don't have to solve for it upfront, like in the table approach. And, at least on the project where I got bit by a document db architecture, it's a lot harder to solve for many of these problems when you solve for them later in your project, so it's better just to build using structured tables up front for a project with meaningful structures and lots of data. Steve --000000000000a3dd6505d810e8e6 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Tue, Feb 15, 2022 at 12:15 AM Ion = Alberdi <ion.alberdi@pricem= oov.com> wrote:
Hello to all,

One of the use cases we need t= o implement requires
storing and query-ing thousands (and more as the pr= oduct grows) of csv files
that have different schema-s (by schema we mea= n column names and their type).

These csv would then need to be main= tained with operations like:
- add column,
- add row,
- delete row= ,
- read: filter/sort/paginate,
- write: edit column values.

L= et's assume that we store the definition of each schema in a dedicated = table,
with the schema defined in a json column. With this schema we'= ;ll be able translate the read/write/update queries to these imported csv f= iles into related SQL queries.

The remaining question is how to stor= e the data of each file in the DB.

As suggested by https://www.p= ostgresql.org/docs/10/sql-copy.html there is a way to import a csv in i= ts own table. By using this approach for each csv-s we see:

Pros:- All postgresql types available: https://www.postgresql.org/docs/9.5= /datatype.html,
- Constraints on columns, among others unicity const= raints,
=C2=A0 that makes the DB guarantee rows will not duplicated (rel= evant to the add row use case),
- Debuggability: enables using standard = SQL to browse csv data,
- Can reuse existing libraries to generate dynam= ic SQL queries [1]

Cons:
- Need to have as many tables as differe= nt schemas.

Another solution could consist of implementing a documen= t store in postgresql,
by storing all columns of a row in a single jsonb= column.

Pros:
- Single table to store all different imported csv= -s.

Cons:
- Less types available https://www.postgresql= .org/docs/9.4/datatype-json.html,
- No constraint on columns, (no un= icity or data validation constraints
that should be delegated to the app= lication),
- Ramp-up on json* functions, (and I wonder whether there are= libraries
to safely generate dynamic SQL queries on json columns),
(= - Debuggability: this is not such a big con as json_to_record enables
go= ing back to a standard SQL experience)

Based on this first pro/con l= ist, we're wondering about the scalability
limits faced by postgresq= l instances getting more tables in a given DB.

Browsing the web, we = saw two main issues:
- One related to the OS "you may see some perf= ormance degradation associated
=C2=A0 with databases containing many tab= les. PostgreSQL may use a large number of
=C2=A0 files for storing the t= able data, and performance may suffer if the operating
=C2=A0 system doe= s not cope well with many files in a single directory." [1]
- Relat= ed to that, the fact that some operations like autovacuum are O(N) on numbe= r of tables [3]

On the other hand, reading timescaledb's archite= cture https://docs.timescale.com/timescaledb/latest/overview/c= ore-concepts/hypertables-and-chunks/#partitioning-in-hypertables-with-chunk= s
"Each chunk is implemented using a standard database table.&q= uot;
it seems that their platform took such a direction, which may have = proved the scalability of such an approach.

My question is thus the = following:
how many of such tables can a single postgresql instance hand= le without trouble [4]?

Any challenge/addition to the pro/cons = list described above would be very welcome too.

=C2=A0
Given that no matter what answer the community c= an give you about the number of tables per DB is reasonable, if your projec= t is successful, you'll probably exceed that limit eventually. Why not = plan for federation at the start (a little, at low cost) by including the P= G server URL and DB name where the CSV is stored in your CSV table schema s= tore? That way, for now, you just store CSVs in the current PG server/DB, a= nd should it get overwhelmed, it's relatively easy to just point access= ors to a different server and/or DB in the future for some CSV resources? T= he main upfront increased cost is that you'll need to solve for credent= ial management for the various PG servers. If you're in AWS, "Secr= ets Manager" would work - but there are lots of equivalent solutions o= ut there.

FWIW, I think your analysis of the pros = and cons of tables vs documents is excellent but slightly incomplete. In my= experience with document DB, I only postpone all the downsides, in order t= o get the immediate benefits (kind of like a "sugar high"). Event= ually you have to solve for everything you solve for with the table-based s= olution. You just don't have to solve for it upfront, like in the table= approach. And, at least on the project where I got bit by a document db ar= chitecture, it's a lot harder to solve for many of these problems when = you solve for them later in your project, so it's better just to build = using structured tables up front for a project with meaningful structures a= nd lots of data.

Steve
--000000000000a3dd6505d810e8e6--