dbt-tidb 1.2.0 尝鲜

article/2025/9/2 20:48:22

作者: shiyuhang0 原文来源: https://tidb.net/blog/1f56ab48

本文假设你对 dbt 有一定了解。如果是第一次接触 dbt,建议先阅读 官方文档 或 当 TiDB 遇见 dbt

本文中的示例基于官方维护的 jaffle_shop 项目。关于此项目的细节介绍,可以参考 当 TiDB 遇见 dbt 或 github project page ,本文不再赘述

TiDB Cloud 官方在5月份开始正式面向全球用户提供全托管的 DBaaS (Database-as-a-Service)服务,支持用户在全托管的数据库上运行关键业务交易和实时分析任务。

同时 TiDB Cloud 还提供了免费试用的 dev tier,可以方便开发者试用、调试。搭配 dev tier,dbt-tidb 易用性大大提高。

恰逢 dbt-tidb v1.2.0 发布,除了支持 dbt-core v1.2.0 之外,它还带来了一些好用的新特性。借此机会,本文将体验 dev tier 并测试 dbt-tidb v1.2.0 的新特性。

对于开发者们,本文还介绍了如何升级 dbt-tidb,可供参考。

Setup

  1. 安装 dbt-tidb v1.2.0
$ pip install dbt-tidb=1.2.0 
  1. 在 TiDB Cloud 上创建免费的 dev tier,如遇问题可以参考 官方文档 。

    1. 注册并登录账号,页面会跳转到 TiDB Cloud 控制台。

    2. 点击 Create Cluster,跳转到创建页面,创建参数一般默认即可。

    3. 点击右下角 Create,跳转到 Security Settings,配置 Root Password 与 IP Access List。(点选 Allow Access from Anywhere 可以允许任意 IP 地址的访问)

    4. 点击右下角 Apply,页面跳转回 TiDB Cloud 控制台,等待集群初始化完成。

    5. 初始化完毕后点击 Connect 按钮,即可查看相应 host 与 user 了。可以直接复制 MySQL 连接串以测试集群连通性。

  1. 下载 jaffle_shop 项目
git clone https://github.com/dbt-labs/jaffle_shop
  1. ~/.dbt 路径下配置 profiles.yml 中的连接信息
jaffle_shop_tidb:                        # 工程名称target: dev                             outputs:dev:type: tidb                         # 适配器类型server: gateway01.ap-southeast-1.prod.aws.tidbcloud.com # 修改为你的 TiDB 地址port: 4000                         # 修改为你的 TiDB 端口号schema: test                       # 数据库名称username: 41y7Jq2g5sBr2ia.root     # 修改为你的 TiDB 用户名password: ${fake_password}         # 修改为你的 TiDB 密码
  1. 修改 jaffle_shop 中的 dbt_project.yml,只需修改 profile 为 profiles.yml 中定义的工程名
profile: 'jaffle_shop_tidb'
  1. 在 jaffle_shop 目录下执行dbt debug 即可验证配置是否正确
dbt debug

Feature

Connection Retry

在 dbt 中,运行/构建/测试可能会有数百个独立的数据库连接。由于网络等原因导致的单个超时有可能使整个项目运行失败。

因此 dbt-tidb 新增了重试功能来解决暂时性的连接超时问题。

Connection Retry 举例🌰

  1. 在 profile.yml 添加重试次数的配置,同时使用无效用户模拟连接失败的场景
jaffle_shop_tidb:                        # 工程名称target: dev                             outputs:dev:type: tidb                         # 适配器类型server: gateway01.ap-southeast-1.prod.aws.tidbcloud.com # 修改为你的 TiDB 地址port: 4000                         # 修改为你的 TiDB 端口号schema: test                       # 数据库名称username: 41y7Jq2g5sBr2ia.invaild_user           password: ${fake_password}         # 修改为你的 TiDB 密码                retries: 3   # 重试次数
  1. 执行 dbt debug,终端的确显示了相应错误。但想知道是否进行了重试,需要查看 debug 日志
