一、安裝環境
Windows 10 x64 bit
postgresql-10.12-3-windows-x64.exe
下載地址: https://www.enterprisedb.com/thank-you-downloading-postgresql?cid=62
postgis-bundle-pg10x64-setup-3.0.1-1.exe
下載地址: https://winnie.postgis.net/download/windows/pg10/buildbot/postgis-bundle-pg10x64-setup-3.0.1-1.exe
timescaledb-postgresql-10_1.7.0-windows-amd64.zip
下載地址: https://timescalereleases.blob.core.windows.net/windows/timescaledb-postgresql-10_1.7.0-windows-amd64.zip
二、安裝步驟
運行postgresql-10.12-3-windows-x64.exe
正常安裝完成即可,如果無法正常安裝請使用管理員權限安裝。
值得注意的是,由於這裏已經提供了PostGIS Bundle 3.0
的擴展插件,安裝最後無需通過StackBuilder
再次下載了。
- 配置 IP地址遠程訪問
找到安裝\PostgreSQL\10\data
目錄下的postgresql.conf
文件:
# - Connection Settings -
listen_addresses = '*' # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost'; use '*' for all
# (change requires restart)
port = 5432 # (change requires restart)
max_connections = 100 # (change requires restart)
...
...
確認監聽地址爲:***listen_addresses = ‘*’
***
找到安裝\PostgreSQL\10\data
目錄下的pg_hba.conf
文件:
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
...
...
新增一行IPv4的連接地址:*** host all all 0.0.0.0/0 md5
***
# IPv4 local connections:
host all all 127.0.0.1/32 md5
host all all 0.0.0.0/0 md5
# IPv6 local connections:
host all all ::1/128 md5
...
...
完成之後可使用本地IP進行連接測試。
運行postgis-bundle-pg10x64-setup-3.0.1-1.exe
,勾選創建postgis_30_sample
等待安裝,有彈窗提示,偷懶的可以一路yes就可以了。
如果出現錯誤應該是Postgre SQL
版本與PostGis Bundle
版本不對應,或者安裝包下載出錯。
完成之後,連接數據庫,選擇默認數據庫postgres
新建查詢:
CREATE EXTENSION postgis;
CREATE EXTENSION postgis
> OK
> 時間: 2.156s
- 第一步:關閉
PostgreSQL 10
服務
右鍵我的電腦 > 管理 > 服務和應用程序 > 服務 > postgresql-x64-10
> 屬性 > 停止
- 第二步:配置環境變量
Path
右鍵我的電腦 > 屬性 > 高級系統設置 > 環境變量 > Path
> 編輯 > 新建
添加兩行數據(根據個人安裝路徑):
\PostgreSQL\10\bin
\PostgreSQL\10\lib
- 第三步:解壓
timescaledb-postgresql-10_1.7.0-windows-amd64.zip
,安裝
打開解壓文件timescaledb
,右鍵setup.exe
以管理員身份運行:
2020/05/14 17:11:06 WELCOME to TimescaleDB Windows installer!
2020/05/14 17:11:06 timescaledb-tune is a program that modifies your postgresql.conf configuration to be optimized for your machine's resources.
Do you want to run timescaledb-tune.exe now? [(y)es / (n)o]: y
Please enter the path to your postgresql.conf:
這裏把自己的postgresql.conf
的路徑複製上去,如:D:\PostgreSQL\10\data\postgresql.conf
剩下的一路yes即可。
- 第四步:驗證安裝
完成之後,首先開啓postgresql-x64-10
服務
連接數據庫,選擇默認數據庫postgres
新建查詢:
CREATE EXTENSION timescaledb;
CREATE EXTENSION timescaledb;
> 警告:
WELCOME TO
_____ _ _ ____________
|_ _(_) | | | _ \ ___ \
| | _ _ __ ___ ___ ___ ___ __ _| | ___| | | | |_/ /
| | | | _ ` _ \ / _ \/ __|/ __/ _` | |/ _ \ | | | ___ \
| | | | | | | | | __/\__ \ (_| (_| | | __/ |/ /| |_/ /
|_| |_|_| |_| |_|\___||___/\___\__,_|_|\___|___/ \____/
Running version 1.7.0
For more information on TimescaleDB, please visit the following links:
1. Getting started: https://docs.timescale.com/getting-started
2. API reference documentation: https://docs.timescale.com/api
3. How TimescaleDB is designed: https://docs.timescale.com/introduction/architecture
Note: TimescaleDB collects anonymous reports to better understand and assist our users.
For more information and how to disable, please see our docs https://docs.timescaledb.com/using-timescaledb/telemetry.
> 時間: 0.528s
也可參考網上教程 Windows安裝TimescaleDB
這裏建議官方的案例【How to explore TimescaleDB using simulated IoT sensor data】
地址:https://blog.timescale.com/tutorials/how-to-explore-timescaledb-using-simulated-iot-sensor-data/
e-timescaledb-using-simulated-iot-sensor-data/)】
地址:https://blog.timescale.com/tutorials/how-to-explore-timescaledb-using-simulated-iot-sensor-data/
也可以參考我整理過的文檔timescaledb_official_simple.sql
- timescaledb_official_simple.sql
-- 創建一個 timescaledb的測試庫便於進行官方案例實驗
CREATE DATABASE "time_scale_db";
-- 創建timescaledb擴展:
-- 1、第一種方式:
-- CREATE EXTENSION IF NOT EXISTS "timescaledb" CASCADE;
-- 2、第二種方式:
CREATE EXTENSION "timescaledb";
-- 官方測試 案例 https://blog.timescale.com/tutorials/how-to-explore-timescaledb-using-simulated-iot-sensor-data/
-- The Internet of Things (IoT) describes a trend where computing is becoming ubiquitous
-- and is embedded in more and more physical things. For many of these things, the purpose
-- of IoT is to collect sensor data about the environment in which it exists: e.g., oil wells,
-- factories, power plants, farms, moving vehicles, office buildings, homes.
-- 物聯網(Internet of Things,IoT)描述了一種趨勢,即計算變得無處不在,並嵌入到越來越多的物理事物中。
-- 對於其中許多方面,物聯網的目的是收集有關其存在環境的傳感器數據:例如油井、工廠、發電廠、農場、移動車輛、辦公樓、住宅
-- In other words, IoT is all about the data. And the datasets generated by these things are
-- generally time-series in nature, with relational metadata to describe those things.
-- 換句話說,物聯網就是數據。而由這些事物生成的數據集本質上是時間序列,用關係元數據來描述這些事物。
-- In this tutorial we explore some of the features and capabilities of TimescaleDB using an IoT
-- sensor dataset that is meant to simulate a real-world IoT deployment.
-- 在本教程中,我們將探索TimescaleDB的一些特性和功能,它使用一個IoT傳感器數據集來模擬真實的IoT部署。
------ Step 1: Set up your tables
------ 第一節 建立數據表及初始化傳感器數據
-- Second, create the “sensors” and “sensor_data” tables:
-- 第一步:創建 sensors 傳感器信息表
DROP TABLE IF EXISTS "public"."sensors";
CREATE TABLE "public"."sensors"(
"id" SERIAL PRIMARY KEY,
"type" VARCHAR(50),
"location" VARCHAR(50)
);
-- 第二步:創建 sensors sensor_data 傳感器數據表
DROP TABLE IF EXISTS "public"."sensor_data";
CREATE TABLE "public"."sensor_data" (
"time" TIMESTAMPTZ NOT NULL,
"sensor_id" INTEGER,
"temperature" DOUBLE PRECISION,
"cpu" DOUBLE PRECISION,
FOREIGN KEY ("sensor_id") REFERENCES "public"."sensors"("id")
);
-- Third, convert the sensor_data table into a hypertable:
-- 第三步:創建 轉換 sensor_data爲超表
SELECT create_hypertable('sensor_data', 'time');
-- Fourth, populate the sensors table with 4 sensors:
-- 第四步:插入到 sensors 4組傳感器信息數據
INSERT INTO "public"."sensors" ("id","type", "location") VALUES
(1,'a','floor'),
(2,'a', 'ceiling'),
(3,'b','floor'),
(4,'b', 'ceiling');
-- Fifth, verify that the sensors were created correctly:
-- 第五步:查詢確認當前的傳感器信息數據
SELECT * FROM "public"."sensors";
-- id | type | location
-- ----+------+----------
-- 1 | a | floor
-- 2 | a | ceiling
-- 3 | b | floor
-- 4 | b | ceiling
-- (4 rows)
------ Step 2: Create simulated IoT sensor data
------ 第二節 創建模擬物聯網傳感器數據
-- Note: for the following sections we’ll share the results of our queries as an example,
-- but since the tutorials generates random data every time it is run, your results will look different
-- (but will be structured the same way).
-- 注意:對於下面的部分,我們將以共享查詢結果爲例,但是由於教程每次運行時都會生成隨機數據,
-- 因此您的結果看起來會有所不同(但結構將相同)。
-- First, generate a dataset of simulated data for one sensor, recording data every 5 minutes for the past 24 hours:
-- 首先,爲一個傳感器生成一個模擬數據集,在過去24小時內每5分鐘記錄一次數據:
-- 第一步 生成模擬數據
SELECT
generate_series(now() - interval '24 hour', now(), interval '5 minute') AS "time",
random() AS "cpu",
random()*100 AS "temperature";
-- Note: Your data will look different but should have the same structure.
-- 提示:實際數據可能會有所不同,僅供參考
-- time | cpu | temperature
-- -------------------------------+----------------------+-------------------
-- 2019-07-31 15:55:31.744218+00 | 0.0306301130913198 | 75.7227655500174
-- 2019-07-31 16:00:31.744218+00 | 0.626729523297399 | 20.1422684360296
-- 2019-07-31 16:05:31.744218+00 | 0.526347786653787 | 87.2947076335549
-- 2019-07-31 16:10:31.744218+00 | 0.169700589030981 | 21.1996510624886
-- 2019-07-31 16:15:31.744218+00 | 0.71232553711161 | 91.3718110416085
-- Second, generate a similar dataset for each of our four sensors and insert into our sensor_data table:
-- 第二步:爲我們的四個傳感器中的每一個生成一個相似的數據集並插入到我們的傳感器數據表中
-- 【建議分步執行】
-- 爲id爲1傳感器插入數據
WITH "simulated_data"
AS
(SELECT
1 as sensor_id, generate_series(now() - interval '24 hour', now(), interval '5 minute') AS "time",
random() AS "cpu",
random()*100 AS "temperature"
)
INSERT INTO "public"."sensor_data" ("time", "sensor_id", "cpu", "temperature")
SELECT "time","sensor_id", "cpu", "temperature" FROM "simulated_data";
-- 爲id爲2傳感器插入數據
WITH "simulated_data"
AS
(SELECT
2 as sensor_id, generate_series(now() - interval '24 hour', now(), interval '5 minute') AS "time",
random() AS "cpu",
random()*100 AS "temperature"
)
INSERT INTO "public"."sensor_data" ("time", "sensor_id", "cpu", "temperature")
SELECT "time","sensor_id", "cpu", "temperature" FROM "simulated_data";
-- 爲id爲3傳感器插入數據
WITH "simulated_data"
AS
(SELECT
3 as sensor_id, generate_series(now() - interval '24 hour', now(), interval '5 minute') AS "time",
random() AS "cpu",
random()*100 AS "temperature"
)
INSERT INTO "public"."sensor_data" ("time", "sensor_id", "cpu", "temperature")
SELECT "time","sensor_id", "cpu", "temperature" FROM "simulated_data";
-- 爲id爲4傳感器插入數據
WITH "simulated_data"
AS
(SELECT
4 as sensor_id, generate_series(now() - interval '24 hour', now(), interval '5 minute') AS "time",
random() AS "cpu",
random()*100 AS "temperature"
)
INSERT INTO "public"."sensor_data" ("time", "sensor_id", "cpu", "temperature")
SELECT "time","sensor_id", "cpu", "temperature" FROM "simulated_data";
-- Third, verify that the simulated sensor_data was written correctly:
-- 第三步:查詢確認數據
SELECT * FROM "public"."sensor_data" ORDER BY "time";
-- time | sensor_id | temperature | cpu
-- -------------------------------+-----------+--------------------+---------------------
-- 2019-07-31 15:56:25.843575+00 | 1 | 6.86688972637057 | 0.682070567272604
-- 2019-07-31 15:56:40.244287+00 | 2 | 26.589260622859 | 0.229583469685167
-- 2019-07-31 15:56:45.653115+00 | 3 | 79.9925176426768 | 0.457779890391976
-- 2019-07-31 15:56:53.560205+00 | 4 | 24.3201029952615 | 0.641885648947209
-- 2019-07-31 16:01:25.843575+00 | 1 | 33.3203678019345 | 0.0159163917414844
-- 2019-07-31 16:01:40.244287+00 | 2 | 31.2673618085682 | 0.701185956597328
-- 2019-07-31 16:01:45.653115+00 | 3 | 85.2960689924657 | 0.693413889966905
-- 2019-07-31 16:01:53.560205+00 | 4 | 79.4769988860935 | 0.360561791341752
-- …
------ Step 3: Run basic queries
------ 第三節:運行基本查詢
-- Let’s start by calculating the average temperature and cpu by 30 minute window:
-- 第一步:讓我們從計算平均溫度和cpu的30分鐘窗口開始
SELECT
time_bucket('30 minutes', "time") AS "period",
AVG("temperature") AS "avg_temp",
AVG("cpu") AS "avg_cpu"
FROM "public"."sensor_data"
GROUP BY "period";
-- period | avg_temp | avg_cpu
-- ------------------------+------------------+-------------------
-- 2019-07-31 19:00:00+00 | 49.6615830013373 | 0.477344429974134
-- 2019-07-31 22:00:00+00 | 58.8521540844037 | 0.503637770501276
-- 2019-07-31 16:00:00+00 | 50.4250325243144 | 0.511075591299838
-- 2019-07-31 17:30:00+00 | 49.0742547437549 | 0.527267253802468
-- 2019-08-01 14:30:00+00 | 49.3416377226822 | 0.438027751864865
-- But what if we don’t just want the average temperature for each period, but also the last temperature?
-- (For example if we wanted to understand the final temperature value at the end of the interval.)
-- 第二步:但如果我們不只是想要每個時期的平均溫度,還要最後一個溫度呢?
-- (例如,如果我們想了解間隔結束時的最終溫度值。)
SELECT
time_bucket('30 minutes', "time")AS "period",
AVG("temperature")AS "avg_temp",
last("temperature", "time") AS "last_temp",
AVG("cpu") AS "avg_cpu"
FROM "public"."sensor_data"
GROUP BY "period";
-- period | avg_temp | last_temp | avg_cpu
-- ------------------------+------------------+------------------+-------------------
-- 2019-07-31 19:00:00+00 | 49.6615830013373 | 84.3963081017137 | 0.477344429974134
-- 2019-07-31 22:00:00+00 | 58.8521540844037 | 76.5528806950897 | 0.503637770501276
-- 2019-07-31 16:00:00+00 | 50.4250325243144 | 43.5192013625056 | 0.511075591299838
-- 2019-07-31 17:30:00+00 | 49.0742547437549 | 22.740753274411 | 0.527267253802468
-- 2019-08-01 14:30:00+00 | 49.3416377226822 | 59.1331578791142 | 0.438027751864865
-- …
-- Now let’s take advantage of some of the metadata we have stored in the sensors table:
-- 現在,讓我們利用存儲在sensors表中的一些元數據:
-- 第三步:Join查詢詳細數據
SELECT
"public"."sensors"."location",
time_bucket('30 minutes', "time")AS "period",
AVG("temperature")AS "avg_temp",
last("temperature", "time") AS "last_temp",
AVG("cpu") AS "avg_cpu"
FROM "public"."sensor_data" JOIN "public"."sensors" on "public"."sensor_data"."sensor_id" = "public"."sensors"."id"
GROUP BY "period", "public"."sensors"."location";
-- location | period | avg_temp | last_temp | avg_cpu
-- ----------+------------------------+------------------+-------------------+-------------------
-- ceiling | 2019-07-31 15:30:00+00 | 25.4546818090603 | 24.3201029952615 | 0.435734559316188
-- floor | 2019-07-31 15:30:00+00 | 43.4297036845237 | 79.9925176426768 | 0.56992522883229
-- ceiling | 2019-07-31 16:00:00+00 | 53.8454438598516 | 43.5192013625056 | 0.490728285357666
-- floor | 2019-07-31 16:00:00+00 | 47.0046211887772 | 23.0230117216706 | 0.53142289724201
-- ceiling | 2019-07-31 16:30:00+00 | 58.7817596504465 | 63.6621567420661 | 0.488188337767497
-- floor | 2019-07-31 16:30:00+00 | 44.611586847653 | 2.21919436007738 | 0.434762630766879
-- ceiling | 2019-07-31 17:00:00+00 | 35.7026890735142 | 42.9420990403742 | 0.550129583687522
-- floor | 2019-07-31 17:00:00+00 | 62.2794370166957 | 52.6636955793947 | 0.454323202022351
-- …
------ Step 4: Set up a continuous aggregate view
------ 第四節:創建連續聚合視圖
-- Our queries have gotten a little unwieldy. If we find ourselves running them often, we can save ourselves time
-- (user time and query time) by saving them as a continuous aggregate view:
-- 我們的查詢有點麻煩。如果我們發現自己經常運行它們,我們可以通過將它們保存爲連續聚合視圖來節省時間(用戶時間和查詢時間):
-- 第一步創建聚合視圖
CREATE VIEW "public"."sensor_data_30min"
WITH (timescaledb.continuous)
AS
SELECT
time_bucket('30 minutes', "time")AS "period",
AVG("temperature")AS "avg_temp",
last("temperature", "time") AS "last_temp",
AVG("cpu") AS "avg_cpu"
FROM "public"."sensor_data"
GROUP BY "period";
-- We can see the results by automatically querying the continuous aggregate view:
-- 我們可以通過自動查詢連續聚合視圖來查看結果:
-- 第二步 通過聚合視圖查詢數據
SELECT * FROM "public"."sensor_data_30min";
-- period | avg_temp | last_temp | avg_cpu
-- ------------------------+------------------+------------------+-------------------
-- 2019-07-31 15:30:00+00 | 34.442192746792 | 24.3201029952615 | 0.502829894074239
-- 2019-07-31 16:00:00+00 | 50.4250325243144 | 43.5192013625056 | 0.511075591299838
-- 2019-07-31 16:30:00+00 | 51.6966732490497 | 63.6621567420661 | 0.461475484267188
-- 2019-07-31 17:00:00+00 | 48.991063045105 | 42.9420990403742 | 0.502226392854936
-- 2019-07-31 17:30:00+00 | 49.0742547437549 | 22.740753274411 | 0.527267253802468
-- ...
-- What a continuous aggregate view does is recompute the query automatically at regular time intervals
-- (which the user can specify) and materialize the results into a table. When we query the view, TimescaleDB
-- reads and processes the much smaller materialized table instead of the raw data. This speeds up the query
-- significantly (and is also much easier for us to type!).
-- 連續聚合視圖的作用是按固定的時間間隔(用戶可以指定)自動重新計算查詢,並將結果具體化到表中。當我們查詢視圖時,
-- TimescaleDB讀取並處理更小的物化表,而不是原始數據。這大大加快了查詢的速度(而且對我們來說也更容易鍵入!)
-- To peek further behind the scenes:
-- 要深入瞭解幕後情況:
SELECT * FROM timescaledb_information.continuous_aggregate_stats;
-- view_name | completed_threshold | invalidation_threshold | job_id | last_run_started_at | job_status | last_run_duration | next_scheduled_run
-- -------------------+------------------------+------------------------+--------+------------------------------+------------+-------------------+-------------------------------
-- sensor_data_30min | 2019-08-01 14:30:00+00 | 2019-08-01 14:30:00+00 | 1000 | 2019-08-01 15:59:32.46657+00 | scheduled | 00:00:00.006064 | 2019-08-01 16:59:32.472634+00
--