{"id":22484,"date":"2023-02-15T15:56:56","date_gmt":"2023-02-15T14:56:56","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=22484"},"modified":"2023-02-16T21:24:11","modified_gmt":"2023-02-16T20:24:11","slug":"timescaledb","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/","title":{"rendered":"TimescaleDB"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.timescale.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">TimescaleDB<\/a> is a &#8220;time-series&#8221; database (TSDB). This kind of databases are optimized for storing, manipulating and querying time-series data. But&#8230; what is time-series data ?<br>Time-series data is a collection of metrics (regular) or measurements (irregular) that are tracked over time. In other words, time-series data is data that collectively represents how a system, process, or behavior changes over time.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"343\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-1024x343.jpg\" alt=\"\" class=\"wp-image-22632\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-1024x343.jpg 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-300x101.jpg 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-768x257.jpg 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-1536x515.jpg 1536w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1.jpg 2000w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>As you can imagine, time-series database are not new. The first time-series databases were mainly used for storing financial data. Today, time-series data are everywhere and we can find them in several applications and across various industries and business. The major reason is that we live surrounded by objects that are more and more connected and therefore have more and more sensors. IoT is thus one of the main use cases of time-series data, but it is obviously not the only one. Here are some other areas where this kind of data is used :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Weather (e.g. rainfall measurement)<\/li>\n\n\n\n<li>Medical (e.g. heartbeat per minutes) <\/li>\n\n\n\n<li>Website (e.g. daily visitors on a blog)<\/li>\n\n\n\n<li>Retail (e.g. annual sales)<\/li>\n\n\n\n<li>And much more&#8230;<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"550\" height=\"271\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/sample-time-seriese-analysis.png\" alt=\"\" class=\"wp-image-22515\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/sample-time-seriese-analysis.png 550w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/sample-time-seriese-analysis-300x148.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><figcaption class=\"wp-element-caption\"><em>Example of the monthly orders quantity &#8211; including forecasts<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"has-text-align-left\">TimescaleDB is actually a relational database for time-series data. It&#8217;is packaged as an extension of PostgreSQL, bringing new capabilities and features for data management and analytics as well as new optimizations and mechanisms for storage and query planner\/execution.<br>Being integrated to PostgreSQL as an extension allows TimescaleDB to take advantage of all the possibilities PostgreSQL offers in terms of data (data types, index types, schema, etc,&#8230;) but also of all the other available extensions. Some of them are particularly well adapted to work with TimescaleDB, I am thinking in particular of the well known <a href=\"https:\/\/postgis.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">PostGIS<\/a> and <a href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstatstatements.html\" target=\"_blank\" rel=\"noreferrer noopener\">pg_stat_statement<\/a>.<\/p>\n\n\n\n<p>TimescaleDB features have been designed specifically for time-series data management. Among them, we can find : <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Transparent and automated partitioning<br><\/strong>&#8211; To improve performance by keeping latest data and indexes in memory<br><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Native columnar compression<br><\/strong>&#8211; Compression according to data type (up to 97% storage reduction)<br><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Continuous and real-time aggregations<br><\/strong>&#8211; By maintaining a materialized view of aggregate time-series data to improve query performance<br><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Automated time-series data management<br><\/strong>&#8211; Retention policies, reordering policies, compression policies, aso&#8230;<br><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>In-database job-scheduling framework<br><\/strong>&#8211; To run native and user-defined actions<br><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Horizontally-scalable multi-node operation<br><\/strong>&#8211; To scale the the time-series data across many databases<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Hypertables<\/h2>\n\n\n\n<p>TimescaleDB works with a specific type of tables called hypertables. Hypertables are designed to improve insert and query performance by partitioning time-series data on its time parameter. <br>The hypertables are actually parent tables made of many regular PostgreSQL child tables, called &#8220;chunks&#8221;. Each chunk is a partition based on a time constraint and only contains data from that time range.  They are automatically set up and maintained by the database, meanwhile you insert and read the data as if it stored in a single and standard PostgreSQL table.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/hypertables-chunks-1024x780.png\" alt=\"\" class=\"wp-image-22548\" width=\"840\" height=\"639\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/hypertables-chunks-1024x780.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/hypertables-chunks-300x229.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/hypertables-chunks-768x585.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/hypertables-chunks-1536x1170.png 1536w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/hypertables-chunks.png 1956w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>https:\/\/docs.timescale.com\/timescaledb\/latest\/overview\/core-concepts\/hypertables-and-chunks\/hypertable-architecture\/<\/em><\/figcaption><\/figure>\n\n\n\n<p>You can have both hypertables and regular PostgreSQL tables in the same database. Obviously, you should choose hypertables for time-series data, and regular PostgreSQL tables for relational data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Deployment<\/h2>\n\n\n\n<p>TimescaleDB is available with several deployment options : <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Timescale Cloud<br><\/strong>Fully managed service with automatic backup and restore, HA via replication, scaling, resizing, aso&#8230;<br><a href=\"https:\/\/console.cloud.timescale.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/console.cloud.timescale.com\/<br><\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Managed Service for TimescaleDB<br><\/strong>A service is a cloud instance on your chosen cloud provider, which you can install your database on. Available cloud providers are Azure, GCP and certain regions in AWS.<br><a href=\"https:\/\/portal.managed.timescale.com\/login\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/portal.managed.timescale.com\/login<br><\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Self hosted<br><\/strong>Of course, TimescaleDB can also be installed on-premise on Linux (Debian, Ubuntu, RHEL, Rocky Linux, Fedora), on Windows or MacOS.<br>This is the option I chose for this blog.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Installation<\/h2>\n\n\n\n<p>I decided to install TimescalDB on one of my PostgreSQL 14.6 instance that I have deployed with <a href=\"https:\/\/www.dbi-services.com\/products\/yak\/\" target=\"_blank\" rel=\"noreferrer noopener\">YaK<\/a> :-). When deploying TimescalDB on an already existing instance, it is recommended to install it from source instead of using the package manager of the Linux distribution. Please check before the compatibility matrix between PostgreSQL and TimescaleDB : <a href=\"https:\/\/docs.timescale.com\/timescaledb\/latest\/how-to-guides\/upgrades\/upgrade-pg\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/docs.timescale.com\/timescaledb\/latest\/how-to-guides\/upgrades\/upgrade-pg\/<\/a>. <\/p>\n\n\n\n<p>The first thing to do is to clone the git repository and to checkout to the latest version (here 2.9.3) :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; highlight: [1,11,13]; title: ; notranslate\" title=\"\">\npostgres@timescale:\/home\/postgres\/ &#x5B;pg14.6] git clone https:\/\/github.com\/timescale\/timescaledb\nCloning into &#039;timescaledb&#039;...\nremote: Enumerating objects: 58335, done.\nremote: Counting objects: 100% (238\/238), done.\nremote: Compressing objects: 100% (161\/161), done.\nremote: Total 58335 (delta 126), reused 142 (delta 77), pack-reused 58097\nReceiving objects: 100% (58335\/58335), 30.13 MiB | 17.35 MiB\/s, done.\nResolving deltas: 100% (48073\/48073), done.\n09:08:42 postgres@timescale:\/home\/postgres\/ &#x5B;pg14.6] \n\npostgres@timescale:\/home\/postgres\/ &#x5B;pg14.6] cd timescaledb\/\n\npostgres@timescale:\/home\/postgres\/timescaledb\/ &#x5B;pg14.6] git checkout 2.9.3\nNote: switching to &#039;2.9.3&#039;.\n...\n...\n...\npostgres@timescale:\/home\/postgres\/timescaledb\/ &#x5B;pg14.6] \n<\/pre><\/div>\n\n\n<p>Then, bootstrap the built system :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres@timescale:\/home\/postgres\/timescaledb\/ &#x5B;pg14.6] .\/bootstrap\n-- The C compiler identification is GNU 10.2.1\n-- Detecting C compiler ABI info\n-- Detecting C compiler ABI info - done\n-- Check for working C compiler: \/usr\/bin\/cc - skipped\n-- Detecting C compile features\n-- Detecting C compile features - done\n-- TimescaleDB version 2.9.3. Can be updated from version 2.9.2\n-- Build type is Release\n-- Install method is &#039;source&#039;\n-- Performing Test CC_SUPPORTS_NO_UNUSED_CLI_ARG\n...\n...\n...\n-- Configuring done\n-- Generating done\n-- Build files have been written to: \/home\/postgres\/timescaledb\/build\nTimescaleDB build system initialized in .\/build. To compile, do:\ncd .\/build &amp;&amp; make\npostgres@timescale:\/home\/postgres\/timescaledb\/ &#x5B;pg14.6] \n<\/pre><\/div>\n\n\n<p>Build the extension :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres@timescale:\/home\/postgres\/timescaledb\/ &#x5B;pg14.6] cd build &amp;&amp; make\nScanning dependencies of target sqlupdatescripts\n&#x5B;  1%] Generating \/home\/postgres\/timescaledb\/build\/sql\/updates\/post-update.sql.processed\n&#x5B;  1%] Generating \/home\/postgres\/timescaledb\/build\/sql\/timescaledb--2.9.2--2.9.3.sql\n&#x5B;  2%] Generating \/home\/postgres\/timescaledb\/build\/sql\/timescaledb--2.9.1--2.9.3.sql\n&#x5B;  2%] Generating \/home\/postgres\/timescaledb\/build\/sql\/timescaledb--2.9.0--2.9.3.sql\n&#x5B;  3%] Generating \/home\/postgres\/timescaledb\/build\/sql\/timescaledb--2.8.1--2.9.3.sql\n...\n...\n...\n&#x5B; 99%] Building C object tsl\/src\/CMakeFiles\/timescaledb-tsl.dir\/remote\/utils.c.o\n&#x5B;100%] Linking C shared module timescaledb-tsl-2.9.3.so\n&#x5B;100%] Built target timescaledb-tsl\npostgres@timescale:\/home\/postgres\/timescaledb\/build\/ &#x5B;pg14.6]\n<\/pre><\/div>\n\n\n<p>And install it :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres@timescale:\/home\/postgres\/timescaledb\/build\/ &#x5B;pg14.6] make install\nInstall the project...\n-- Install configuration: &quot;Release&quot;\n-- Installing: \/u01\/app\/postgres\/product\/14\/db_6\/share\/extension\/timescaledb.control\n-- Installing: \/u01\/app\/postgres\/product\/14\/db_6\/share\/extension\/timescaledb--2.9.3.sql\n...\n...\n...\n-- Installing: \/u01\/app\/postgres\/product\/14\/db_6\/lib\/timescaledb-2.9.3.so\n-- Installing: \/u01\/app\/postgres\/product\/14\/db_6\/lib\/timescaledb.so\n-- Installing: \/u01\/app\/postgres\/product\/14\/db_6\/lib\/timescaledb-tsl-2.9.3.so\npostgres@timescale:\/home\/postgres\/timescaledb\/build\/ &#x5B;pg14.6] \n<\/pre><\/div>\n\n\n<p>Once the extension is installed, we need to add it to list of the shared_preload_libraries PostgreSQL parameter :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nshared_preload_libraries = &#039;pg_stat_statements,timescaledb&#039;\n<\/pre><\/div>\n\n\n<p>The instance must be restarted to take the new value in account.<\/p>\n\n\n\n<p>Some other instance parameters can be automatically adapted using <a href=\"https:\/\/github.com\/timescale\/timescaledb-tune\" target=\"_blank\" rel=\"noreferrer noopener\">timescaledb-tune<\/a> (memory, parallelism, WAl, aso) but I&#8217;ll not do it for this demo.<\/p>\n\n\n\n<p>Like all PostgreSQL extensions, TimescalDB needs to be added to the database. I usually create the extensions in the template1 database, so that they are automatically available for all the databases that will be created in the future :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,4]; title: ; notranslate\" title=\"\">\npostgres=# \\c template1\nYou are now connected to database &quot;template1&quot; as user &quot;postgres&quot;.\n\ntemplate1=# create extension if not exists timescaledb;\nWARNING:  \nWELCOME TO\n _____ _                               _     ____________  \n|_   _(_)                             | |    |  _  \\ ___ \\ \n  | |  _ _ __ ___   ___  ___  ___ __ _| | ___| | | | |_\/ \/ \n  | | | |  _ ` _ \\ \/ _ \\\/ __|\/ __\/ _` | |\/ _ \\ | | | ___ \\ \n  | | | | | | | | |  __\/\\__ \\ (_| (_| | |  __\/ |\/ \/| |_\/ \/\n  |_| |_|_| |_| |_|\\___||___\/\\___\\__,_|_|\\___|___\/ \\____\/\n               Running version 2.9.3\nFor more information on TimescaleDB, please visit the following links:\n\n 1. Getting started: https:\/\/docs.timescale.com\/timescaledb\/latest\/getting-started\n 2. API reference documentation: https:\/\/docs.timescale.com\/api\/latest\n 3. How TimescaleDB is designed: https:\/\/docs.timescale.com\/timescaledb\/latest\/overview\/core-concepts\n\nNote: TimescaleDB collects anonymous reports to better understand and assist our users.\nFor more information and how to disable, please see our docs https:\/\/docs.timescale.com\/timescaledb\/latest\/how-to-guides\/configuration\/telemetry.\n\nCREATE EXTENSION\ntemplate1=# \n<\/pre><\/div>\n\n\n<p>Once done, let&#8217;s create a new database to check the extension availability :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,5,9]; title: ; notranslate\" title=\"\">\npostgres=# create database timescaledb;\nCREATE DATABASE\npostgres=#\n\npostgres=# \\c timescaledb \nYou are now connected to database &quot;timescaledb&quot; as user &quot;postgres&quot;.\ntimescaledb=# \n\ntimescaledb=# \\dx\n                                            List of installed extensions\n        Name        | Version |   Schema   |                              Description                               \n--------------------+---------+------------+------------------------------------------------------------------------\n pg_prewarm         | 1.2     | extensions | prewarm relation data\n pg_stat_statements | 1.9     | extensions | track planning and execution statistics of all SQL statements executed\n pg_trgm            | 1.6     | extensions | text similarity measurement and index searching based on trigrams\n plpgsql            | 1.0     | pg_catalog | PL\/pgSQL procedural language\n timescaledb        | 2.9.3   | public     | Enables scalable inserts and complex queries for time-series data\n(5 rows)\n\ntimescaledb=# \n<\/pre><\/div>\n\n\n<p>All right !<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hypertable creation<\/h2>\n\n\n\n<p>The process of creating a hypertable is easy. First of all, let&#8217;s create some standard tables :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\ntimescaledb=# CREATE TABLE &quot;locations&quot;(\n    device_id    TEXT,\n    location     TEXT,\n    environment  TEXT\n);\nCREATE TABLE\ntimescaledb=# \n\ntimescaledb=# CREATE TABLE &quot;conditions&quot;(\n    time         TIMESTAMP WITH TIME ZONE NOT NULL,\n    device_id    TEXT,\n    temperature  NUMERIC,\n    humidity     NUMERIC\n);\n\ntimescaledb=# CREATE INDEX ON &quot;conditions&quot;(time DESC);\nCREATE INDEX\ntimescaledb=# CREATE INDEX ON &quot;conditions&quot;(device_id, time DESC);\nCREATE INDEX\ntimescaledb=#\n\ntimescaledb=# \\dt\n           List of relations\n Schema |    Name    | Type  |  Owner   \n--------+------------+-------+----------\n public | conditions | table | postgres\n public | locations  | table | postgres\n(2 rows)\n<\/pre><\/div>\n\n\n<p>Then convert one of the table to hypertable :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\ntimescaledb=# SELECT create_hypertable(&#039;conditions&#039;, &#039;time&#039;, chunk_time_interval =&gt; INTERVAL &#039;24 hours&#039;);\n<\/pre><\/div>\n\n\n<p>The first argument is the name of the table we want to convert. The second argument is the name of the column containing time values as well as the primary column to partition by. The 3rd argument is the event time that each chunk covers. Default is 7 days, here we set it to 1 day.<\/p>\n\n\n\n<p>To populate the tables, I have loaded the <a href=\"https:\/\/docs.timescale.com\/timescaledb\/latest\/tutorials\/sample-datasets\/#weather-datasets\" target=\"_blank\" rel=\"noreferrer noopener\">sample datasets<\/a> provided by Timescale :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\npostgres@timescale:\/home\/postgres\/ &#x5B;PG01] psql -U postgres -d timescaledb -c &quot;\\COPY locations FROM weather_big_locations.csv CSV&quot;\nCOPY 2000\n<\/pre><\/div>\n\n\n<p>As the quantity of data loaded into the conditions table is huge and the native&nbsp;<code>COPY<\/code>&nbsp;function of PostgreSQL is transactional and single-threaded, I used the <a href=\"https:\/\/github.com\/timescale\/timescaledb-parallel-copy\" target=\"_blank\" rel=\"noreferrer noopener\">timescaledb-parallel-copy<\/a> tool to bulk insert the data :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres@timescale:\/home\/postgres\/ &#x5B;PG01] .\/timescaledb-parallel-copy --db-name timescaledb --table conditions --file weather_big_conditions.csv --workers 2 --reporting-period 30s\nat 30s, row rate 47817.24\/sec (period), row rate 47817.24\/sec (overall), 1.435000E+06 total rows\nat 1m0s, row rate 34509.19\/sec (period), row rate 41165.22\/sec (overall), 2.470000E+06 total rows\nat 1m30s, row rate 32162.36\/sec (period), row rate 38164.07\/sec (overall), 3.435000E+06 total rows\n...\n...\nCOPY 40000000\npostgres@timescale:\/home\/postgres\/ &#x5B;PG01]\n<\/pre><\/div>\n\n\n<p>There are several views that can be query to get information about TimescaleDB objects. We can for instance list the chunks using the view <em>timescaledb_information.chunks<\/em>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1]; title: ; notranslate\" title=\"\">\ntimescaledb=# select hypertable_name, chunk_name, primary_dimension, range_start, range_end, is_compressed from timescaledb_information.chunks;\n hypertable_name |    chunk_name     | primary_dimension |      range_start       |       range_end        | is_compressed \n-----------------+-------------------+-------------------+------------------------+------------------------+---------------\n conditions      | _hyper_2_1_chunk  | time              | 2016-11-15 01:00:00+01 | 2016-11-16 01:00:00+01 | f\n conditions      | _hyper_2_2_chunk  | time              | 2016-11-16 01:00:00+01 | 2016-11-17 01:00:00+01 | f\n conditions      | _hyper_2_3_chunk  | time              | 2016-11-17 01:00:00+01 | 2016-11-18 01:00:00+01 | f\n conditions      | _hyper_2_4_chunk  | time              | 2016-11-18 01:00:00+01 | 2016-11-19 01:00:00+01 | f\n conditions      | _hyper_2_5_chunk  | time              | 2016-11-19 01:00:00+01 | 2016-11-20 01:00:00+01 | f\n conditions      | _hyper_2_6_chunk  | time              | 2016-11-20 01:00:00+01 | 2016-11-21 01:00:00+01 | f\n conditions      | _hyper_2_7_chunk  | time              | 2016-11-21 01:00:00+01 | 2016-11-22 01:00:00+01 | f\n conditions      | _hyper_2_8_chunk  | time              | 2016-11-22 01:00:00+01 | 2016-11-23 01:00:00+01 | f\n conditions      | _hyper_2_9_chunk  | time              | 2016-11-23 01:00:00+01 | 2016-11-24 01:00:00+01 | f\n conditions      | _hyper_2_10_chunk | time              | 2016-11-24 01:00:00+01 | 2016-11-25 01:00:00+01 | f\n conditions      | _hyper_2_11_chunk | time              | 2016-11-25 01:00:00+01 | 2016-11-26 01:00:00+01 | f\n conditions      | _hyper_2_12_chunk | time              | 2016-11-26 01:00:00+01 | 2016-11-27 01:00:00+01 | f\n conditions      | _hyper_2_13_chunk | time              | 2016-11-27 01:00:00+01 | 2016-11-28 01:00:00+01 | f\n conditions      | _hyper_2_14_chunk | time              | 2016-11-28 01:00:00+01 | 2016-11-29 01:00:00+01 | f\n conditions      | _hyper_2_15_chunk | time              | 2016-11-29 01:00:00+01 | 2016-11-30 01:00:00+01 | f\n conditions      | _hyper_2_16_chunk | time              | 2016-11-30 01:00:00+01 | 2016-12-01 01:00:00+01 | f\n conditions      | _hyper_2_17_chunk | time              | 2016-12-01 01:00:00+01 | 2016-12-02 01:00:00+01 | f\n conditions      | _hyper_2_18_chunk | time              | 2016-12-02 01:00:00+01 | 2016-12-03 01:00:00+01 | f\n conditions      | _hyper_2_19_chunk | time              | 2016-12-03 01:00:00+01 | 2016-12-04 01:00:00+01 | f\n conditions      | _hyper_2_20_chunk | time              | 2016-12-04 01:00:00+01 | 2016-12-05 01:00:00+01 | f\n conditions      | _hyper_2_21_chunk | time              | 2016-12-05 01:00:00+01 | 2016-12-06 01:00:00+01 | f\n conditions      | _hyper_2_22_chunk | time              | 2016-12-06 01:00:00+01 | 2016-12-07 01:00:00+01 | f\n conditions      | _hyper_2_23_chunk | time              | 2016-12-07 01:00:00+01 | 2016-12-08 01:00:00+01 | f\n conditions      | _hyper_2_24_chunk | time              | 2016-12-08 01:00:00+01 | 2016-12-09 01:00:00+01 | f\n conditions      | _hyper_2_25_chunk | time              | 2016-12-09 01:00:00+01 | 2016-12-10 01:00:00+01 | f\n conditions      | _hyper_2_26_chunk | time              | 2016-12-10 01:00:00+01 | 2016-12-11 01:00:00+01 | f\n conditions      | _hyper_2_27_chunk | time              | 2016-12-11 01:00:00+01 | 2016-12-12 01:00:00+01 | f\n conditions      | _hyper_2_28_chunk | time              | 2016-12-12 01:00:00+01 | 2016-12-13 01:00:00+01 | f\n conditions      | _hyper_2_29_chunk | time              | 2016-12-13 01:00:00+01 | 2016-12-14 01:00:00+01 | f\n(29 rows)\n\ntimescaledb=# \n\n<\/pre><\/div>\n\n\n<p>Or the view<em> timescaledb_information.hypertables<\/em> to get information about the existing hypertables :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1]; title: ; notranslate\" title=\"\">\ntimescaledb=# select hypertable_name, num_dimensions, num_chunks, compression_enabled, is_distributed from timescaledb_information.hypertables;\n hypertable_name | num_dimensions | num_chunks | compression_enabled | is_distributed \n-----------------+----------------+------------+---------------------+----------------\n conditions      |              1 |         29 | f                   | f\n(1 row)\n\ntimescaledb=# \n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Query the data<\/h2>\n\n\n\n<p>After insertion, the data can be read as usual :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\ntimescaledb=# SELECT * FROM conditions ORDER BY time DESC LIMIT 10;\n          time          |     device_id      | temperature | humidity \n------------------------+--------------------+-------------+----------\n 2016-11-30 07:04:00+01 | weather-pro-001641 |        60.2 |       48\n 2016-11-30 06:04:00+01 | weather-pro-001803 |          62 |     55.9\n 2016-11-30 05:50:00+01 | weather-pro-001082 |        63.9 |       48\n 2016-11-30 05:18:00+01 | weather-pro-001601 |          60 |     55.8\n 2016-11-30 04:50:00+01 | weather-pro-000372 |          60 |     48.2\n 2016-11-30 04:22:00+01 | weather-pro-000799 |          55 |     40.8\n 2016-11-30 03:46:00+01 | weather-pro-001288 |          60 |     48.2\n 2016-11-30 03:36:00+01 | weather-pro-001969 |          62 |     48.1\n 2016-11-30 03:34:00+01 | weather-pro-000043 |          62 |     55.9\n 2016-11-30 03:34:00+01 | weather-pro-000732 |        61.9 |       48\n(10 rows)\n\ntimescaledb=# \n<\/pre><\/div>\n\n\n<p>And using functions like avg, min, max, we can have interesting results.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\ntimescaledb=# SELECT date_trunc(&#039;hour&#039;, time) &quot;hour&quot;,\ntrunc(avg(temperature), 2) avg_temp,\ntrunc(min(temperature), 2) min_temp,\ntrunc(max(temperature), 2) max_temp\nFROM conditions c\nWHERE c.device_id IN (\n    SELECT device_id FROM locations\n    WHERE location LIKE &#039;field-%&#039;\n) GROUP BY &quot;hour&quot; ORDER BY &quot;hour&quot; ASC LIMIT 24;\n          hour          | avg_temp | min_temp | max_temp \n------------------------+----------+----------+----------\n 2016-11-15 13:00:00+01 |    73.57 |    68.00 |    79.29\n 2016-11-15 14:00:00+01 |    74.57 |    68.79 |    80.49\n 2016-11-15 15:00:00+01 |    75.57 |    69.39 |    81.49\n 2016-11-15 16:00:00+01 |    76.56 |    70.09 |    82.59\n 2016-11-15 17:00:00+01 |    77.57 |    71.09 |    83.59\n 2016-11-15 18:00:00+01 |    78.57 |    71.99 |    84.89\n 2016-11-15 19:00:00+01 |    79.55 |    72.49 |    86.59\n 2016-11-15 20:00:00+01 |    80.54 |    73.29 |    87.39\n 2016-11-15 21:00:00+01 |    81.52 |    74.59 |    88.39\n 2016-11-15 22:00:00+01 |    82.51 |    75.79 |    89.29\n 2016-11-15 23:00:00+01 |    83.51 |    76.49 |    90.00\n 2016-11-16 00:00:00+01 |    84.49 |    77.49 |    90.00\n 2016-11-16 01:00:00+01 |    85.45 |    77.99 |    90.00\n 2016-11-16 02:00:00+01 |    85.37 |    77.89 |    90.00\n 2016-11-16 03:00:00+01 |    84.37 |    76.79 |    89.60\n 2016-11-16 04:00:00+01 |    83.38 |    75.99 |    88.70\n 2016-11-16 05:00:00+01 |    82.36 |    75.09 |    87.90\n 2016-11-16 06:00:00+01 |    81.35 |    73.79 |    86.90\n 2016-11-16 07:00:00+01 |    80.38 |    72.49 |    86.10\n 2016-11-16 08:00:00+01 |    79.41 |    71.09 |    85.19\n 2016-11-16 09:00:00+01 |    78.43 |    69.79 |    84.40\n 2016-11-16 10:00:00+01 |    77.44 |    68.50 |    83.69\n 2016-11-16 11:00:00+01 |    77.49 |    68.50 |    83.99\n 2016-11-16 12:00:00+01 |    78.52 |    69.29 |    84.89\n(24 rows)\n\ntimescaledb=# \n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Compression<\/h2>\n\n\n\n<p>When compression is enabled, the data stored in the hypertables is compressed chunk by chunk. A compressed chunk stores the data in a hybrid row-columnar format, where multiple records are grouped into a single row. The goal is to store the data into a single row instead of using a lot of rows to store the same data. Less rows means less disk space required. Easy, isn&#8217;t ? Let&#8217;s see how it work.<\/p>\n\n\n\n<p>To enable compression on the table :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\ntimescaledb=# ALTER TABLE conditions SET (timescaledb.compress, timescaledb.compress_segmentby = &#039;device_id&#039;);\nALTER TABLE\ntimescaledb=#\n<\/pre><\/div>\n\n\n<p>As you can see, we have the possibility to define which column to segment by. As I&#8217;m not able to write an understandable explanation about this, I will simply reuse the explanation that you can find in the official documentation :<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&#8220;\u2026The column that a table is segmented by contains only a single entry, while all other columns can have multiple arrayed entries.<br>Because a single value is associated with each compressed row, there is no need to decompress to evaluate the value in that column. This means that queries with WHERE clauses that filter by a segmentby column are much more efficient, because decompression can happen after filtering instead of before. This avoids the need to decompress filtered-out rows altogether.<br>Because some queries are more efficient than others, it is important to pick the correct set of segmentby columns. If your table has a primary key all of the primary key columns, except for time, can go into the segmentby list.&#8221;<\/p>\n<\/blockquote>\n\n\n\n<p>We can now add a compression policy to compress chunks that are older than 7 days.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,10]; title: ; notranslate\" title=\"\">\ntimescaledb=# SELECT add_compression_policy(&#039;conditions&#039;, INTERVAL &#039;7 days&#039;);\n add_compression_policy \n------------------------\n                   1000\n(1 row)\n\ntimescaledb=# \\x\nExpanded display is on.\n\ntimescaledb=# SELECT * FROM timescaledb_information.jobs WHERE proc_name=&#039;policy_compression&#039;;\n-&#x5B; RECORD 1 ]-----+-------------------------------------------------\njob_id            | 1000\napplication_name  | Compression Policy &#x5B;1000]\nschedule_interval | 12:00:00\nmax_runtime       | 00:00:00\nmax_retries       | -1\nretry_period      | 01:00:00\nproc_schema       | _timescaledb_internal\nproc_name         | policy_compression\nowner             | postgres\nscheduled         | t\nfixed_schedule    | f\nconfig            | {&quot;hypertable_id&quot;: 2, &quot;compress_after&quot;: &quot;7 days&quot;}\nnext_start        | 2023-02-15 19:44:40.692243+01\ninitial_start     | \nhypertable_schema | public\nhypertable_name   | conditions\ncheck_schema      | _timescaledb_internal\ncheck_name        | policy_compression_check\n\ntimescaledb=# \n<\/pre><\/div>\n\n\n<p>It&#8217;s very important that you don&#8217;t compress all the data because compressed rows can not be updated or deleted. Therefore, take care to compress only data that are old enough and for which you are sure that no update will be required.<\/p>\n\n\n\n<p>Good. We have now enabled the compression on the hypertable, and created an automatic job to perform the compression of chunks which contains data older than 7 days.<\/p>\n\n\n\n<p>Thanks to the view <em>hypertable_compression_stats<\/em>, we can compare the size of the table before and after the compression :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [4]; title: ; notranslate\" title=\"\">\ntimescaledb=# SELECT pg_size_pretty(before_compression_total_bytes) as &quot;before compression&quot;, pg_size_pretty(after_compression_total_bytes) as &quot;after compression&quot; FROM hypertable_compression_stats(&#039;conditions&#039;);\n before compression | after compression \n--------------------+-------------------\n 6603 MB            | 186 MB\n(1 row)\n\ntimescaledb=#\n<\/pre><\/div>\n\n\n<p>Quite impressive, isn&#8217;t ? This performance is due to the fact that TimescaleDB uses, behind the scene, the best time-series data compression algorithms. Actually, you can not choose the algorithme you want to use when compressing your hypertables as TimescaleDB chooses the most appropriate one according to the type of data : <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Delta-of-delta + Simple-8b with run-length encoding compression <br><\/strong>for integers, timestamps, and other integer-like types<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>XOR-based compression<br><\/strong>for floats<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Whole-row dictionary compression<br><\/strong>for columns with a few repeating values (plus LZ compression on top)<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>LZ-based array compression<br><\/strong>for all other types<\/li>\n<\/ul>\n\n\n\n<p>If you want to take a deep dive into these various algorithms and know how they are implemented in TimescaleDB,  I recommend to read <a href=\"https:\/\/www.timescale.com\/blog\/time-series-compression-algorithms-explained\/\" target=\"_blank\" rel=\"noreferrer noopener\">this blog<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Retention<\/h2>\n\n\n\n<p>As we have seen, setting up compression is an efficient way to save disk space. But is it really worth to keep very old data, even if they are compressed ? Of course this depends on the requirements of the business, but in a general way it&#8217;s always good to configure an automatic purge of old data. TimescaleDB offers this possibility :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,12]; title: ; notranslate\" title=\"\">\ntimescaledb=# SELECT add_retention_policy(&#039;conditions&#039;, INTERVAL &#039;6 months&#039;);\n add_retention_policy \n----------------------\n                 1001\n(1 row)\n\ntimescaledb=# \n\ntimescaledb=# \\x\nExpanded display is on.\n\ntimescaledb=# SELECT * FROM timescaledb_information.jobs WHERE job_id=1001;\n-&#x5B; RECORD 1 ]-----+---------------------------------------------\njob_id            | 1001\napplication_name  | Retention Policy &#x5B;1001]\nschedule_interval | 1 day\nmax_runtime       | 00:05:00\nmax_retries       | -1\nretry_period      | 00:05:00\nproc_schema       | _timescaledb_internal\nproc_name         | policy_retention\nowner             | postgres\nscheduled         | t\nfixed_schedule    | f\nconfig            | {&quot;drop_after&quot;: &quot;6 mons&quot;, &quot;hypertable_id&quot;: 2}\nnext_start        | 2023-02-16 15:07:31.789794+01\ninitial_start     | \nhypertable_schema | public\nhypertable_name   | conditions\ncheck_schema      | _timescaledb_internal\ncheck_name        | policy_retention_check\n\ntimescaledb=#\n<\/pre><\/div>\n\n\n<p>Old chunks can also be dropped manually :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\ntimescaledb=# SELECT drop_chunks(&#039;conditions&#039;, INTERVAL &#039;6 months&#039;);\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>This was my first test with TimescaleDB. It seems to be very powerful product when it comes to store and manage time-series data. The compression and the retention features are particularly interesting to save disk space, especially when your data are stored in the cloud. Your monthly bill can be reduced considerably with this :-).<\/p>\n\n\n\n<p>There are still other features that seem to be interesting to test, for example the continuous aggregates or the distributed hypertables. Maybe for another blog\u2026<\/p>\n\n\n\n<p>I hope you enjoyed reading this blog as much as I enjoyed writing it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction TimescaleDB is a &#8220;time-series&#8221; database (TSDB). This kind of databases are optimized for storing, manipulating and querying time-series data. But&#8230; what is time-series data ?Time-series data is a collection of metrics (regular) or measurements (irregular) that are tracked over time. In other words, time-series data is data that collectively represents how a system, process, [&hellip;]<\/p>\n","protected":false},"author":30,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[229,198,83],"tags":[652,378,77,2842,2840,2841],"type_dbi":[],"class_list":["post-22484","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","category-database-management","category-postgresql","tag-data","tag-extension","tag-postgresql","tag-time-series","tag-timescale","tag-timescaledb"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>TimescaleDB - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/timescaledb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"TimescaleDB\" \/>\n<meta property=\"og:description\" content=\"Introduction TimescaleDB is a &#8220;time-series&#8221; database (TSDB). This kind of databases are optimized for storing, manipulating and querying time-series data. But&#8230; what is time-series data ?Time-series data is a collection of metrics (regular) or measurements (irregular) that are tracked over time. In other words, time-series data is data that collectively represents how a system, process, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/timescaledb\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-15T14:56:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-02-16T20:24:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-1024x343.jpg\" \/>\n<meta name=\"author\" content=\"Jo\u00ebl Cattin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jo\u00ebl Cattin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/\"},\"author\":{\"name\":\"Jo\u00ebl Cattin\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/2c774f00321ee734515f0c2f6a96b780\"},\"headline\":\"TimescaleDB\",\"datePublished\":\"2023-02-15T14:56:56+00:00\",\"dateModified\":\"2023-02-16T20:24:11+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/\"},\"wordCount\":1638,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/02\\\/DSC_0066-2000x670-1-1024x343.jpg\",\"keywords\":[\"data\",\"Extension\",\"PostgreSQL\",\"time-series\",\"timescale\",\"timescaledb\"],\"articleSection\":[\"Database Administration &amp; Monitoring\",\"Database management\",\"PostgreSQL\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/\",\"name\":\"TimescaleDB - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/02\\\/DSC_0066-2000x670-1-1024x343.jpg\",\"datePublished\":\"2023-02-15T14:56:56+00:00\",\"dateModified\":\"2023-02-16T20:24:11+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/2c774f00321ee734515f0c2f6a96b780\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/02\\\/DSC_0066-2000x670-1.jpg\",\"contentUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/02\\\/DSC_0066-2000x670-1.jpg\",\"width\":2000,\"height\":670},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/timescaledb\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"TimescaleDB\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/2c774f00321ee734515f0c2f6a96b780\",\"name\":\"Jo\u00ebl Cattin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g\",\"caption\":\"Jo\u00ebl Cattin\"},\"description\":\"Jo\u00ebl Cattin has more than three years of experience in databases management. He is specialized in Oracle solutions such as Data Guard and RMAN and has a good background knowledge of Oracle Database Appliance (ODA), Real Application Cluster (RAC) and applications development on APEX. Jo\u00ebl Cattin\u2019s experience includes other RDBMS, such as PostgreSQL and MySQL. He is Oracle Database 12c Administrator Certified Professional, EDB Postgres Advanced Server 9.5 Certified Professional, RedHat Certified System Administrator and ITILv3 Foundation for Service Management Certified. Jo\u00ebl Cattin holds a degree from the \u00c9cole Sup\u00e9rieure d\u2019Informatique de Gestion (ESIG) in Del\u00e9mont and a Federal Certificate of Proficiency in Computer Science (Certificat f\u00e9d\u00e9ral de Capacit\u00e9 \u2013 CFC).\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/joel-cattin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"TimescaleDB - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/","og_locale":"en_US","og_type":"article","og_title":"TimescaleDB","og_description":"Introduction TimescaleDB is a &#8220;time-series&#8221; database (TSDB). This kind of databases are optimized for storing, manipulating and querying time-series data. But&#8230; what is time-series data ?Time-series data is a collection of metrics (regular) or measurements (irregular) that are tracked over time. In other words, time-series data is data that collectively represents how a system, process, [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/","og_site_name":"dbi Blog","article_published_time":"2023-02-15T14:56:56+00:00","article_modified_time":"2023-02-16T20:24:11+00:00","og_image":[{"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-1024x343.jpg","type":"","width":"","height":""}],"author":"Jo\u00ebl Cattin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jo\u00ebl Cattin","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/"},"author":{"name":"Jo\u00ebl Cattin","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780"},"headline":"TimescaleDB","datePublished":"2023-02-15T14:56:56+00:00","dateModified":"2023-02-16T20:24:11+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/"},"wordCount":1638,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-1024x343.jpg","keywords":["data","Extension","PostgreSQL","time-series","timescale","timescaledb"],"articleSection":["Database Administration &amp; Monitoring","Database management","PostgreSQL"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/timescaledb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/","url":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/","name":"TimescaleDB - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1-1024x343.jpg","datePublished":"2023-02-15T14:56:56+00:00","dateModified":"2023-02-16T20:24:11+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/timescaledb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1.jpg","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2023\/02\/DSC_0066-2000x670-1.jpg","width":2000,"height":670},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/timescaledb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"TimescaleDB"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780","name":"Jo\u00ebl Cattin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g","caption":"Jo\u00ebl Cattin"},"description":"Jo\u00ebl Cattin has more than three years of experience in databases management. He is specialized in Oracle solutions such as Data Guard and RMAN and has a good background knowledge of Oracle Database Appliance (ODA), Real Application Cluster (RAC) and applications development on APEX. Jo\u00ebl Cattin\u2019s experience includes other RDBMS, such as PostgreSQL and MySQL. He is Oracle Database 12c Administrator Certified Professional, EDB Postgres Advanced Server 9.5 Certified Professional, RedHat Certified System Administrator and ITILv3 Foundation for Service Management Certified. Jo\u00ebl Cattin holds a degree from the \u00c9cole Sup\u00e9rieure d\u2019Informatique de Gestion (ESIG) in Del\u00e9mont and a Federal Certificate of Proficiency in Computer Science (Certificat f\u00e9d\u00e9ral de Capacit\u00e9 \u2013 CFC).","url":"https:\/\/www.dbi-services.com\/blog\/author\/joel-cattin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/22484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/30"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=22484"}],"version-history":[{"count":53,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/22484\/revisions"}],"predecessor-version":[{"id":22653,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/22484\/revisions\/22653"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=22484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=22484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=22484"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=22484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}