$ dbt debug
Connection:server: gateway01.ap-southeast-1.prod.aws.tidbcloud.comport: 4000database: Noneschema: testuser: 41y7Jq2g5sBr2ia.invaild_userConnection test: [ERROR]1 check failed:
dbt was unable to connect to the specified database.
The database returned the following error:>Database Error1045 (28000): Access denied for user '41y7Jq2g5sBr2ia.invaild_user'@'10.0.123.88' (using password: YES)
  1. 去 logs 目录下查看 dbt.log,可以发现重试了3次,每次间隔1秒。最后抛出错误
$ cat dbt.log
06:24:19.875482 [debug] [MainThread]: tidb adapter: Got a retryable error when attempting to open a tidb connection.
3 attempts remaining. Retrying in 1 seconds.
Error:
1045 (28000): Access denied for user '41y7Jq2g5sBr2ia.invaild_user'@'10.0.123.88' (using password: YES)
06:24:21.321733 [debug] [MainThread]: tidb adapter: Got a retryable error when attempting to open a tidb connection.
2 attempts remaining. Retrying in 1 seconds.
Error:
1045 (28000): Access denied for user '41y7Jq2g5sBr2ia.invaild_user'@'10.0.123.88' (using password: YES)
06:24:22.703960 [debug] [MainThread]: tidb adapter: Got a retryable error when attempting to open a tidb connection.
1 attempts remaining. Retrying in 1 seconds.
Error:
1045 (28000): Access denied for user '41y7Jq2g5sBr2ia.invaild_user'@'10.0.123.88' (using password: YES)
06:24:24.069883 [debug] [MainThread]: tidb adapter: Error running SQL: select 1 as id

Grant

在 ELT 之后,我们往往需要对数据进行权限控制。基于此,dbt 从 1.2.0 开始支持 Grant 对 dbt 生成的数据集进行访问控制。相应的 dbt-tidb 也支持了授权机制,能够对 dbt 产生的视图与表进行授权管理。

Gant 目前支持 model, seed 和 snapshots。如果你在 dbt_project.yml 下配置,那么项目内所有资源(model/seed/snapshots 都是资源)都会生效。当然,你也可以像其他配置项一样针对特定资源配置相应的 SQL 或 YAML,它会覆盖 dbt_project.yml 中的配置。

有一点需要注意的是 Grant 不支持创建用户,我们需要在 TiDB 中先创建好所需用户。

Grant 举例🌰

  1. 在 TiDB 中创建用户,注意在 dev tier 中用户名必须带前缀(和 root 用户的前缀保持一致)
CREATE USER '41y7Jq2g5sBr2ia.user1'@'%' IDENTIFIED BY '';
CREATE USER '41y7Jq2g5sBr2ia.user2'@'%' IDENTIFIED BY '';
CREATE USER '41y7Jq2g5sBr2ia.user3'@'%' IDENTIFIED BY '';
  1. 在 jaffle_shop 项目中的 dbt_project.yml 增加 grant 配置
seeds:+grants:select: ['41y7Jq2g5sBr2ia.user1','41y7Jq2g5sBr2ia.user2']insert: ['41y7Jq2g5sBr2ia.user1','41y7Jq2g5sBr2ia.user3']
  1. 在 jaffle_shop 项目下执行 dbt seed
$ dbt seed
06:38:49  Concurrency: 1 threads (target='dev')
06:38:49
06:38:49  1 of 3 START seed file test.raw_customers ...................................... [RUN]
06:38:50  1 of 3 OK loaded seed file test.raw_customers .................................. [INSERT 100 in 1.58s]
06:38:50  2 of 3 START seed file test.raw_orders ......................................... [RUN]
06:38:52  2 of 3 OK loaded seed file test.raw_orders ..................................... [INSERT 99 in 1.52s]
06:38:52  3 of 3 START seed file test.raw_payments ....................................... [RUN]
06:38:54  3 of 3 OK loaded seed file test.raw_payments ................................... [INSERT 113 in 1.66s]
06:38:55
06:38:55  Finished running 3 seeds in 0 hours 0 minutes and 9.09 seconds (9.09s).
06:38:55
06:38:55  Completed successfully
06:38:55
06:38:55  Done. PASS=3 WARN=0 ERROR=0 SKIP=0 TOTAL=3
  1. 成功后查询 TiDB:
  • 41y7Jq2g5sBr2ia.user1 被赋予了 Select + Insert 权限

