一、安装环境
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
--