Partitioning in Postgres, 2022 Edition
brandur.org
brandur.org
Something like:
CREATE TABLE logs (
time TIMESTAMPTZ,
data JSONB
) PARTITION ON time IN INTERVAL '1 day'
And it just creates/manages these partitions for every day?If you can already manage partitions like this manually it feels like the next step is to just have it be automatic. So you have less of a need to switch to Timescale or ClickHouse or whatever other database as the amount of data you're storing/querying grows. (Yeah that's a handwave-y suggestion but at least you could stick with Postgres for longer.)
- https://github.com/pgpartman/pg_partman
- https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Postg...
TSL is mainly about not competing with their cloud offerings. So you can't run a database-as-a-service for time series data with it.
More about the license: https://www.timescale.com/blog/building-open-source-business...
Comparison about the open source and community editions: https://docs.timescale.com/timescaledb/latest/timescaledb-ed...
Regardless of what they say on a public page, that is a vague license. Can I use Timescale to provide a SaaS service that collects application traces, and I provide a DSL to query the database that is not exposing the DB directly? No, its a gray area.
Yes you can. (Timescale co-founder here)
The vast majority of people using TimescaleDB use our community/open-source software (rather than managed Cloud), and vast vast majority of those use the TSL (Community) edition, including many as part of their SaaS service.
It's a three-part test for asking "is this a value added service?" [0] Given the way your have described your service, sounds like a clear "Yes".
- Is your SaaS service primarily different than a database product/service? Yes.
- Is the main value of your SaaS service different than that of a time-series database, and you aren't primarily offering your SaaS service as a time-series database? Yes.
- Are users prevented from directly defining internal table structures through the database DDL? Presumably yes.
[0] https://www.timescale.com/legal/licenses#section-3-10-value-...
It's a great extension. We have used it in production for a few years now, as part of a commercial on-prem observability tool (an app that keeps around 1TB of data at any one time, written at avg 15mb/sec, maybe 500ish partitions, user configurable retention strategy). It is extremely reliable. Support for Keith F working on it is one of the reasons I like Crunchy.
edit: I clearly didn't read the link before writing this
CREATE TABLE business_data (
customer_key TEXT,
data JSONB
) PARTITION ON customer_key
where it creates a partition for each unique value of customer_key. Seems like this ought not to be that hard.CREATE TABLE … PARTITION OF … FOR VALUES IN ('the_customer');
https://www.postgresql.org/docs/current/ddl-partitioning.htm...
However if you really want to go down this road, you could put a trigger on the main customer table for INSERT or UPDATE to run a SECURITY DEFINED (setuid) function that runs a CREATE TABLE … IF NOT EXISTS DDL query to your specifications. Just beware of corner cases and be extremely careful regarding secure access to modifications of that customers table.
It’s as easy as:
CREATE EXTENSION timescaledb:
SELECT create_hypertable('table_name', 'time_column_name', chunk_time_interval=>interval '1 day'):
Disclaimer: I’m a TimescalerPartitioning a big table is definitely on my TODO list. How big does a typical table need to grow before partitioning is seen as a 'necessity'? What are some ways current partitioning strategies have made things too difficult?
Often partitions are made for time-related data, and these partitions may have smaller granularity. Say, you want to keep last 6 months of data, but make the partitions week-sized, or even day-sized, to make transitions more smooth.
One gotcha to be careful with is that if you run a query spanning multiple partitions, it will run them all at once and if your database isn't super big - will bring it to its knees.
Outside of that really no issues. We also use Timescale quite heavily, which also works fantastic.
Not if these are analytical queries...
If you're wondering what the point of partitioning a table that's going to be used for analytical queries: if you partition by insertion time, and your table is append-only, then you're only ever writing to one partition (the newest one), with all the partitions other than the newest one being "closed" — VACUUM FREEZEd and then never written to again. So, rather than one huge set of indices that get gradually-more expensive to update as you insert more records, those write costs will only rise up to the end of the month/week/day, and then jump back down to zero as you begin writing to a new empty partition.
Something like this:
create table orders(
order_id int unique
, year int
, primary key (order_id, year)
);
create table order_data(
order_id int
, year int
, LOADS_OF_COLUMNS_HERE jsonb
, primary key (order_id, year)
, foreign key (order_id, year) references orders(order_id, year)
) partition by list(year);