<!---->

  • 41y7Jq2g5sBr2ia.user2 被赋予了Select 权限

<!---->

  • 41y7Jq2g5sBr2ia.user3 被赋予了 Insert 权限
mysql> select * from mysql.tables_priv where User in('41y7Jq2g5sBr2ia.user1','41y7Jq2g5sBr2ia.user2','41y7Jq2g5sBr2ia.user3');
+------+------+-----------------------+---------------+---------+---------------------+---------------+---------------+
| Host | DB   | User                  | Table_name    | Grantor | Timestamp           | Table_priv    | Column_priv   |
+------+------+-----------------------+---------------+---------+---------------------+---------------+---------------+
| %    | test | 41y7Jq2g5sBr2ia.user1 | raw_customers |         | 2022-08-19 06:46:08 | Select,Insert | Select,Insert |
| %    | test | 41y7Jq2g5sBr2ia.user2 | raw_customers |         | 2022-08-19 06:46:08 | Select        | Select        |
| %    | test | 41y7Jq2g5sBr2ia.user3 | raw_customers |         | 2022-08-19 06:46:08 | Insert        | Insert        |
| %    | test | 41y7Jq2g5sBr2ia.user1 | raw_orders    |         | 2022-08-19 06:46:10 | Select,Insert | Select,Insert |
| %    | test | 41y7Jq2g5sBr2ia.user2 | raw_orders    |         | 2022-08-19 06:46:10 | Select        | Select        |
| %    | test | 41y7Jq2g5sBr2ia.user3 | raw_orders    |         | 2022-08-19 06:46:10 | Insert        | Insert        |
| %    | test | 41y7Jq2g5sBr2ia.user1 | raw_payments  |         | 2022-08-19 06:46:12 | Select,Insert | Select,Insert |
| %    | test | 41y7Jq2g5sBr2ia.user2 | raw_payments  |         | 2022-08-19 06:46:12 | Select        | Select        |
| %    | test | 41y7Jq2g5sBr2ia.user3 | raw_payments  |         | 2022-08-19 06:46:12 | Insert        | Insert        |
+------+------+-----------------------+---------------+---------+---------------------+---------------+---------------+

Cross-database macros

dbt 的一个强大之处就是它可以复用宏(可以理解为函数), dbt-util 就是官方提供的一个工具仓库,我们可以通过引入 dbt-util 复用其封装好的宏。dbt 1.2.0 将其中的 Cross-database macros 从 util 迁移到了 core,这意味着你无需引入 dbt-util 就可以直接使用它们。

对此,dbt-tidb 也做了相应适配工作。现在,你可以直接在 dbt-tidb 中使用下列函数,使用方式可以参考 dbt-tidb 官网 。

  • bool_or

<!---->

  • cast_bool_to_text

<!---->

  • dateadd

<!---->

  • datediff

<!---->

  • date_trunc

<!---->

  • hash

<!---->

  • safe_cast

<!---->

  • split_part

<!---->

  • last_day

<!---->

  • cast_bool_to_text

<!---->

  • concat

<!---->

  • escape_single_quotes

<!---->

  • except

<!---->

  • intersect

<!---->

  • length

<!---->

  • position

<!---->

  • replace

<!---->

  • right

以 datediff 举例🌰

  1. 执行 dbt seed 生成 raw_orders 表
dbt seed
  1. 在 models 目录下创建 datediff.sql,计算 raw_orders 表中订单时间和 2018-01-01 相差的天数
