You need to enable JavaScript to run this app.
导航
Power BI (MySQL)
最近更新时间:2025.08.20 10:42:59首次发布时间:2024.12.25 17:16:42
复制全文
我的收藏
有用
有用
无用
无用

Power BI 是微软开发的一款功能强大的商业智能工具。 它使用户能够可视化和分析数据,以做出明智的业务决策。 用户可以创建交互式和可定制的仪表板、报告和可视化。

背景信息

ByteHouse 支持通过 IAM 用户或数据库用户连接 Power BI。IAM 用户与数据库用户二者差异说明如下,您可按需选择。

  • IAM 用户为火山引擎访问控制(IAM)中创建的用户,其权限由 IAM 权限策略及您授予的 ByteHouse 资源和数据权限决定。IAM 用户可访问 ByteHouse 控制台,也支持通过 CLI、连接驱动、生态工具、API 等方式访问 ByteHouse。
  • 数据库用户为 ByteHouse 中创建的数据库级别用户,可为其授予环境、资源和数据权限。数据库用户不可访问 ByteHouse 控制台,但支持通过 CLI、连接驱动、生态工具、API 等方式访问 ByteHouse。

更多 IAM 用户和数据库用户的介绍请参见以下文档:

前提条件

  1. 操作系统与环境要求:
    1. 仅支持 64 位 (x64) 平台的 Windows 11,Windows 10, Windows Server 2012 R2, Windows Server 2012, Windows 8, Windows 8.1, Windows Server 2016, Windows Server 2019;
    2. 系统使用 Internet Explorer 10 或更高版本。
  2. 安装 Power BI Gateway。请参考官方文档安装。
  3. 拥有 ByteHouse 账号。

配置与使用

  1. 进入Power BI 后,访问 Get data -> more -> 搜索 MySQL,即可查看 MySQL database 的数据源。

  2. 填写 ByteHouse 的相关连接信息。

    1. Server:配置为 ByteHouse 的网络域名,您可以在 ByteHouse 控制台的 租户管理 > 基本信息 > 网络信息中查看对应信息。详情请参见步骤二:配置网络信息
    2. Database :填写连接的数据库名称
  3. 填写 ByteHouse 的认证信息。

    参数

    使用 IAM 用户连接

    使用数据库用户连接

    UserName

    建议新建 API Key 创建连接,可以在 ByteHouse 控制台 > 租户管理 > 连接信息中获取的 API Key,详情请参考获取 API Key,设置 API Key。
    UserName 配置为 API Key 的前半部分。例如:如果API Key是1111111:222222,则 UserName 是1111111

    UserName 由 {accountID_or_accountName}::{username}[::{envID}] 构成,获取详情请参考步骤三:获取 ByteHouse 连接串信息

    • accountID_or_accountName:指火山引擎用户账号 ID 或名称,可登录 ByteHouse 控制台,单击右上角个人中心查看并复制账号ID 或名称。
    • username:登录 ByteHouse 数据库账号用户名。可在 ByteHouse 控制台 > 权限管理 > 用户 > 查看数据库用户名
    • {envID}:可选配置,数据库所在的环境名称。如果使用 default 环境,可不配置;如需使用其他环境,需指定环境名称,配置时无需添加[]。您可登录 ByteHouse 控制台,在租户管理 > 基本信息 > 当前环境中获取。
      使用示例如下:
      • 配置环境 ID:21xxxxxxxx::demouser::demoenv
      • 不配置环境 ID:21xxxxxxxx::demouser

    Password

    Password 配置为 API Key 的后半部分。例如:如果API Key是1111111:222222,则 Password 是222222

    数据库账号的密码由管理员创建数据库账号时自定义配置,您可联系管理员获取密码。如果密码丢失或遗忘,可通联系管理员重置密码,详情请参考重置密码

  4. 连接成功后,加载对应的数据库表。

测试数据集 Demo

DDL

CREATE database IF NOT EXISTS hamster_odbc;
DROP table IF EXISTS hamster_odbc.all_types;
CREATE table IF NOT EXISTS hamster_odbc.all_types (
    c1 Int8,
    c2 Int16,
    c3 Int32,
    c4 Int64,
    c5 Float32,
    c6 Float64,
    c7 String,
    c8 Nullable(String),
    c9 Date,
    c10 DateTime,
    c11 UUID,
    c12 Array(Int8),
    c13 Enum8('v1'=1, 'v2'=2),
    c14 Enum16('v3'=1, 'v4'=2),
    c15 Decimal(2, 2),
    c16 FixedString(2),
    c17 Tuple(s String, i Int64),
    c18 Map(String, String)
) ENGINE = CnchMergeTree ORDER BY c1;

