全部产品
存储与CDN 数据库 安全 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 钉钉智能硬件
流计算

创建维表

更新时间:2017-12-29 15:19:52

流计算使用DIM TABLE定义维表数据。维表数据是一类特殊的外部数据,它相对流数据来说比较稳定且变化缓慢,是静态或准静态数据,作为JOIN/LEFT OUTER JOIN的右表使用。特别注意的是,维表在流计算中不允许作为FROM后的数据存储,流计算中对于FROM子句后对接的数据存储一定是流式数据存储,即 SELECT * FROM DIM_TABLE 是不被允许的

  1. CREATE DIM TABLE table_name
  2. [(col_name data_type, ...[, PRIMARY KEY(col_name, ...)])]
  3. [WITH (property_name=other_property_value,...)];
  4. data_type
  5. : primitive_type
  6. primitive_type
  7. : INT
  8. | BIGINT
  9. | DOUBLE
  10. | STRING

特别注意的是:

维表关联

  • 流计算对于维表处理原理可以形象的理解为,对于每条流式进入的数据,流计算向外部的维表存储请求进行关联查询,例如每条进入流式数据,流计算使用该条数据向外部RDS进行SELECT查询请求,看是否在RDS数据库中有该行数据。因此,维表在流计算中不允许作为FROM后的数据存储,流计算中对于FROM子句后对接的数据存储一定是流式数据存储,即 SELECT * FROM DIM_TABLE 是不被允许的,必须使用 SELECT * FROM STREAM_TABLE JOIN DIM_TABLE ON STREAM_TABLE.key = DIM_TABLE.key

  • 参考上述流计算维表运行原理,因此对于关联查询的条件必须是维表的主键。例如一张TableStore(原OTS)维表,用户在手写JOIN条件时候,必须使用TableStore主键进行关联查询。即在CREATE DIM TABLE 中指定PRIMARY KEY是TableStore主键,同时要求JOIN后面的条件必须也是TableStore的主键

  • 流计算要求JOIN条件必须是DDL中声明维表的主键,但是对于DDL中维表的主键在部分存储要求是主键,在其他某些存储不要求是主键,关键取决于底层存储是否支持非主键查询。其实明白了上述流计算关联维表查询原理就能够容易明白其原因。例如,对于TableStore外部维表主键必须要求是TableStore主键,原因在于当流计算需要从TableStore查询数据时候,TableStore仅支持主键查询。对于RDS/Mysql而言,由于SQL数据库不要求一定主键查询,因此此时的DDL声明主键不一定是Mysql主键。但,考虑到SQL数据库非主键查询(更严格来说是非索引查询)可能导致查询很慢,进而拖累流计算运行效率。

维表通用配置

在实际生产业务中,维表数据可能存在大量的关联查询操作,因此流计算对于维表设置了部分通用配置,以方便用户针对维表进行细节调优操作:

Cache类

为优化查询性能,避免每次流数据Join操作均从实际维表数据存储查询数据,所有的维表操作在流计算内部实际上均支持使用内存Cache进行缓存,配置如下:

  • cacheType

    cache的类型,目前支持三种类型,包括:

    • LRU,使用LRU算法进行过期数据替换,流计算默认使用该选项。

    • ALL,所有维表数据将直接加载到流计算每个计算节点内。注意,如果数据太大,可能造成OOM情况。

    • NONE,关闭cache,每次Join操作流计算将直接查询维表数据存储。

    默认值为LRU类型

  • cacheTTL

    指定cache的Time-To-Live时间,即数据过期时间,单位为毫秒。一旦数据在cache存在时间大于cacheTTL,数据将从维表数据存储重新加载。注意的是:这里的cacheTTL是针对整个Cache的失效时间,而非单个数据失效时间。

    默认值为不失效,数据缓存不命中新数据进入Cache并替换掉老数据

  • cacheSize

    指定cache的大小,单位为记录数。注意,该值设置过大,或者每条记录过大,可能造成计算进程OOM。

    默认值为10000,单位为记录数

Cache通用参数示例如下:

  1. CREATE DIM TABLE user (
  2. id STRING,
  3. name STRING,
  4. age STRING,
  5. PRIMARY KEY (id)
  6. ) WITH (
  7. type='ots',
  8. cacheType='LRU', -- 使用LRU方式
  9. cacheTTL='600000', -- TTL设置为10分钟
  10. cacheSize='10000' -- cache的记录条数为10000
  11. );

示例一

我们定义了一个RDS的维表,然后进行关联查询,用于扩展流中的数据:

  1. create dim table dim_rds
  2. (
  3. id STRING,
  4. name STRING
  5. primary key(id)
  6. ) with (
  7. type = 'rds',
  8. url = 'jdbc:mysql://xxxxxxx.rds.aliyuncs.com:3306/galaxy_test',
  9. username = 'xxx',
  10. password = 'xxx',
  11. tableName = 'galaxy_rds_mysql_test',
  12. cacheTTL = '120000',
  13. cacheType = 'LRU',
  14. );
  15. SELECT
  16. s.id,
  17. d.name
  18. FROM
  19. source_datahub s
  20. JOIN
  21. dim_rds d
  22. ON
  23. s.id = d.id

实例二

以下给出一个错误实例,用户将维表当做普通表进行查询是不允许的:

  1. create dim table dim_rds
  2. (
  3. id STRING,
  4. name STRING
  5. primary key(id)
  6. ) with (
  7. type = 'rds',
  8. url = 'jdbc:mysql://xxxxxxx.rds.aliyuncs.com:3306/galaxy_test',
  9. username = 'xxx',
  10. password = 'xxx',
  11. tableName = 'galaxy_rds_mysql_test',
  12. cacheTTL = '120000',
  13. cacheType = 'LRU',
  14. );
  15. --以下为错误的语法!
  16. SELECT
  17. s.id,
  18. d.name
  19. FROM
  20. source_datahub s
  21. JOIN
  22. SELECT
  23. *
  24. FROM
  25. dim_rds
  26. WHERE
  27. name like '%taobao%'
  28. ON
  29. s.id = d.id

上述语法是错误的!流计算对于维表处理模式是对进入的每条流式数据,关联查询维表中的数据,因此流计算无法对维表进行直接的SELECT操作,请使用示例一的语法表达。

本文导读目录