with orders as (select * from {{ ref('raw_orders') }})select * , {{datediff( "'2018-01-01'", "order_date", 'day' )}} as datediff from orders
  1. 执行 dbt run -s datediff 指定运行 datediff,执行成功后查询 TiDB 结果如下
mysql> select * from test.datediff;
+------+---------+------------+----------------+----------+
| id   | user_id | order_date | status         | datediff |
+------+---------+------------+----------------+----------+
|    1 |       1 | 2018-01-01 | returned       |        0 |
|    2 |       3 | 2018-01-02 | completed      |        1 |
|    3 |      94 | 2018-01-04 | completed      |        3 |
|    4 |      50 | 2018-01-05 | completed      |        4 |
|    5 |      64 | 2018-01-05 | completed      |        4 |
|    6 |      54 | 2018-01-07 | completed      |        6 |
|    7 |      88 | 2018-01-09 | completed      |        8 |
|    8 |       2 | 2018-01-11 | returned       |       10 |
|    9 |      53 | 2018-01-12 | completed      |       11 |
|   10 |       7 | 2018-01-14 | completed      |       13 |
|   11 |      99 | 2018-01-14 | completed      |       13 |
|   12 |      59 | 2018-01-15 | completed      |       14 |
|   13 |      84 | 2018-01-17 | completed      |       16 |
|   14 |      40 | 2018-01-17 | returned       |       16 |
|   15 |      25 | 2018-01-17 | completed      |       16 |
|   16 |      39 | 2018-01-18 | completed      |       17 |
|   17 |      71 | 2018-01-18 | completed      |       17 |
|   18 |      64 | 2018-01-20 | returned       |       19 |
|   19 |      54 | 2018-01-22 | completed      |       21 |
|   20 |      20 | 2018-01-23 | completed      |       22 |

Upgrade dbt-tidb to support new dbt-core

上文介绍了 dbt-tidb v1.2.0 带来的诸多新特性。那么新特性是如何实现的,dbt-tidb 又是如何进行版本升级的呢?下文将会给你带来答案。

关于构建 dbt adapter 的细节可以参考 dbt 官方文档 ,本节则会带来版本升级的相关经验。

版本规则

dbt-tidb 版本与 dbt-core(官方维护的内核)一样遵循 Semantic Versioning 。

为了避免兼容性问题,dbt-tidb 选择与 dbt-core 保持一致版本,同版本间才能相互兼容工作。即 dbt-tidb 1.2.0 也仅支持 dbt-core 1.2.0。虽然官方升级时会尽量避免兼容性修改,但兼容性修改还是会发生的。如 dbt-core 1.2.0 为了支持 retry connection 特性新增了可覆盖的方法,如果 adapter 实现了该方法,那么也就无法运行在 dbt-core 1.1.0 之上了(除非代码进行版本判断,嵌入两种逻辑)

基于此,在 dbt-core 发布 1.1.0 与 1.2.0 之后,dbt-tidb 也需要分别发布 1.1.0 与 1.2.0 版本。

调研

当我们进行版本升级,第一步就是要调研需要支持哪些特性。

以下几种调研的途径,你可以结合使用多种方式

  1. 查看 dbt-core 的 release note,重点关注针对 adapter 的新特性。最终梳理需要实现的新特性。

<!---->

  1. 有时候,dbt 官方会在 Github Discussion 中整理 adapter 升级需要支持的特性。这时候,你就可以放心大胆依据它来升级。

<!---->

  1. 官方的 版本升级文档

<!---->

  1. 参考其他 adapter 的实现,你可以在 Available adapters 找到所有的 adapter

<!---->

  1. 不推荐的选择:不实现特性,而只修改打包时 dbt-core 的版本。此时无法享受任何版本升级带来的新特性。

dbt-tidb 主要依据第一、二种方式,整理出需要实现的特性如下表:

dbt-tidb 1.1.0

  • 废弃Python 3.7,支持 Python 3.10

<!---->

  • 使用新的测试框架进行测试

