Timescale 代码快速入门指南旨在帮助您将 Timescale 集成到您自己的程序中。它们使用您最喜欢的编程语言来解释如何连接到 Timescale 数据库,创建和管理超表,以及摄取和查询数据。
本快速入门指南将引导您完成
在开始之前,请确保您已拥有
- 安装了 TimescaleDB。有关更多信息,请参阅安装文档。
- 安装了 Java 开发工具包 (JDK)。
- 安装了 PostgreSQL JDBC 驱动程序。
本快速入门中的所有代码均适用于 Java 16 及更高版本。如果您使用的是旧版本的 JDK,请使用旧的编码技术。
在本节中,您将使用单个文件中的应用程序创建与 TimescaleDB 的连接。您可以使用任何您喜欢的构建工具,包括 gradle
或 maven
。
创建一个目录,其中包含一个名为
Main.java
的文本文件,内容如下package com.timescale.java;public class Main {public static void main(String... args) {System.out.println("Hello, World!");}}从当前目录的命令行中,运行应用程序
java Main.java如果命令成功,
Hello, World!
行输出将打印到您的控制台。导入 PostgreSQL JDBC 驱动程序。如果您使用的是依赖管理器,请包含 PostgreSQL JDBC 驱动程序 作为依赖项。
下载 JDBC 驱动程序的 JAR 文件 并将其与
Main.java
文件一起保存。将
JDBC 驱动程序
导入 Java 应用程序,并显示可用驱动程序列表以进行检查package com.timescale.java;import java.sql.DriverManager;public class Main {public static void main(String... args) {DriverManager.drivers().forEach(System.out::println);}}运行所有示例
java -cp *.jar Main.java
如果命令成功,则会向您的控制台打印类似于 org.postgresql.Driver@7f77e91b
的字符串。这意味着您已准备好从 Java 连接到 TimescaleDB。
找到您的 TimescaleDB 凭据,并使用它们来编写 JDBC 的连接字符串。
您将需要
- 密码
- 用户名
- 主机 URL
- 端口
- 数据库名称
使用以下格式编写您的连接字符串变量
var connUrl = "jdbc:postgresql://<HOSTNAME>:<PORT>/<DATABASE_NAME>?user=<USERNAME>&password=<PASSWORD>";有关创建连接字符串的更多信息,请参阅 JDBC 文档。
警告
这种编写连接字符串的方法仅用于测试或开发目的。对于生产环境,请对密码、主机名和端口号等敏感详细信息使用环境变量。
package com.timescale.java;import java.sql.DriverManager;import java.sql.SQLException;public class Main {public static void main(String... args) throws SQLException {var connUrl = "jdbc:postgresql://<HOSTNAME>:<PORT>/<DATABASE_NAME>?user=<USERNAME>&password=<PASSWORD>";var conn = DriverManager.getConnection(connUrl);System.out.println(conn.getClientInfo());}}运行代码
java -cp *.jar Main.java如果命令成功,则会向您的控制台打印类似于
{ApplicationName=PostgreSQL JDBC Driver}
的字符串。
在本节中,您将创建一个名为 sensors
的表,其中保存了虚构传感器的 ID、类型和位置。此外,您还将创建一个名为 sensor_data
的超表,其中保存这些传感器的测量值。测量值包含时间、sensor_id、温度读数和传感器的 CPU 百分比。
编写一个字符串,其中包含用于创建关系表的 SQL 语句。此示例创建一个名为
sensors
的表,其中包含id
、type
和location
列CREATE TABLE sensors (id SERIAL PRIMARY KEY,type TEXT NOT NULL,location TEXT NOT NULL);创建一个语句,执行您在上一步中创建的查询,并检查表是否已成功创建
package com.timescale.java;import java.sql.DriverManager;import java.sql.SQLException;public class Main {public static void main(String... args) throws SQLException {var connUrl = "jdbc:postgresql://<HOSTNAME>:<PORT>/<DATABASE_NAME>?user=<USERNAME>&password=<PASSWORD>";var conn = DriverManager.getConnection(connUrl);var createSensorTableQuery = """CREATE TABLE sensors (id SERIAL PRIMARY KEY,type TEXT NOT NULL,location TEXT NOT NULL)""";try (var stmt = conn.createStatement()) {stmt.execute(createSensorTableQuery);}var showAllTablesQuery = "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'public'";try (var stmt = conn.createStatement();var rs = stmt.executeQuery(showAllTablesQuery)) {System.out.println("Tables in the current database: ");while (rs.next()) {System.out.println(rs.getString("tablename"));}}}}
创建关系表后,您可以创建超表。表和索引的创建、表的更改、数据的插入、数据的选择以及大多数其他任务都在超表上执行。
为您的超表创建一个
CREATE TABLE
SQL 语句。请注意超表如何具有强制性的时间列CREATE TABLE sensor_data (time TIMESTAMPTZ NOT NULL,sensor_id INTEGER REFERENCES sensors (id),value DOUBLE PRECISION);创建一个语句,执行您在上一步中创建的查询
SELECT create_hypertable('sensor_data', by_range('time'));注意
by_range
和by_hash
维度构建器是 TimescaleDB 2.13 的新增功能。执行您创建的两个语句,并将您的更改提交到数据库
package com.timescale.java;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.List;public class Main {public static void main(String... args) {final var connUrl = "jdbc:postgresql://<HOSTNAME>:<PORT>/<DATABASE_NAME>?user=<USERNAME>&password=<PASSWORD>";try (var conn = DriverManager.getConnection(connUrl)) {createSchema(conn);insertData(conn);} catch (SQLException ex) {System.err.println(ex.getMessage());}}private static void createSchema(final Connection conn) throws SQLException {try (var stmt = conn.createStatement()) {stmt.execute("""CREATE TABLE sensors (id SERIAL PRIMARY KEY,type TEXT NOT NULL,location TEXT NOT NULL)""");}try (var stmt = conn.createStatement()) {stmt.execute("""CREATE TABLE sensor_data (time TIMESTAMPTZ NOT NULL,sensor_id INTEGER REFERENCES sensors (id),value DOUBLE PRECISION)""");}try (var stmt = conn.createStatement()) {stmt.execute("SELECT create_hypertable('sensor_data', by_range('time'))");}}}
您可以通过几种不同的方式将数据插入到您的超表中。在本节中,您可以插入单行,也可以批量插入多行。
打开与数据库的连接,使用预处理语句来制定
INSERT
SQL 语句,然后执行该语句final List<Sensor> sensors = List.of(new Sensor("temperature", "bedroom"),new Sensor("temperature", "living room"),new Sensor("temperature", "outside"),new Sensor("humidity", "kitchen"),new Sensor("humidity", "outside"));for (final var sensor : sensors) {try (var stmt = conn.prepareStatement("INSERT INTO sensors (type, location) VALUES (?, ?)")) {stmt.setString(1, sensor.type());stmt.setString(2, sensor.location());stmt.executeUpdate();}}
如果您想使用批处理机制插入一批行。在本示例中,您生成一些示例时序数据以插入到 sensor_data
超表中
本节介绍如何对您的数据库执行查询。
定义您想要在数据库上运行的 SQL 查询。此示例结合了时序数据和关系数据。它返回每 15 分钟间隔内具有特定类型和位置的传感器的平均值。
SELECT time_bucket('15 minutes', time) AS bucket, avg(value)FROM sensor_dataJOIN sensors ON sensors.id = sensor_data.sensor_idWHERE sensors.type = ? AND sensors.location = ?GROUP BY bucketORDER BY bucket DESC;使用预处理语句执行查询,并读取所有位于
floor
上的a
类型传感器的结果集try (var stmt = conn.prepareStatement("""SELECT time_bucket('15 minutes', time) AS bucket, avg(value)FROM sensor_dataJOIN sensors ON sensors.id = sensor_data.sensor_idWHERE sensors.type = ? AND sensors.location = ?GROUP BY bucketORDER BY bucket DESC""")) {stmt.setString(1, "temperature");stmt.setString(2, "living room");try (var rs = stmt.executeQuery()) {while (rs.next()) {System.out.printf("%s: %f%n", rs.getTimestamp(1), rs.getDouble(2));}}}如果命令成功,您将看到如下输出
2021-05-12 23:30:00.0: 0,5086492021-05-12 23:15:00.0: 0,4778522021-05-12 23:00:00.0: 0,4622982021-05-12 22:45:00.0: 0,4570062021-05-12 22:30:00.0: 0,568744...
现在您已经能够从您的 Java 应用程序连接、读取和写入 TimescaleDB 实例,并生成从现有 TimescaleDB 实例构建新应用程序所需的脚手架,请务必查看这些高级 TimescaleDB 教程
本节包含完整的代码示例。
关键词
在此页面上发现问题?报告问题 或 在 GitHub 上编辑此页。