涛思数据TDengine now插值问题记录

27 篇文章 6 订阅

TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传递的 PRECISION 参数就可以支持微秒和纳秒。(从 2.1.5.0 版本开始支持纳秒精度)。在使用过程中如果没有特殊要求一般采用默认值。

TDengine内部函数 now 是客户端的当前时间,插入记录时,如果时间戳为 now,插入数据时使用提交这条记录的客户端的当前时间。在使用“插入多条记录”方式写入数据时,不能把第一列的时间戳取值都设为 NOW,否则会导致语句中的多条记录使用相同的时间戳,于是就可能出现相互覆盖以致这些数据行无法全部被正确保存。其原因在于,NOW 函数在执行中会被解析为所在 SQL 语句的实际执行时间,出现在同一语句中的多个 NOW 标记也就会被替换为完全相同的时间戳取值。

 --资料来源:文档 - 涛思数据 | TDengine

   TDengine是单个数据一张表,可以通过超级表管理。在底层逻辑上,还是仅有子表名和ts时戳1个主键。Iot数据在同一时刻数据也仅会变化一次,正常使用是没有问题。

    但最近在使用TDengine记录日志时,就遇到一个场景,我对Iot来的报文进行日志记录,每个设备一张表,以服务端处理时间做ts主键。后来根据计数器核对数据时发现数据丢失严重,忽然想起之前看过的涛思官网上看到的上述资料,知道了原因所在。找对症处理起来就很容易了。

     这个服务采用JAVA编写,先定义一个锁用于支持并发,定义一个变量记录上次的时间,时间单位是ms。在写入时不使用now直接插入,而是采用时间值。如果当前时间与上次的相同或小,就使用上次时间+1.。

import java.time.Instant;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

    private static Lock lock = new ReentrantLock();
    private long lastStatTs = 0;

。。。
    //处理高并发下的ts重复问题
    long insMilli = Instant.now().toEpochMilli();
    lock.lock();
    if ( lastStatTs < insMilli )
    {
       lastStatTs = insMilli;
    }else {
       lastStatTs ++;
    }
    //示例Sql,插入使用lastStatTs
    INSERT INTO d1001 VALUES (lastStatTs, 10.2, 219, 0.32);    

   使用上面的方法,可以解决数据有高并发,但数据密度有限的情况。

   如果涉及超级表和Iot数据保存,建议在数据源带时戳,设计好数据模型,避免在服务端处理数据时戳造成的数据重复问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您需要记录复杂接口操作数据所产生的数据变化,建议使用以下方法: 1. 在数据库中创建一个触发器,用于记录数据变化。触发器可以在数据修改前或修改后执行,以便记录修改前后的数据。 2. 在接口中,使用一个类似于拦截器的方式,在数据修改前或修改后,通过 JDBC 执行触发器。可以使用 Spring AOP 或者自己手动实现一个类似于拦截器的方法。 3. 在触发器中,记录修改前后的数据。可以使用存储过程或者动态的 SQL 语句,根据修改前后的数据记录相关信息。 4. 在接口中,可以使用日志记录记录相关修改操作的信息。可以记录修改前后的数据、操作人员、时间等信息。 下面是一个简单的示例代码,用于记录数据变化: ```java public class DataChangeInterceptor { @Autowired private JdbcTemplate jdbcTemplate; public void before(Method method, Object[] args, Object target) { // 记录修改前的数据 // ... } public void after(Method method, Object[] args, Object target, Object returnValue) { // 记录修改后的数据 // ... // 执行触发器 jdbcTemplate.execute("CALL data_change_trigger()"); } } ``` 在触发器中,可以使用类似于下面的 SQL 语句记录数据变化: ```sql CREATE TRIGGER data_change_trigger AFTER UPDATE ON table_name FOR EACH ROW BEGIN INSERT INTO data_change_log (table_name, column_name, old_value, new_value, change_time, operator) VALUES ('table_name', 'column_name', OLD.column_name, NEW.column_name, NOW(), 'operator_name'); END; ``` 这样,就可以记录复杂接口操作数据所产生的数据变化了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值