<!---->

  • 在 incremental 中支持多 unique key

dbt-tidb 1.2.0

  • 支持 Connection retry 特性

<!---->

  • 支持 grant 特性,进行权限配置

<!---->

  • 支持 Cross-database macros (dbt-util 包下的部分 macros 被迁移至 dbt-core)

<!---->

  • 新增 BaseDocsGenerate 与 BaseValidateConnection 测试

使用测试

在开发前,我想先介绍如何进行测试。因为我建议使用 Test Driven Development(TTD) 的方式进行开发 dbt adapter。即:先编写测试,然后进行对应功能实现,通过测试即认为支持该功能。

自 dbt-core 1.1.0 开始,dbt 就为 adapter 开发者提供了全新的一套测试框架。DBT 正在大力推广新测试框架,相比于旧的测试框架,该新框架的一个好处就是它随着 dbt-core 一起发版。这样就能及时对相应特性或 BUG 修复进行测试。

得益于该测试框架,adapter 基本无需自己编写测试就可以对相应功能进行测试。关于测试框架如何使用,可以参考 Testing a new adapter 。

dbt-tidb 1.1.0 开始使用新的测试框架,引入 basic 包,以测试基础的 dbt 功能,另外 incremental 多 unique key 的支持暂时也放在了 basic 包下

dbt-tidb 1.2.0 又根据新增特性补充了以下测试

  • Basic 包:新增 BaseValidateConnection 与 BaseDocsGenerate ,分别用于测试连接与文档生成相关功能

<!---->

  • Grant :新增 grant 包,用于测试 grant 特性

<!---->

  • Util :新增 util 包,用于测试从 dbt-util 迁移来的 Cross-database macros

如何开发

我们以 grant 特性为例介绍如何进行新特性支持。

添加测试

在上一步中我们已经介绍过如何测试。对于 grant,我们需要增加如下测试:

class TestModelGrantsTiDB(BaseModelGrants):passclass TestIncrementalGrantsTiDB(BaseIncrementalGrants):passclass TestSeedGrantsTiDB(BaseSeedGrants):passclass TestSnapshotGrantsTiDB(BaseSnapshotGrants):passclass TestInvalidGrantsTiDB(BaseInvalidGrants):pass

其中我们直接使用 pass 不进行任何实现修改,只继承测试框架的默认实现。

实现特性

接下来就是实现特性。一般可以通过覆盖默认宏或是覆盖默认方法来进行拓展,具体应该覆盖哪些,可以参考如下:

  • dbt 官方人员可能会在 Github discussions 中介绍如何实现

<!---->

  • 参考 dbt-core 该特性相应 pr

<!---->

  • 参考其他 adapter

通过官方仓库 discussion 中整理的 1.2.0 升级汇总 。我们发现 grant 主要通过覆盖 dbt-core 的宏实现,主要需要实现如下宏:

  • get_show_grant_sql:返回授权信息(通过查看相关代码,可以发现返回格式需为 grantee (用户名) + privilege_type(权限类型))

<!---->

  • get_grant_sql:进行授权

<!---->

  • get_revoke_sql:收回授权

以下是相关实现:

get_show_grant_sql

我们首先查询 TiDB 的 mysql.tables_priv 表获取权限信息。然后筛选出对应的库表,接着轮询 Select、Insert、Update、Delete 四种权限,最后按用户+权限的格式输出。对应 SQL 如下

{% macro tidb__get_show_grant_sql(relation) %}select case(Table_priv) when null then null else 'select' end as privilege_type, `User` as grantee from mysql.tables_priv  where `DB` = '{{relation.schema}}' and `Table_name` = '{{relation.identifier}}' and Table_priv like '%Select%'union ALLselect case(Table_priv) when null then null else 'insert' end as privilege_type, `User` as grantee from mysql.tables_priv  where `DB` = '{{relation.schema}}' and `Table_name` = '{{relation.identifier}}' and Table_priv like '%Insert%'union ALLselect case(Table_priv) when null then null else 'update' end as privilege_type, `User` as grantee from mysql.tables_priv  where `DB` = '{{relation.schema}}' and `Table_name` = '{{relation.identifier}}' and Table_priv like '%Update%'union ALLselect case(Table_priv) when null then null else 'delete' end as privilege_type, `User` as grantee from mysql.tables_priv  where `DB` = '{{relation.schema}}' and `Table_name` = '{{relation.identifier}}' and Table_priv like '%Delete%'{% endmacro %}