INSERT INTO hamster_odbc.all_types
(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,
--c17,
c18)
VALUES (
    127,
    32767,
    2147483647,
    9223372036854775807,
    100000.1,
    14000000000.1,
    'OK',
    NULL,
    '2022-12-30',
    '2022-12-30 13:44:17',
    417ddc5d-e556-4d27-95dd-a34d84e46a50,
    [1,2,3,4],
    'v1',
    'v3',
    4.20,
    'b\0',
--    ('a', 1),
    {'key1': 'value1', 'key2': 'value2'}
), (
    100,
    3200,
    2147483647,
    9223372036854775807,
    100000.1,
    14000000000.1,
    'OK',
    NULL,
    '2022-12-31',
    '2022-12-30 13:44:17',
    417ddc5d-e556-4d27-95dd-a34d84e46a50,
    [1,2,3,4],
    'v1',
    'v3',
    4.20,
    'b\0',
--    ('a', 1),
    {'key1': 'value1', 'key2': 'value2'}
), (
    100,
    3200,
    2147483647,
    9223372036854775807,
    100000.1,
    14000000000.1,
    'OK',
    NULL,
    '2022-12-29',
    '2022-12-30 13:44:17',
    417ddc5d-e556-4d27-95dd-a34d84e46a50,
    [1,2,3,4],
    'v1',
    'v3',
    4.20,
    'b\0',
--    ('a', 1),
    {'key1': 'value1', 'key2': 'value2'}
);
DROP TABLE IF EXISTS hamster_odbc.range_key_dictionary_source_table;
CREATE TABLE IF NOT EXISTS hamster_odbc.range_key_dictionary_source_table ( `key` UInt64, `value` String, `value_nullable` Nullable(String) ) ENGINE=CnchMergeTree() PRIMARY KEY tuple() ORDER BY tuple();
INSERT INTO hamster_odbc.`range_key_dictionary_source_table` VALUES (1, 'OK', NULL), (2, 'OK', 'OK');
DROP DICTIONARY IF EXISTS hamster_odbc.range_key_dictionary;
CREATE DICTIONARY hamster_odbc.range_key_dictionary (
  `key` UInt64,
  `value` String,
  `value_nullable` Nullable(String)
) PRIMARY KEY `key` SOURCE(
  CLICKHOUSE(USER 'default' TABLE 'range_key_dictionary_source_table' PASSWORD '' DB 'hamster_odbc')
) LIFETIME(MIN 10 MAX 20) LAYOUT(FLAT());

DQL

通过 ODBC 添加数据时写入 SQL 语句中。

select 
ifNull(c7, 'was_null'),
ifNull(c8, 'OK'),
JSONExtractString('{"a": "OK", "b": [-100, 200.0, 300]}', 'a'),
multiIf(c7='OK', c7, 'a'='a', 'issue', 'issue'),
multiIf('a'='c', 'issue', c8 IS NULL, 'OK', 'issue'),
multiIf('a'='c', 'issue', c8='OK', 'issue', 'OK'),
if(c10=toDateTime('2022-12-30 13:44:17'), 'OK', 'issue'),
if(c10=toDateTime(1672407857, 'UTC'), 'OK', 'issue'),
if(date_trunc('hour', c10)=toDateTime('2022-12-30 13:00:00'), 'OK', 'issue'),
if(date_trunc('month', c10)=toDateTime('2022-12-01 00:00:00'), 'OK', 'issue'),
if(year(c10)=2022, 'OK', 'issue'),
if(month(c10)=12, 'OK', 'issue'),
if(date(c10)=toDateTime('2022-12-30 00:00:00'), 'OK', 'issue'),
case when 'a'='a' then 'OK' else 'issue' end,
case when 'a'='b' then 'issue' else 'OK' end,
if((SELECT argMin(c2, c1) FROM hamster_odbc.all_types)=3200, 'OK', 'issue'),
if((select uniqExactIf(number, number % 2 = 0) from numbers(100))=50, 'OK', 'issue'),
if((select max(c1) from hamster_odbc.all_types)=127, 'OK', 'issue'),
if(leftPad(c7, 5)='   OK', 'OK', 'issue'),
dictGetOrDefault('hamster_odbc.range_key_dictionary', 'value', toUInt64(1), 'issue') as dict_1,
dictGetOrDefault('hamster_odbc.range_key_dictionary', 'value', toUInt64(3), 'OK') as dict_2
from hamster_odbc.all_types limit 1;

select 
c1, c9,
leadInFrame(c9) OVER (PARTITION BY c1 ORDER BY c9 ASC ROWS
                 BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
from hamster_odbc.all_types;

DQL 的输出如下:
Image