Timescale 代码快速入门指南旨在帮助您将 Timescale 集成到您自己的程序中。它们使用您最喜欢的编程语言来解释如何连接到 Timescale 数据库,创建和管理超表,以及摄取和查询数据。

本快速入门指南将引导您完成

在开始之前,请确保您已拥有

本快速入门中的所有代码均适用于 Java 16 及更高版本。如果您使用的是旧版本的 JDK,请使用旧的编码技术。

在本节中,您将使用单个文件中的应用程序创建与 TimescaleDB 的连接。您可以使用任何您喜欢的构建工具,包括 gradlemaven

  1. 创建一个目录,其中包含一个名为 Main.java 的文本文件,内容如下

    package com.timescale.java;
    public class Main {
    public static void main(String... args) {
    System.out.println("Hello, World!");
    }
    }
  2. 从当前目录的命令行中,运行应用程序

    java Main.java

    如果命令成功,Hello, World! 行输出将打印到您的控制台。

  3. 导入 PostgreSQL JDBC 驱动程序。如果您使用的是依赖管理器,请包含 PostgreSQL JDBC 驱动程序 作为依赖项。

  4. 下载 JDBC 驱动程序的 JAR 文件 并将其与 Main.java 文件一起保存。

  5. 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);
    }
    }
  6. 运行所有示例

    java -cp *.jar Main.java

如果命令成功,则会向您的控制台打印类似于 org.postgresql.Driver@7f77e91b 的字符串。这意味着您已准备好从 Java 连接到 TimescaleDB。

  1. 找到您的 TimescaleDB 凭据,并使用它们来编写 JDBC 的连接字符串。

    您将需要

    • 密码
    • 用户名
    • 主机 URL
    • 端口
    • 数据库名称
  2. 使用以下格式编写您的连接字符串变量

    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());
    }
    }
  3. 运行代码

    java -cp *.jar Main.java

    如果命令成功,则会向您的控制台打印类似于 {ApplicationName=PostgreSQL JDBC Driver} 的字符串。

在本节中,您将创建一个名为 sensors 的表,其中保存了虚构传感器的 ID、类型和位置。此外,您还将创建一个名为 sensor_data 的超表,其中保存这些传感器的测量值。测量值包含时间、sensor_id、温度读数和传感器的 CPU 百分比。

  1. 编写一个字符串,其中包含用于创建关系表的 SQL 语句。此示例创建一个名为 sensors 的表,其中包含 idtypelocation

    CREATE TABLE sensors (
    id SERIAL PRIMARY KEY,
    type TEXT NOT NULL,
    location TEXT NOT NULL
    );
  2. 创建一个语句,执行您在上一步中创建的查询,并检查表是否已成功创建

    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"));
    }
    }
    }
    }

创建关系表后,您可以创建超表。表和索引的创建、表的更改、数据的插入、数据的选择以及大多数其他任务都在超表上执行。

  1. 为您的超表创建一个 CREATE TABLE SQL 语句。请注意超表如何具有强制性的时间列

    CREATE TABLE sensor_data (
    time TIMESTAMPTZ NOT NULL,
    sensor_id INTEGER REFERENCES sensors (id),
    value DOUBLE PRECISION
    );
  2. 创建一个语句,执行您在上一步中创建的查询

    SELECT create_hypertable('sensor_data', by_range('time'));
    注意

    by_rangeby_hash 维度构建器是 TimescaleDB 2.13 的新增功能。

  3. 执行您创建的两个语句,并将您的更改提交到数据库

    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'))");
    }
    }
    }

您可以通过几种不同的方式将数据插入到您的超表中。在本节中,您可以插入单行,也可以批量插入多行。

  1. 打开与数据库的连接,使用预处理语句来制定 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 超表中

本节介绍如何对您的数据库执行查询。

  1. 定义您想要在数据库上运行的 SQL 查询。此示例结合了时序数据和关系数据。它返回每 15 分钟间隔内具有特定类型和位置的传感器的平均值。

    SELECT time_bucket('15 minutes', time) AS bucket, avg(value)
    FROM sensor_data
    JOIN sensors ON sensors.id = sensor_data.sensor_id
    WHERE sensors.type = ? AND sensors.location = ?
    GROUP BY bucket
    ORDER BY bucket DESC;
  2. 使用预处理语句执行查询,并读取所有位于 floor 上的 a 类型传感器的结果集

    try (var stmt = conn.prepareStatement("""
    SELECT time_bucket('15 minutes', time) AS bucket, avg(value)
    FROM sensor_data
    JOIN sensors ON sensors.id = sensor_data.sensor_id
    WHERE sensors.type = ? AND sensors.location = ?
    GROUP BY bucket
    ORDER 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,508649
    2021-05-12 23:15:00.0: 0,477852
    2021-05-12 23:00:00.0: 0,462298
    2021-05-12 22:45:00.0: 0,457006
    2021-05-12 22:30:00.0: 0,568744
    ...

现在您已经能够从您的 Java 应用程序连接、读取和写入 TimescaleDB 实例,并生成从现有 TimescaleDB 实例构建新应用程序所需的脚手架,请务必查看这些高级 TimescaleDB 教程

本节包含完整的代码示例。

关键词

在此页面上发现问题?报告问题 或 在 GitHub 上编辑此页