get_grant_sql

使用标准 grant SQL 对多用户进行授权,注意用户需使用双引号。对应 SQL 如下:

{%- macro tidb__get_grant_sql(relation, privilege, grantees) -%}grant {{ privilege }} on {{ relation }} to {{ '\"' + grantees|join('\", \"') + '\"' }}
{%- endmacro -%}

get_revoke_sql

使用标准 revoke SQL 对多用户收回授权,用户同样需使用双引号。对应 SQL 如下:

 {%- macro tidb__get_revoke_sql(relation, privilege, grantees) -%}revoke {{ privilege }} on {{ relation }} from {{ '\"' + grantees|join('\", \"') + '\"' }}
{%- endmacro -%}

修复错误

实现完成之后,我们需要运行测试检查是否能够通过。当发现并没有通过时,我们一般有以下方式去修复错误:

  1. 根据错误输出,判断错误原因进行修复,一般的 SQL 格式错误都可以用这种方式发现。

<!---->

  1. 查看 dbt-core 中该特性对应的 pr。

    1. 查看是否修改了一些已被 adapter 覆盖的宏/方法,如果是,那么 adapter 可能也需要相应修改。
    2. 查看是否还有新增的其他可被覆盖的宏/方法。

<!---->

  1. 参考其他 adapter 支持的代码。查看是否有任何遗漏

在支持 grant 的过程中,就基于第二种方法发现 dbt-tidb 之前已经覆盖了 incremental 与 snapshot 宏。而在 grant 特性支持 pr 中,dbt-core 修改了这两个宏的默认实现。dbt-tidb 也需要进行相应修改:

{% materialization incremental, adapter='tidb' %}-- other code{% set grant_config = config.get('grants') %}-- other code{% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}{% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}-- other code{%- endmaterialization %}

该代码首先获取 grant 配置,然后调用 apply_grants 应用上文实现的 get_grant_sql 方法。

同时,也发现需要覆盖新增的call_dcl_statements 宏,来将多条 SQL 变为单条 SQL 依次请求。因为 dbt-tidb 暂时还不支持多 SQL 请求,如下:

{% macro tidb__call_dcl_statements(dcl_statement_list) %}{% for dcl_statement in dcl_statement_list %}{% call statement('grant_or_revoke') %}{{ dcl_statement }}{% endcall %}{% endfor %}
{% endmacro %}

修复测试

测试中可能还会发现一些错误,这些错误并不是因为我们没有实现该特性,而是因为一些兼容性问题,测试本身需要一些修改。关于如何修改测试, Testing a new adapter 中也有介绍

dbt-tidb 支持授权时就进行了测试修改。因为在授权失败时,不同的 adapter 可能会抛出不一样的错误,那么自然需要改写授权失败的信息,使其符合 TiDB 的报错:

class TestInvalidGrantsTiDB(BaseInvalidGrants):def grantee_does_not_exist_error(self):return "You are not allowed to create a user with GRANT"def privilege_does_not_exist_error(self):return "Illegal privilege level specified for"

Conclusion

本文结合 dev tier 与 dbt-tidb 举例试用了 dbt-tidb v1.2.0 带来的主要特性。

同时以 dbt-tidb 为例,介绍了升级 dbt adapter 的流程与技巧。也欢迎大家对 dbt-tidb 任何形式的贡献。


http://chatgpt.dhexx.cn/article/rvA9BCCx.shtml

相关文章

为啥用 时序数据库 TSDB

前言 其实我之前是不太了解时序数据库以及它相关的机制的&#xff0c;只是大概知晓它的用途。但因为公司的业务需求&#xff0c;我意外参与并主导了公司内部开源时序数据库influxdb的引擎改造&#xff0c;所以我也就顺理成章的成为时序数据库“从业者”。 造飞机的人需要时刻…

Prometheus 学习之——本地存储 TSDB

Prometheus 学习之——本地存储 TSDB 文章目录 Prometheus 学习之——本地存储 TSDB前言一、TSDB 核心概念二、详细介绍1.block1&#xff09;chunks2&#xff09;index3&#xff09;tombstone4&#xff09;meta.json 2.WAL 总结 前言 Prometheus 是 CNCF 收录的第二个项目&…

阿里云IoT物模型上报数据流转到实例内TSDB

阿里云物联网平台上存储的数据最多为30天&#xff0c;为了能让数据永久保存下来&#xff0c;就需要把物联网平台的数据流转到其他的数据库&#xff0c;对于企业版实例&#xff0c;内部有一个实例内的时空数据库TSDB&#xff0c;正好可以利用。下边就介绍一下物联网平台的物模型…

使用TSDB自动检测时序数据的异常情况

本期Jesse就带大家来继续了解一下TSDB的应用问题&#xff0c;小伙伴们&#xff0c;让我们直接步入正题吧。 本文仅代表个人观点&#xff0c;如有偏颇之处&#xff0c;还请海涵&#xff5e; 现今&#xff0c;每天都有数千亿个传感器产生大量时序数据。公司收集大量数据使得分析…

TSDB 存储引擎介绍

本文介绍 DolphinDB 在2.0版本中新推出的存储引擎 TSDB。 1. OLAP 与 TSDB 适用的场景 OLAP 是 DolphinDB 在2.0版本之前的唯一存储引擎。数据表中每个分区的每一列存为一个文件。数据在表中的存储顺序与数据写入的顺序一致&#xff0c;数据写入有非常高的效率。 OLAP 引擎的…

TSDB与Blockchain

各位小伙伴们我们又见面了&#xff0c;伴随着区块链技术的推广&#xff0c;很多企业也在思考是否将其应用。其实TSDB与区块链有很多共通之处&#xff0c;本期Jesse就来和大家聊聊TSDB与区块链。本文参考了Nicolas Hourcard的文章“You Don’t Need a Blockchain, You Need a Ti…

FlashDB嵌入式数据库之TSDB数据存储解析

一、驱动层&#xff1a;SFUD&#xff08;Serial Flash Universal Driver&#xff09; 是一款开源的串行 SPI Flash 通用驱动库 二、中间层&#xff1a;FAL&#xff08;FLASH ABSTRACTION LAYER)&#xff09;FLASH 抽象层 三、应用层&#xff1a;FlashDB&#xff08;FlashDB 是一…

时间序列数据库 (TSDB)

参考文档&#xff1a;时间序列数据库 TSDB_时间序列数据库 TSDB-阿里云帮助中心 什么是时序数据库 时序数据是随时间不断产生的一系列数据&#xff0c;简单来说&#xff0c;就是带时间戳的数据。数据可能来自服务器和应用程序的指标、物联网传感器的读数、网站或应用程序上的…

TSDB在高速公路大数据平台的应用

好久没有跟大家聊TSDB的应用场景了&#xff0c;Jesse也在国庆期间进行了补课&#xff0c;今天就跟大家聊聊TSDB在高速公路大数据平台的应用。本文借鉴了郝建明、袁逸涛发表在《上海船舶运输科学研究生学报》的《基于时序数据库的高速公路数据集成平台》一文&#xff0c;感谢二位…

时序数据库(TSDB)

时序数据库&#xff08;TSDB&#xff09;是一种特定类型的数据库&#xff0c;主要用来存储时序数据。随着5G技术的不断成熟&#xff0c;物联网技术将会使得万物互联。物联网时代之前只有手机、电脑可以联网&#xff0c;以后所有设备都会联网&#xff0c;这些设备每时每刻都会吐…

TSDB数据库

目录 为什么需要时序数据库&#xff1a; 时间序列数据库的特点&#xff1a; 常见的时间序列数据库&#xff1a; 时间序列数据库存储&#xff1a; 时间序列数据库问题&#xff1a; 参考资料&#xff1a; 内容是在我球的docs上直接复制过来的&#xff0c;懒得写两份&#x…

关于时许数据库的相关名词解释

1 时序数据库TSDB 英文全称为 Time Series Database&#xff0c;提供高效存取时序数据和统计分析功能的数据管理系统。 2 时序数据&#xff08;Time Series Data&#xff09; 基于稳定频率持续产生的一系列指标监测数据。例如&#xff0c;监测某城市的空气质量时&#xff0c…

物联网平台搭建的全过程介绍(六)——物联网TSDB之基本知识及读写代码介绍

目录 一、TSDB基本知识 二、物联网平台数据流通架构 三、TSDB数据结构 1、TSDB数据包的组成 2、TSDB的另外两个相关概念 四、阿里云物联网平台实例内TSDB功能介绍 1、数据写入 &#xff08;1&#xff09;需要添加的依赖 &#xff08;2&#xff09;写入数据代码 2、数据…

ES6—简介

目录 一、概述 二、扩展&#xff1a;Babel转码器 三、拓展&#xff1a;编译打包 一、概述 概念 ES6全称ECMAScript 6.0&#xff0c;是Javascript语言的下一代标准&#xff0c;2015年6月正式发布。 注意&#xff0c;ES6既是一个历史名词&#xff0c;也是一个泛指&#xff0c;…

深入浅出ES6(一):ES6是什么

深入浅出ES6&#xff08;一&#xff09;&#xff1a;ES6是什么 作者 Jason Orendorff &#xff0c;译者 刘振涛 发布于 2015年6月5日 | http://www.infoq.com/cn/articles/es6-in-depth-an-introduction 我的阅读清单 编者按&#xff1a;ECMAScript 6离我们越来越近了&#…

[ 前端开发 ] 为什么要学习ES6?

ECMAScript 6 概念 ECMAScript 6 简称 ES6 为什么要学习ES6? ES6 是 JavaScript 的下一个版本标准&#xff0c;诞生于2015年6月份。ES6 的主要目的是为了解决 ES5 的先天不足。ES6 的终极目标是为了使 JavaScript 语言可以用来编写复杂的大型应用程序&#xff0c;成为企业…

前端基础之ES6

ES6 ES6简介 ES6实际上是一个泛指&#xff0c;泛指ES2015及后续版本 为什么使用ES6&#xff1f; 每一次标准的诞生都意味着语言的完善&#xff0c;功能的加强。JavaScript语言本身也有一些令人不满意的地方。 变量提升特性增加了程序运行时的不可预测性语法过于松散&#x…

第一节:ES是什么?ES6是什么?

系列文章目录 第一节&#xff1a;ES是什么&#xff1f;ES6是什么&#xff1f; 文章目录 系列文章目录前言一、ES是什么&#xff1f;二、ES6是什么&#xff1f; 前言 学习一下ES&#xff0c;都是自己学习的总结和理解&#xff0c;大家有什么问题都可以提出&#xff0c;一起讨论…

1.什么是ES6,为什么使用它

1.什么是ES6&#xff1f; ECMAScript 6&#xff08;以下简称ES6&#xff09;是JavaScript语言的下一代标准&#xff0c;已经在2015年6月正式发布了。Mozilla公司将在这个标准的基础上&#xff0c;推出JavaScript 2.0。ES6主要是为了解决ES5的先天不足&#xff0c;比如JavaScri…

ES6是什么

ES6是什么 ECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已经在 2015 年 6 月正式发布了。 它的目标&#xff0c;是使得 JavaScript 语言可以用来编写复杂的大型应用程序&#xff0c;成为企业级开发语言。 现在大部分的编…