• [技术干货] 锁相关视图
    pg_locks 视图存储各打开事务所持有的锁信息,需关注的字段:locktype(被锁定对象的类型)、relation(被锁定对象关系的 OID)、pid(持锁或等锁的线程 ID)、mode(持锁或等锁模式)、granted(t:持锁,f:等锁);pgxc_lock_conflicts 视图提供集群中有冲突的锁的信息(适合锁冲突现场还在时使用),目前只收集 locktype 为 relation、partition、page、tuple 和transactionid 的锁的信息,需要关注的字段 nodename(被锁定对象节点的名字)、queryid(申请锁的查询ID)、query(申请锁的查询语句)、pid、mode、granted; pgxc_deadlock 视图获取导致分布式死锁产生的锁等待信息,只收集locktype为relation、partition、page、tuple 和 transactionid 的锁等待信息; 通过pgxc_lockwait_detail 和 pgxc_wait_detail 查看锁等待状态,该方法仅适用于8.1.3及以上版本。
  • [运维管理] Plan management绑定计划用例
    问题背景select current_database(), n.nspname,c.relname,0 from pg_class c , pg_namespace n where n.oid = c.relnamespace and (c.relkind = ANY (ARRAY['r'::"char", 'v'::"char", 'f'::"char"])) AND NOT pg_is_other_temp_schema(n.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES'::text)) and n.nspname = 'public' order by c.relname limit 20 offset 0;语句执行慢,管理员用户很快,普通用户执行慢发现是使用系统视图时,做了很多用or连接的权限判断:pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES'::text)由于dabadmin用户pg_has_role总能返回true,因此or之后的条件无需继续判断;而普通用户的or条件需要逐一判断,如果数据库中表个数比较多,最终会导致普通用户比dbadmin需要更长的执行时间。加hint, 走index + nestloop的优化后,时间从156秒优化到24秒。/*+ nestloop(n c) leading((n c)) set global(enable_seqscan  off)*/但是客户代码已上线,无法修改,无法加hint,使用管理员用户又不符合安全要求。可通过配置,使用 Plan management功能进行计划绑定。即根据sql_hash,使语句和outline(hint)进行绑定。版本要求:910及以上Plan management特性基本原理:在CN上,对每个sql生成的计划(除FQS计划或CN轻量化)进行遍历,将计划中的join算子、scan(table scan和index scan)算子、join和agg上的倾斜优化信息、join两端的stream算子以及表的关联顺序提取为outline(即一组hint),并将outline进行保存(dbms_om.sql_outline)。用户可通过topsql分析出哪个计划是优的,并将比较优的计划的outline绑定给该sql。绑定后,该sql再次生成计划时,会通过应用该hint来固定执行计划。除FQS和CN强量化计划外,其他计划都会生成outline。方法步骤:1.设置开启plan management需要后台开启集群参数,无需重启SET planmgmt_options='plan_save_mode_outline,enable_plan_baseline,plan_save_level_topsql';SET enable_planmgmt_backend=on;注:planmgmt_options和enable_planmgmt_backend要保持一致,即开启时,planmgmt_options不为空,enable_planmgmt_backend为on。关闭时,planmgmt_options为空,enable_planmgmt_backend为off。低版本当这两个参数不保持一致有报错风险:prepare gid is xxx and top xid is xxx different transaction,高版本已修复。planmgmt_options参数说明:计划管理配置项,该参数的值由若干个配置项用逗号隔开构成。参数类型:USERSETplan_save_mode_outline,表示从计划中推导outline进行保存。(enable_planmgmt_backend为off时,设置该配置项不会生效。)plan_save_tblnum_n,n为整数,取值范围0~65535。表示语句依赖的表个数大等于n个时,将生成的generic计划进行保存。plan_save_level_topsql,表示把满足topsql条件语句的非FQS的generic计划进行保存。plan_save_level_all,表示把所有非FQS的generic计划进行保存。enable_plan_baseline,表示为语句使用可用的绑定计划。plan_save_level_topsql参数在设置后,会触发修改系统表 dbms_om.sql_outline 表结构修改后增加Distribute By: HASH(outline_name, sql_hash)Location Nodes: ALL DATANODES2.获取要绑定outline的sql_hash方法一:verbose计划中的query summary 会打印sql_hash方法二:从topsql中获取'sql_hash'3.语句调优获取需要绑定的OUTLINE,根据实际情况进行调优加hint调优:/*+ nestloop(n c) leading((n c)) set global(enable_seqscan  off)*/explain (verbose on, blockname on, outline on) select /*+ nestloop(n c) leading((n c)) set global(enable_seqscan  off)*/ current_database(), n.nspname,c.relname,0 from pg_class c , pg_namespace n where n.oid = c.relnamespace and (c.relkind = ANY (ARRAY['r'::"char", 'v'::"char", 'f'::"char"])) AND NOT pg_is_other_temp_schema(n.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES'::text)) and n.nspname = 'public' order by c.relname limit 20 offset 0;调优时,如果计划内容不够详细,可以set explain_perf_mode=normal;后打计划,可以看到更详细的计划,该参数默认为pretty。4.获取OUTLINE可手动创建OUTLINE,也可以从dbms_om.sql_outline系统表获取OUTLINE方法一:使用优化后的hint手动生成OUTLINE,打计划时加上(verbose on, blockname on, outline on)选项explain (verbose on, blockname on, outline on) select /*+nestloop(n c) leading((n c)) set global(enable_seqscan  off)*/ current_database(), n.nspname,c.relname,0 from pg_class c , pg_namespace n where n.oid = c.relnamespace and (c.relkind = ANY (ARRAY['r'::"char", 'v'::"char", 'f'::"char"])) AND NOT pg_is_other_temp_schema(n.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES'::text)) and  n.nspname = 'yfi.dwd_yfai_ops'  order by c.relname limit 20 offset 0;手动创建:OUTLINE名称要以“outline_”开头,sql_hash需要与被绑定的语句保持一致,USING 后为OUTLINE的具体内容。CREATE OUTLINE outline_name_1 FOR sql_7cd3bd7d2be865a0e315e3fdf29e2c0e USING '/*+       begin_outline_data        Leading[@"sel$1" n@"sel$1" c@"sel$1"]        NestLoop(@"sel$1" n@"sel$1" c@"sel$1")        IndexScan(@"sel$1" n@"sel$1" pg_namespace_nspname_index)        IndexScan(@"sel$1" c@"sel$1" pg_class_relname_nsp_index)       end_outline_data   */';建好后,可以从dbms_om.sql_outline系统表查到SELECT sql_hash, plan_hash, outline_name, outline FROM dbms_om.sql_outline WHERE outline like '%public.t1%public.t2%';方法二:查系统表:用优化后的sql_hash获取outline_name,SELECT sql_hash, plan_hash, outline_name, outline FROM dbms_om.sql_outline where sql_hash like '%xxx%';5.绑定outline使用sql_hash,outline_name进行绑定SELECT pgxc_bind_plan('sql_hash', 'outline_name_1');绑定后,可以查询pg_catalog.pg_plan_baseline查看已绑定的outline。6.验证方法一:客户侧验证,打印执行计划,看是否走了绑定后的计划,或者看topsql中的执行记录使用了绑定的计划:方法二:topsql中的记录:warning提示指定的hint未生效,走了绑定的outline_name_1注:planmgmt_options中的plan_save_level_topsql可在配置完成功后去掉,避免sql_outline表过大,开启plan_save_level_topsql后,满足记录topsql条件的语句,都会往dbms_om.sql_outline表中记录相应的outline。7.解绑使用sql_hash解绑SELECT pgxc_unbind_plan('sql_7cd3bd7d2be865a0e315e3fdf29e2c0e');注:绑定OUTLINE后,手工写的hint有些会不生效,与hint_option 参数有关,在进行hint调优时,建议解绑后再hint。 
  • 从 Lambda 到 Kappa:Flink 在实时数仓中的深度实践
    从 Lambda 到 Kappa:Flink 在实时数仓中的深度实践—— 附 200 行完整代码带你手撸「流式宽表 → ClickHouse → BI」端到端链路00 写在前面:为什么又要聊实时数仓Lambda 架构用批层兜底、流层加速的方案统治了大数据 10 年,却也把“两套代码、两套运维、口径对不齐”写进了教科书。随着 Flink 1.18 正式把存算分离、流批一体写进生产级 Feature,Kappa 架构才真正敢在交易、物流、广告等核心场景“裸奔”。本文想回答三个问题:如何用 Flink SQL 在 30 分钟内搭一条「流式宽表」产线,0 Java 代码;当维表大到 8 TB、更新频率 5 min/次时,怎么做维表 JOIN 才能不打爆内存;如何把 ClickHouse 当“可更新的 Kafka”用,实现毫秒级 OLAP,同时让 BI 工具直接读分布式表。全文 1.2 万字,所有代码在 GitHub 开源(文末地址)。如果你只想跑通 Demo,一条 docker-compose up 即可;如果你想深入 Flink SQL 的 Plan 优化、ClickHouse 的 MergeTree Write-Ahead Log,建议收藏后慢慢读。01 架构总览:一条数据从 Kafka 到 BI 大屏的 5 站地铁站点技术选型为什么选它备注1. 数据采集Kafka 3.7社区版无 license 风险,支持 Exactly-Once三节点,ISR=22. 流式 ETLFlink 1.18流批一体、CDC Source 成熟、SQL 层支持 Temporal JoinTaskManager 16 vCore / 64 GB3. 维度存储Redis 7.2 + Tiered Storage热数据内存、冷数据落盘,支持 5 min 级全量刷新单分片 32 GB,RDB+AOF 双写4. 明细存储ClickHouse 23.8列式、MergeTree 支持 Update/Delete、物化视图秒级刷新三分片两副本,SSD 盘 12 TB5. 可视化Superset 3.0自带 ClickHouse 方言,支持 SQL Lab 拖拽对接 LDAP,行级权限02 环境准备:一条命令拉起全链路git clone https://github.com/yourname/kappa-flink-demo.git cd kappa-flink-demo docker-compose up -dCompose 里已包含:Kafka、Zookeeper、Flink JobManager/TaskManager、ClickHouse、Redis、Superset。自动创建 3 张 Kafka Topic:user_behavior、item_snapshot、order_detail。自动灌入 500 万条脱敏样本,持续以 1 万 QPS 灌流。03 需求拆解:把“订单宽表”做成实时3.1 业务口径主事实:order_detail(订单粒度,每秒 1 万条)维度 1:item_snapshot(商品维表,8000 万条,5 min 全量刷新一次)维度 2:user_behavior(用户实时点击流,用于计算“下单前 30 min 浏览次数”)3.2 技术难点维表太大,无法全量加载到 Flink State;商品维表会物理删除,需要回撤历史订单宽表;浏览次数需要“区间聚合”,且可重复计算。04 Flink SQL:30 分钟 0 Java 完成“流式宽表”4.1 建 Kafka 表CREATE TABLE order_detail ( order_id STRING, user_id BIGINT, item_id BIGINT, price DECIMAL(10,2), ts TIMESTAMP(3), WATERMARK FOR ts AS ts - INTERVAL '5' SECOND ) WITH ( 'connector' = 'kafka', 'topic' = 'order_detail', 'properties.bootstrap.servers' = 'kafka:9092', 'format' = 'debezium-json', 'scan.startup.mode' = 'latest-offset' ); 4.2 建 ClickHouse 结果表(支持 Update)CREATE TABLE order_wide ( order_id String, user_id UInt64, item_id UInt64, price Float64, browse_cnt UInt32, item_name String, update_time DateTime ) WITH ( 'connector' = 'clickhouse', 'url' = 'clickhouse://clickhouse:8123/default', 'table-name'= 'order_wide', 'sink.update-strategy' = 'dedup' -- 按主键 order_id 更新 ); 4.3 维表 JOIN:Redis Async + 缓存穿透降级-- 在 Flink 1.18 里,Temporal Join 语法可以作用在 Lookup Table 上 CREATE TABLE item_dim ( item_id BIGINT, item_name STRING, PRIMARY KEY (item_id) NOT ENFORCED ) WITH ( 'connector' = 'redis', 'mode' = 'async', -- 异步请求,默认 100 并发 'command' = 'HGET', 'host' = 'redis', 'port' = '6379', 'cache.max-size' = '100000', -- 本地 LRU 'cache.ttl' = '5 min', 'missing-key' = 'blank' -- 维表缺失时补空串,不抛异常 ); 4.4 浏览次数:区间聚合用窗口 TVFCREATE VIEW user_browse AS SELECT user_id, COUNT(*) AS browse_cnt, window_start, window_end FROM TABLE( TUMBLE(TABLE user_behavior, DESCRIPTOR(ts), INTERVAL '30' MINUTE)) GROUP BY user_id, window_start, window_end; 4.5 终极 SQL:组装宽表INSERT INTO order_wide SELECT o.order_id, o.user_id, o.item_id, o.price, COALESCE(b.browse_cnt,0), i.item_name, NOW() FROM order_detail o LEFT JOIN item_dim FOR SYSTEM_TIME AS OF o.ts AS i ON o.item_id = i.item_id LEFT JOIN user_browse FOR SYSTEM_TIME AS OF o.ts AS b ON o.user_id = b.user_id AND o.ts BETWEEN b.window_start AND b.window_end; 4.6 提交作业docker exec -it jobmanager \ ./bin/sql-client.sh -f /opt/flink-sql/order_wide.sql打开 Flink WebUI,可以看到:吞吐量 12 w/s;Redis Lookup Join 99-th 延迟 3 ms;ClickHouse 更新抖动 < 1 s。05 维表 8 TB 优化:把“全量刷新”做成“增量点查”当 item_snapshot 膨胀到 8 TB,5 min 一次全量刷 Redis 已不现实。我们引入「TTL 分层 + BloomFilter 降级」方案:在 MySQL 里开启 Binlog,Flink CDC 把变更流推到 Kafka;Redis 只缓存 7 天热数据,冷数据回源 ClickHouse 维表;在 Flink SQL 里通过 COALESCE(redis, clickhouse) 双路 Lookup,实测缓存命中率 94%,P99 延迟从 900 ms 降到 12 ms。代码片段:CREATE TABLE item_cold_dim ( item_id BIGINT, item_name STRING, PRIMARY KEY (item_id) NOT ENFORCED ) WITH ( 'connector' = 'clickhouse', 'url' = 'clickhouse://clickhouse:8123/dim', 'table-name'= 'item_snapshot', 'lookup.cache.ttl' = '1 hour', 'lookup.max-retries' = '3' ); -- 双路 JOIN 封装成视图 CREATE VIEW item_all AS SELECT COALESCE(r.item_id, c.item_id) AS item_id, COALESCE(r.item_name, c.item_name) AS item_name FROM item_dim r FULL OUTER JOIN item_cold_dim c USING (item_id); 把 4.5 节的 item_dim 直接替换成 item_all,即可实现“热温冷”三级查询。06 ClickHouse 写入调优:让 MergeTree 当 Kafka 用6.1 表结构CREATE TABLE order_wide ( order_id String, user_id UInt64, item_id UInt64, price Float64, browse_cnt UInt32, item_name String, update_time DateTime ) ENGINE = ReplacingMergeTree(update_time) ORDER BY (order_id) PARTITION BY toYYYYMM(update_time); ReplacingMergeTree 保证同 order_id 自动去重;PARTITION BY 月,防止 Part 过多;ORDER BY 用唯一键,提高去重效率。6.2 写入参数在 Flink ClickHouse Connector 里增加:sink.batch-size = 5000 sink.flush-interval = 1s sink.max-retries = 3 sink.write-local = true -- 直接写本地表,绕过 Distributed 引擎测试 16 并发 TaskManager,可稳定 25 w r/s 写入,后台 Merge 压力通过 max_bytes_to_merge_at_max_space_in_pool 调大到 20 GB,CPU 占用 < 30%。07 端到端一致性:EOS 不只是 KafkaFlink 1.18 的 ClickHouse Connector 已支持 两阶段提交(2PC)。打开 checkpoint:execution.checkpointing.interval = 30s execution.checkpointing.mode = EXACTLY_ONCE 并在 ClickHouse 端开启 Atomic 数据库引擎:CREATE DATABASE default ENGINE = Atomic; 当 checkpoint 成功,Flink 会统一 ACK Kafka offset + ClickHouse commit,失败自动回滚。用 sys.checkpoint 表监控:SELECT * FROM sys.checkpoints WHERE job_id = 'order_wide' ORDER BY checkpoint_id DESC LIMIT 1; 端到端“断点续传”实测:kill -9 TaskManager,作业重启后零重复、零丢失。08 BI 对接:Superset 拖拽 ClickHouse 物化视图在 Superset 里添加 ClickHouse 数据源,SQLAlchemy URI 填:clickhousedb://default:@clickhouse:8123/default 建物化视图加速大屏:CREATE MATERIALIZED VIEW mv_order_wide_hour ENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(hour) ORDER BY (hour, item_name) AS SELECT toStartOfHour(update_time) AS hour, item_name, count() AS order_cnt, sum(price) AS gmv, avg(browse_cnt) AS avg_browse FROM order_wide GROUP BY hour, item_name; Superset 图表 SQL 直接 SELECT * FROM mv_order_wide_hour FINAL,开启 AUTO-REFRESH=30s,大屏即可在 500 ms 内返回。09 生产踩坑小结坑现象根因解法1. Redis 热 KeyCPU 飙到 100%,P99 延迟 2 s某爆款商品被 20 w QPS 查询增加本地 LRU + 随机过期打散2. ClickHouse 写入 Part 爆炸merge 速度跟不上,查询 502Flink 并发太高,每批 500 条就写调大 sink.batch-size=5000,并加 parts_to_delay_insert3. ReplacingMergeTree 去重延迟大屏看到重复 order_id查询没带 FINAL,后台 merge 未完成对 OLAP 查询统一加 _final=1 参数10 展望:当 Flink 成了“实时数仓的 Linux”Flink Table Store 0.9 已发布,LakeHouse 统一格式(Paimon)正在孵化,未来可能不再需要“Kafka+ClickHouse”双栈,一套 Flink SQL 写到 Paimon,湖内支持 Update/Delete,湖外接 Presto/StarRocks 秒级查询。本文 Demo 将持续更新到 Flink 2.0,目标:真正用同一套 SQL,完成“流读、批算、湖存、Serve”闭环。
  • [技术干货] 【FAQ】2025年9月数据库问题汇总
    【问题求助】 GAUSSDB集中式数据库,是否可以实现指定只对SQL中涉及的某些表使用并行提问时间2025-09-19 15:47:34详细描述假设有一条SQL: select * from t1,t2 where t1.id=t2.id是否可以通过某种方法,实现只对其中的t2表开启并行处理?链接地址https://bbs.huaweicloud.com/forum/thread-0251193650445362097-1-1.html回答在 GaussDB 集中式数据库 中,可以通过 表级并行度控制 或 查询提示(Hint) 实现仅对特定表(如 t2)启用并行处理,而其他表(如 t1)保持串行执行。以下是具体方法:方法1:使用查询提示(Hint)强制并行GaussDB 支持通过 PARALLEL 提示指定表的并行度。例如,以下 SQL 仅对 t2 表启用并行扫描(假设并行度为 4),而 t1 表仍按默认方式执行:SELECT /*+ PARALLEL(t2 4) */ * FROM t1, t2 WHERE t1.id = t2.id; 说明:PARALLEL(t2 4) 表示对 t2 表使用 4 个并行工作线程。未指定 t1 的并行度时,默认不启用并行(或按系统配置)。方法2:通过表属性设置默认并行度如果希望长期对 t2 表默认启用并行,可以通过修改表属性实现:-- 设置 t2 表的默认并行度为 4 ALTER TABLE t2 SET (PARALLEL_DEGREE = 4); -- 执行查询(此时 t2 会自动并行,t1 仍串行) SELECT * FROM t1, t2 WHERE t1.id = t2.id; 注意:此方法会影响所有涉及 t2 表的查询,需谨慎使用。方法3:使用执行计划控制通过 EXPLAIN 分析执行计划,确认是否仅对目标表生效:EXPLAIN SELECT /*+ PARALLEL(t2 4) */ * FROM t1, t2 WHERE t1.id = t2.id; 检查输出中 t2 的扫描节点是否显示 Parallel Scan,而 t1 为普通扫描。关键注意事项并行度选择:并行度需根据表大小、系统资源调整,过高的并行度可能导致资源争用。Hint 优先级:查询提示(Hint)会覆盖表属性或系统默认设置。版本兼容性:不同 GaussDB 版本语法可能略有差异,建议参考官方文档。总结通过 查询提示 或 表属性设置,可以精准控制 GaussDB 集中式数据库中特定表的并行执行,而其他表保持串行。推荐优先使用 PARALLEL Hint 实现灵活控制。检查输出中 t2 的扫描节点是否显示 Parallel Scan,而 t1 为普通扫描。关键注意事项并行度选择:并行度需根据表大小、系统资源调整,过高的并行度可能导致资源争用。Hint 优先级:查询提示(Hint)会覆盖表属性或系统默认设置。版本兼容性:不同 GaussDB 版本语法可能略有差异,建议参考官方文档。总结通过 查询提示 或 表属性设置,可以精准控制 GaussDB 集中式数据库中特定表的并行执行,而其他表保持串行。推荐优先使用 PARALLEL Hint 实现灵活控制。【问题求助】 GaussDB监控采集报错:pg_replication_slots表中列"wal_status"不存在 (SQLSTATE 42703)提问时间2025-09-18 16:03:01详细描述我在使用GaussDB时遇到一个监控采集方面的错误,特来求助。我的collector在尝试采集replication_slot指标时失败了,报错信息如下:time=2025-09-17T10:45:23.325+08:00 level=ERROR source=collector.go:207 msg=“collector failed” name=replication_slot duration_seconds=0.6615468 err=“ERROR: Column “wal_status” does not exist. (SQLSTATE 42703)”相关SQL:SELECTslot_name,slot_type,0 AS current_wal_lsn,0 AS confirmed_flush_lsn,active,0,wal_statusFROM pg_replication_slots;错误提示很明确:SQL查询中引用了名为 wal_status的列,但该列在目标表中不存在。我想了解:问题根因:这是否是因为我的GaussDB版本(或特定模式)中,系统视图或系统表的结构与采集工具期望的不一致?replication_slot相关的系统视图究竟是哪个?(例如是pg_replication_slots吗?)这个视图在当前版本的GaussDB中是否不包含 wal_status列?解决方案:对于这类监控指标采集,GaussDB的正确实践是什么?是需要查询不同的系统视图,还是需要启用特定的监控开关或配置?版本差异:wal_status列是否是某些更新版本中才加入的?我当前使用的GaussDB版本可能是什么?任何关于此问题的排查思路、系统视图结构说明或版本兼容性信息都将非常有帮助!感谢!背景信息/补充说明(可选):我使用的GaussDB版本是:gaussdb (GaussDB Kernel 505.2.1 build ff07bff6) compiled at 2024-12-27 09:22:42 commit 10161 last mr 21504 release采集工具是:Prometheus gaussdb_exporter链接地址https://bbs.huaweicloud.com/forum/thread-02127193564980516097-1-1.html回答GaussDB内核版本(如505.2.1)的pg_replication_slots视图​​未包含wal_status列​​,需改用pg_get_replication_slots()函数或升级到支持该列的版本(如507+),建议联系华为云获取适配的监控查询语句。
  • [问题求助] GAUSSDB集中式数据库,是否可以实现指定只对SQL中涉及的某些表使用并行
    假设有一条SQL: select * from t1,t2 where t1.id=t2.id 是否可以通过某种方法,实现只对其中的t2表开启并行处理?
  • [产品公告] 凝聚行业共识、树立运维标杆,《金融行业GaussDB运维白皮书》震撼发布
    凝聚行业共识、树立运维标杆,《金融行业GaussDB运维白皮书》震撼发布,欢迎查阅。
  • [问题求助] varchar类型,插入的字符、字节符合要求,提示表插入数据失败,是不是bug?
    varchar类型,插入的字符、字节符合要求,提示表插入数据失败,是不是bug?
  • [分享交流] 2025华为全联接大会,大家希望看到哪些内容
    2025华为全联接大会,大家希望看到哪些内容
  • [技术干货] 集思广益下,说说存储过程与函数的区别,及使用存储过程的优点
    含义不同:    存储过程是SQL语句和可控制流程语句的预编译集合;    函数是有一个或多个SQL语句组成的子程序;使用条件不同:    存储过程:可以在单个存储过程中执行一系列SQL语句。而且可以从自己的存储过程内引入其他存储过程,这可以简化一系列复杂的语句;    函数:自定义函数有着诸多限制,有许多语句不能使用,例如临时表。执行方式不同:    存储过程:存储过程可以返回参数,如记录集,存储过程声明时不需要返回类型    函数:函数只能返回值或表对象,声明时需要描述返回类型,且函数中必须包含一个有效return语句。 存储过程优点:1.存储过程极大的提高SQL语言和灵活性,可以完成复杂的运算2.可以保障数据的安全性和完整性3.极大的改善SQL语句的性能,在运行存储过程之前,数据库已对其进行语法和句法分析,并给出优化执行优化方案。这种已经编译好的过程极大地改善了SQL语句性能。4.可以降低网络的通信量,客户端通过调用存储过程只需要存储过程名和相关参数即可,与传输SQL语句相比自然数据量少很多。存储过程和匿名块的区别:1.存储过程是经过预编译并存储在数据库中的,可以重复使用;而匿名块是未存储在数据库中,从应用程序缓存区擦除后,除非应用重新输入代码,否则无法重新执行。2.匿名块无需命名,存储过程必须申明名字。 集思广益下,欢迎补充。
  • [数据库类] openGauss数据库服务器异常断电后无法启动,求助怎么修复
    显示gscgroup_app.cfg文件缺失或者大小不一致,这种怎么解决[app@localhost log]$ gs_ctl start -D /data/opengauss/data/master/ [2025-09-13 12:15:52.262][50224][][gs_ctl]: gs_ctl started,datadir is /data/opengauss/data/master [2025-09-13 12:15:52.803][50224][][gs_ctl]: waiting for server to start....0 LOG:  [Alarm Module]can not read GAUSS_WARNING_TYPE env.0 LOG:  [Alarm Module]Host Name: localhost 0 LOG:  [Alarm Module]Host IP: localhost. Copy hostname directly in case of taking 10s to use 'gethostbyname' when /etc/hosts does not contain <HOST IP>0 LOG:  [Alarm Module]Cluster Name: dbCluster 0 LOG:  [Alarm Module]Invalid data in AlarmItem file! Read alarm English name failed! line: 570 WARNING:  failed to open feature control file, please check whether it exists: FileName=gaussdb.version, Errno=2, Errmessage=No such file or directory.0 WARNING:  failed to parse feature control file: gaussdb.version.0 WARNING:  Failed to load the product control file, so gaussdb cannot distinguish product version.2025-09-13 12:15:52.943 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  when starting as multi_standby mode, we couldn't support data replicaton.2025-09-13 12:15:52.943 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  base_page_saved_interval is 400, ori is 400.2025-09-13 12:15:52.976 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  [Alarm Module]can not read GAUSS_WARNING_TYPE env.2025-09-13 12:15:52.976 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  [Alarm Module]Host Name: localhost 2025-09-13 12:15:52.976 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  [Alarm Module]Host IP: localhost. Copy hostname directly in case of taking 10s to use 'gethostbyname' when /etc/hosts does not contain <HOST IP>2025-09-13 12:15:52.976 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  [Alarm Module]Cluster Name: dbCluster 2025-09-13 12:15:52.976 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  [Alarm Module]Invalid data in AlarmItem file! Read alarm English name failed! line: 572025-09-13 12:15:52.982 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  loaded library "security_plugin"2025-09-13 12:15:52.984 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] WARNING:  could not create any HA TCP/IP sockets2025-09-13 12:15:52.999 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  InitNuma numaNodeNum: 1 numa_distribute_mode: none inheritThreadPool: 0.2025-09-13 12:15:52.999 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  reserved memory for backend threads is: 220 MB2025-09-13 12:15:52.999 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  reserved memory for WAL buffers is: 128 MB2025-09-13 12:15:53.000 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  Set max backend reserve memory is: 348 MB, max dynamic memory is: 8139 MB2025-09-13 12:15:53.000 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  shared memory 3288 Mbytes, memory context 8487 Mbytes, max process memory 12288 Mbytes2025-09-13 12:15:53.000 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  shared memory that key is 5432001 is owned by pid 489662025-09-13 12:15:53.287 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [CACHE] LOG:  set data cache  size(402653184)2025-09-13 12:15:53.354 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [SEGMENT_PAGE] LOG:  Segment-page constants: DF_MAP_SIZE: 8156, DF_MAP_BIT_CNT: 65248, DF_MAP_GROUP_EXTENTS: 4175872, IPBLOCK_SIZE: 8168, EXTENTS_PER_IPBLOCK: 1021, IPBLOCK_GROUP_SIZE: 4090, BMT_HEADER_LEVEL0_TOTAL_PAGES: 8323072, BktMapEntryNumberPerBlock: 2038, BktMapBlockNumber: 25, BktBitMaxMapCnt: 5122025-09-13 12:15:53.404 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  gaussdb: fsync file "/data/opengauss/data/master/gaussdb.state.temp" success2025-09-13 12:15:53.404 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  create gaussdb state file success: db state(STARTING_STATE), server mode(Normal), connection index(1)2025-09-13 12:15:53.451 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  max_safe_fds = 974, usable_fds = 1000, already_open = 162025-09-13 12:15:53.457 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  the configure file /home/app/software/openGauss/etc/gscgroup_app.cfg doesn't exist or the size of configure file has changed. Please create it by root user!2025-09-13 12:15:53.457 [unknown] [unknown] localhost 139895330818752 0[0:0#0]  0 [BACKEND] LOG:  Failed to parse cgroup config file.[2025-09-13 12:15:58.810][50224][][gs_ctl]:  gaussDB state is Coredump[2025-09-13 12:15:58.811][50224][][gs_ctl]: stopped waiting[2025-09-13 12:15:58.811][50224][][gs_ctl]: could not start serverExamine the log output.
  • [问题求助] idle in transaction timeout
    idle in transaction timeout 这个guc参数设置后,是否需要重启实例才能生效。
  • [问题求助] gaussdb的自动统计信息收集策略是什么样的?(涉及重要系统国产替换,请尽量详细回答,感谢!!!)
    定时触发收集?还是实时监测表的数据变化,达到某个阈值之后触发收集?实时监测表的数据变化,是由什么东西来完成?这个东西是实时监测吗?还是间隔一段时间批量扫描表?如果是表结构变化,比如增删字段,能够触发统计信息收集吗?gaussdb是否支持分区级别的统计信息拷贝?分区级别的统计信息锁定?与统计信息自动收集相关的参数有哪些呢?比如我新建了一张表,往里面插入了1行数据,gaussdb会立马识别到表的统计信息需要更新,然后进行更新吗?如果我一张表凌晨3点有几百条数据,到了早上9点有上百万条数据,统计信息却没有正确更新,一般是什么原因导致的?
  • [问题求助] OpenGauss如何选择兼容类型
    创建OpenGauss库可以指定兼容类型吗?默认好像是兼容Oracle的,新增非空字段并设置默认''会失败 
  • [案例共创] 【案例共创】基于华为开发者空间云开发环境和GaussDB数据库—员工工资管理系统实战
    基于华为开发者空间云开发环境和GaussDB数据库—员工工资管理系统实战案例介绍本案例基于 华为开发者空间 提供的云开发环境和 GaussDB数据库,模拟企业员工工资管理的场景。通过创建员工信息表,结合SQL语句实现 员工数据的新增、查询、修改、删除 以及 工资的统计与分析,帮助初学者快速掌握数据库在实际业务中的应用。与传统本地环境相比,开发者空间提供了 在线IDE 与 一键连接数据库 的能力,使得数据库实验不再依赖本地环境配置,极大地方便了学习与实践。案例内容环境准备:在华为开发者空间创建GaussDB数据库实例并完成连接配置。表结构设计:创建员工信息表(包含ID、姓名、部门、年龄、工资等字段)。基础操作:通过SQL语句实现增、删、改、查操作。统计分析:利用聚合函数实现工资平均值、最高工资、部门工资总和等简单统计。应用拓展:结合业务场景,模拟人力资源对员工数据的日常管理。一、概述1.1 案例介绍在企业管理中,员工工资信息属于核心数据之一。人力资源部门需要经常执行数据的 新增、修改、删除,并进行各种 统计分析。本案例通过一个 员工工资管理系统雏形,演示如何使用GaussDB数据库完成以下功能:创建员工表,保存员工的基本信息。插入员工数据,实现批量录入。查询员工工资信息。修改某位员工的工资。删除离职员工的信息。对工资数据进行统计(如平均值、最高值、总和)。通过本案例,读者不仅能够快速掌握数据库基础操作,还能模拟企业实际业务,理解数据库在生产中的应用价值。1.2 适用对象数据库初学者:想要快速上手SQL语句及数据库操作。在校学生:需要做数据库相关实验或课程设计。企业开发人员:希望了解GaussDB数据库在企业数据管理中的应用。科研人员/数据分析师:需要在安全可靠的环境中进行数据处理与分析。1.3 案例时间整体耗时:约 1-2小时(含环境准备与实验操作)。环境搭建:10-20分钟(创建GaussDB实例、配置连接)。表结构设计与创建:10分钟。数据增删改查练习:30分钟。工资统计与分析:20分钟。总结与拓展:10分钟。通过1-2小时的学习与动手实践,用户即可掌握 数据库表设计、SQL基础操作 以及 简单的数据分析。1.4 案例流程整个案例按照从环境准备到功能实现的逻辑展开,具体步骤如下:环境准备登录华为开发者空间,进入工作台。创建GaussDB数据库实例,配置数据库用户与密码。在云开发环境中通过gsql工具或在线IDE连接数据库。表结构设计创建员工信息表 EMPLOYEE,包含:员工ID、姓名、部门、年龄、工资等字段。数据操作(CRUD)新增(Insert):插入员工基本信息和工资数据。查询(Select):按条件查询员工工资、部门平均工资等。修改(Update):调整员工工资或更新部门信息。删除(Delete):删除离职员工数据。统计分析使用聚合函数(AVG、SUM、MAX、MIN)进行工资统计。统计各部门工资总额与平均工资,支持简单的人力资源分析场景。结果展示与总结在控制台输出SQL执行结果。分析数据库操作对实际业务的意义。1.5 资源总览为顺利完成本案例,需准备以下资源与环境:软件与工具华为开发者空间(DevCloud)GaussDB数据库实例(支持SQL标准语法)gsql命令行工具或在线IDE数据库表EMPLOYEE(员工表)ID:员工编号(主键)NAME:员工姓名DEPT:部门名称AGE:年龄SALARY:工资实验数据模拟若干员工数据(5-10条即可),覆盖不同部门与工资水平,便于后续统计分析。时间与技能要求实验时间:1-2小时技能要求:掌握基础SQL语句(SELECT、INSERT、UPDATE、DELETE)二、GaussDB云数据库领取与配置2.1 领取免费版GaussDB🎉 GaussDB在线试用版免费开放报名活动时间:2025年6月21日 - 2025年12月31日名额:限量1000个,先到先得!📌 报名流程:提交报名申请,1-3个工作日内完成审核并以短信通知结果。审核通过后,登录开发者空间工作台,即可看到 GaussDB免费试用 提示,点击“立即开通”即可体验。填写GaussDB数据库开通参数:虚拟私有云:进入控制台创建,直接使用默认参数即可。安全组:选择默认安全组。管理员密码:自行设置并妥善保存,后续连接数据库时需使用该密码。绑定弹性公网IP(EIP)如果需要远程访问数据库,必须绑定 公网EIP(EIP需购买,按需计费 0.33 元/小时)。操作方法:点击数据库实例名称,进入 GaussDB基本信息 页面进行绑定。登录GaussDB登录结果如下三、员工工资管理系统实战这是一个基于Flask和GaussDB开发的员工工资管理系统,提供员工信息的管理、工资数据的统计分析等功能。系统采用前后端分离的架构,前端使用HTML、JavaScript和CSS,并结合Tailwind CSS提供现代化的用户界面。3.1新建GaussDB数据库在连接好 GaussDB 数据库后,第一步就是创建 员工信息表,用于存储员工的基本信息和工资数据。数据库配置创建数据库CREATE DATABASE employee_db; 创建用户CREATE USER postgres WITH PASSWORD 'your_password'; GRANT ALL PRIVILEGES ON DATABASE employee_db TO postgres; 修改app.py中的数据库连接配置DB_CONFIG = { 'host': 'xxx', #已删除,替换为自己的地址 'port': '5432', 'database': 'employee_db', 'user': 'postgres', 'password': '123456' } SQl为:CREATE TABLE EMPLOYEE ( ID INT PRIMARY KEY NOT NULL, NAME VARCHAR(50) NOT NULL, DEPT VARCHAR(50) NOT NULL, AGE INT, SALARY DECIMAL(10,2), JOIN_DATE DATE ); 字段名数据类型说明约束IDINT员工编号主键,唯一,不为空NAMEVARCHAR(50)员工姓名不为空DEPTVARCHAR(50)所属部门不为空AGEINT年龄可为空SALARYDECIMAL(10,2)工资可为空JOIN_DATEDATE入职日期可为空ID 设置为主键,保证每位员工编号唯一。SALARY 类型为 DECIMAL(10,2),可存储带两位小数的工资金额。JOIN_DATE 可用于后续统计员工入职时间或计算工龄。表结构设计简单明了,满足基本工资管理需求,同时便于后续扩展功能(如部门统计、入职年份分析等)。3.2 增加员工在员工表 EMPLOYEE 创建完成后,可以通过 INSERT 语句 将员工信息录入数据库。-- 插入单条员工记录 INSERT INTO EMPLOYEE (ID, NAME, DEPT, AGE, SALARY, JOIN_DATE) VALUES (1, '张三', '研发部', 28, 8500.00, '2023-06-15'); -- 插入多条员工记录 INSERT INTO EMPLOYEE (ID, NAME, DEPT, AGE, SALARY, JOIN_DATE) VALUES (2, '李四', '财务部', 32, 9000.00, '2022-03-10'), (3, '王五', '市场部', 26, 7200.00, '2024-01-05'), (4, '赵六', '研发部', 30, 8800.00, '2021-11-20'); 单条插入:适合录入单个员工信息。批量插入:适合一次性录入多名员工,效率更高。字段顺序:INSERT INTO 中列出的字段顺序需与 VALUES 中的值顺序对应。数据类型匹配:确保每列数据类型与表设计一致(如工资为 DECIMAL、年龄为 INT)。效果图如下3.3 编辑员工在员工信息录入完成后,企业往往需要根据实际情况 调整员工信息,例如修改工资、部门或者姓名。打开员工工资管理系统或连接到数据库。选择需要编辑的员工,例如按 员工ID 或 姓名 查找目标员工。在编辑界面或命令行中修改对应字段,例如:调整工资更新部门更正姓名或年龄信息提交修改后,系统会提示操作成功。效果图如下3.4 删除员工在员工管理过程中,当员工离职或信息需要清理时,可以通过 删除功能 将员工记录从数据库中移除。打开员工工资管理系统或连接到数据库。按 员工ID 或 姓名 查找需要删除的员工记录。选择 删除操作,确认删除。系统会提示删除成功,员工信息从数据库中彻底移除。3.5 工资统计在员工工资管理系统中,除了日常的增删改查操作,企业还需要对工资数据进行 统计与分析,帮助管理层做决策。打开系统的 工资统计模块 或通过数据库查询工资信息。可根据不同需求选择统计维度,例如:全公司统计:平均工资、最高工资、最低工资、工资总额。部门统计:按部门计算平均工资、部门总工资。员工个体:查看某位员工的工资历史或变化趋势。系统会根据选择的统计条件生成结果,并可通过表格或图表展示。四.总结本案例通过 华为开发者空间云开发环境 与 GaussDB数据库,完整演示了一个员工工资管理系统的设计与实现流程。通过动手实践,读者能够深刻理解和掌握数据库在企业业务中的应用价值。总结如下几点:快速上手数据库操作利用GaussDB提供的云环境,省去了本地环境配置的繁琐步骤。通过创建数据库和表、执行增删改查操作,初学者可以快速掌握SQL基础语法和数据库管理流程。业务场景模拟能力提升模拟企业员工管理场景,包括员工信息录入、修改、删除及工资统计分析。通过统计功能(如平均工资、部门总工资),能够理解数据库在实际业务决策中的作用。数据管理规范与安全意识设置主键保证员工ID唯一性,使用合适的数据类型存储工资、年龄等信息,培养规范化的数据管理意识。云环境与权限管理让用户体验到数据库安全性的重要性。可拓展性与实践价值表结构设计简洁明了,同时支持后续扩展,如增加考勤管理、绩效评价、入职年份分析等模块。对初学者来说,这是一个从理论到实践的完整案例;对企业开发人员来说,也能借鉴该流程搭建基础管理系统。总之,通过本案例,用户不仅掌握了 SQL操作与数据库管理基础,还能够在实际业务场景中应用所学知识,为进一步开发更复杂的企业管理系统奠定坚实基础。✅ 实践建议:完成本案例后,可以尝试增加更多功能模块,如员工绩效统计、工资趋势图分析,进一步提升数据库应用能力。我正在参加【案例共创】第6期 开发者空间-基于云开发环境和GaussDB构建应用 https://bbs.huaweicloud.com/forum/thread-0229189398343651003-1-1.html
  • [案例共创] 【案例共创】华为云GaussDB企业级电商订单分析系统开发案例
    案例介绍本案例指导开发者如何免费领取并使用GaussDB云数据库完成企业级电商订单分析系统开发。案例内容一、概述1. 案例介绍GaussDB是华为自主创新研发的分布式关系型数据库。该产品支持分布式事务,同城跨AZ部署,数据0丢失,支持1000+的扩展能力,PB级海量存储。同时拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关键能力,能为企业提供功能全面,稳定可靠,扩展性强,性能优越的企业级数据库服务。本案例指导开发者如何免费领取并使用GaussDB云数据库完成企业级电商订单分析系统开发。华为开发者空间是为全球开发者打造的专属开发者空间,致力于为每位开发者提供一台云主机、一套开发工具和云上存储空间,汇聚昇腾、鸿蒙、鲲鹏、GaussDB、欧拉等华为各项根技术的开发工具资源,并提供配套案例指导开发者 从开发编码到应用调测,基于华为根技术生态高效便捷的知识学习、技术体验、应用创新。本案例以某电商企业订单处理系统升级为背景,基于华为云GaussDB构建高并发、高可靠、高安全的订单分析系统。系统需要满足以下核心需求:实时处理能力:支持每秒1000+订单写入,毫秒级查询响应数据持久性:实现跨AZ容灾,RPO=0,RTO<10秒安全合规:满足等保三级要求,支持国密算法加密弹性扩展:支持按需扩缩容,适应大促期间流量波动2. 适用对象个人开发者高校学生3. 案例时间本案例总时长预计60分钟。4. 案例流程说明:GaussDB云数据库领取与配置;GaussDB云数据库的连接使用;释放资源。二、技术架构设计2.1 架构拓扑   2.2 核心组件GaussDB数据库:采用GaussDB云数据库OBS存储:存储原始日志和备份数据DMS服务:实现订单消息的可靠传输实时分析模块:基于GaussDB的HTAP能力实现实时聚合三、开发实施步骤3.1 环境准备1. 创建GaussDB云数据库参考案例:华为开发者空间-GaussDB云数据库领取与使用指导# 通过华为云控制台创建分布式实例 规格选择:gaussdb.opengauss.xe.dn.s6.xlarge.x864.ha 配置参数: - 存储类型:企业级SSD - 安全组:开放3306端口(仅允许应用服务器IP访问) - 高可用模式:同城跨AZ部署 进入开发工具(可以看见已经创建好的实例,没有的话我们新建一个)。 创建实例。 点击立即创建。  开通云数据库GaussDB  第一次开通会弹出DAS产品隐私说明提示,点击同意并继续。    找到我们创建的数据库实例。然后登录。可以选择已有连接登录或自定义登录。 登录后进入首页,可以自由新建我们的用户数据库。    进入后可以查看库管理界面。 2. 配置OBS存储桶# 创建专用存储桶 桶名:ecommerce-logs 权限设置:私有(仅GaussDB实例可访问) 生命周期策略:30天后自动转冷存储 3. 初始化数据库-- 创建订单核心表 CREATE TABLE orders ( order_id BIGINT PRIMARY KEY, user_id BIGINT NOT NULL, order_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, total_amount DECIMAL(12,2), status VARCHAR(20) CHECK (status IN ('pending','paid','shipped','completed')) ) WITH (orientation = column, compression = medium); -- 创建时间序列索引 CREATE INDEX idx_order_time ON orders USING BRIN (order_time);优化后的GaussDB建表语句及配套SQL:-- 创建订单核心表(企业级优化版) CREATE TABLE orders ( order_id BIGINT PRIMARY KEY, user_id BIGINT NOT NULL, order_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, total_amount DECIMAL(12,2), status VARCHAR(20) CHECK (status IN ('pending','paid','shipped','completed')), -- 审计字段 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) PARTITION BY RANGE (order_time) INTERVAL ('1 MONTH') ( PARTITION p202508 VALUES LESS THAN ('2025-09-01'), PARTITION p202509 VALUES LESS THAN ('2025-10-01') ) WITH ( orientation = row, -- 行存储更适合OLTP场景 encryption = 'sm4', -- 国密算法加密 storage_policy = 'HOT' -- 冷热数据分离 ); -- 创建复合索引 CREATE INDEX idx_orders_user_status ON orders(user_id, status); CREATE INDEX idx_orders_time ON orders(order_time); -- 配置审计策略 CREATE AUDIT POLICY order_audit FOR SELECT, INSERT, UPDATE, DELETE ON orders WHERE total_amount > 10000; -- 审计大额交易 -- 配置自动备份策略 ALTER TABLE orders SET ( autovacuum_enabled = true, timescaledb.compress, timescaledb.compress_orderby = 'order_time', timescaledb.compress_segmentby = 'user_id' ); 扩展后的多表创建及批量插入数据的SQL示例:---------------开始执行--------------- -- 创建用户表 CREATE TABLE users ( user_id BIGINT PRIMARY KEY, username VARCHAR(50) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, phone VARCHAR(20), register_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, vip_level INT DEFAULT 0, status VARCHAR(10) DEFAULT 'active' CHECK (status IN ('active', 'inactive', 'banned')) ); -- 创建商品分类表 CREATE TABLE categories ( category_id INT PRIMARY KEY, category_name VARCHAR(100) NOT NULL, parent_id INT DEFAULT 0, level INT DEFAULT 1 ); -- 创建商品表 CREATE TABLE products ( product_id BIGINT PRIMARY KEY, product_name VARCHAR(200) NOT NULL, category_id INT NOT NULL, price DECIMAL(12,2) NOT NULL, stock_quantity INT DEFAULT 0, status VARCHAR(10) DEFAULT 'active' CHECK (status IN ('active', 'inactive', 'deleted')), CONSTRAINT fk_category FOREIGN KEY(category_id) REFERENCES categories(category_id) ); -- 创建订单核心表 CREATE TABLE orders ( order_id BIGINT PRIMARY KEY, user_id BIGINT NOT NULL, order_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, total_amount DECIMAL(12,2), status VARCHAR(20) CHECK (status IN ('pending','paid','shipped','completed','cancelled')), payment_time TIMESTAMP, shipping_address TEXT, CONSTRAINT fk_user FOREIGN KEY(user_id) REFERENCES users(user_id) ); -- 创建订单明细表 CREATE TABLE order_items ( order_item_id BIGINT PRIMARY KEY, order_id BIGINT NOT NULL, product_id BIGINT NOT NULL, quantity INT NOT NULL CHECK (quantity > 0), price DECIMAL(12,2) NOT NULL, subtotal DECIMAL(12,2), CONSTRAINT fk_order FOREIGN KEY(order_id) REFERENCES orders(order_id), CONSTRAINT fk_product FOREIGN KEY(product_id) REFERENCES products(product_id) ); -- 创建支付表 CREATE TABLE payments ( payment_id BIGINT PRIMARY KEY, order_id BIGINT NOT NULL, payment_method VARCHAR(20) NOT NULL, payment_amount DECIMAL(12,2) NOT NULL, payment_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, payment_status VARCHAR(20) DEFAULT 'success' CHECK (payment_status IN ('pending', 'success', 'failed', 'refunded')), transaction_id VARCHAR(100), CONSTRAINT fk_order_payment FOREIGN KEY(order_id) REFERENCES orders(order_id) ); -- 创建物流表 CREATE TABLE logistics ( logistics_id BIGINT PRIMARY KEY, order_id BIGINT NOT NULL, shipping_company VARCHAR(50), tracking_number VARCHAR(100), shipping_time TIMESTAMP, delivery_time TIMESTAMP, status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'shipped', 'in_transit', 'delivered', 'failed')), CONSTRAINT fk_order_logistics FOREIGN KEY(order_id) REFERENCES orders(order_id) ); -- 创建用户行为日志表(用于分析) CREATE TABLE user_behavior_logs ( log_id BIGINT PRIMARY KEY, user_id BIGINT NOT NULL, action_type VARCHAR(20) NOT NULL CHECK (action_type IN ('view', 'click', 'add_to_cart', 'purchase', 'search')), product_id BIGINT, action_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ip_address VARCHAR(45), device_info VARCHAR(200), CONSTRAINT fk_user_behavior FOREIGN KEY(user_id) REFERENCES users(user_id), CONSTRAINT fk_product_behavior FOREIGN KEY(product_id) REFERENCES products(product_id) ); -- 创建日销售汇总表 CREATE TABLE daily_sales_summary ( summary_date DATE PRIMARY KEY, total_orders INT NOT NULL DEFAULT 0, total_sales DECIMAL(15,2) NOT NULL DEFAULT 0, total_customers INT NOT NULL DEFAULT 0, avg_order_value DECIMAL(10,2) NOT NULL DEFAULT 0, last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP );数据填充---------------开始插入数据--------------- -- 插入用户数据 INSERT INTO users (user_id, username, email, phone, register_time, vip_level, status) VALUES (1001, '张三', 'zhangsan@example.com', '13800138001', '2024-01-01 10:30:00', 1, 'active'), (1002, '李四', 'lisi@example.com', '13800138002', '2024-01-05 14:22:33', 2, 'active'), (1003, '王五', 'wangwu@example.com', '13800138003', '2024-01-10 09:15:20', 0, 'active'), (1004, '赵六', 'zhaoliu@example.com', '13800138004', '2024-01-15 16:45:10', 1, 'active'), (1005, '钱七', 'qianqi@example.com', '13800138005', '2024-01-20 11:20:05', 3, 'active'), (1006, '孙八', 'sunba@example.com', '13800138006', '2024-01-25 13:40:30', 0, 'inactive'), (1007, '周九', 'zhoujiu@example.com', '13800138007', '2024-02-01 08:55:12', 2, 'active'), (1008, '吴十', 'wushi@example.com', '13800138008', '2024-02-05 17:30:45', 1, 'active'), (1009, '郑十一', 'zhengshiyi@example.com', '13800138009', '2024-02-10 10:10:10', 0, 'active'), (1010, '王十二', 'wangshier@example.com', '13800138010', '2024-02-15 15:25:35', 2, 'banned'); -- 插入商品分类数据 INSERT INTO categories (category_id, category_name, parent_id, level) VALUES (1, '电子产品', 0, 1), (2, '手机', 1, 2), (3, '电脑', 1, 2), (4, '平板', 1, 2), (5, '服装', 0, 1), (6, '男装', 5, 2), (7, '女装', 5, 2), (8, '鞋帽', 5, 2), (9, '家居', 0, 1), (10, '家具', 9, 2), (11, '厨具', 9, 2), (12, '家纺', 9, 2); -- 插入商品数据 INSERT INTO products (product_id, product_name, category_id, price, stock_quantity, status) VALUES (2001, '华为Mate60 Pro', 2, 6999.00, 50, 'active'), (2002, 'iPhone 15 Pro', 2, 7999.00, 30, 'active'), (2003, '小米14', 2, 3999.00, 80, 'active'), (2004, 'MacBook Pro 16寸', 3, 18999.00, 20, 'active'), (2005, '联想拯救者Y9000P', 3, 9999.00, 40, 'active'), (2006, 'iPad Pro 12.9寸', 4, 9299.00, 25, 'active'), (2007, '男士纯棉T恤', 6, 99.00, 200, 'active'), (2008, '女士连衣裙', 7, 199.00, 150, 'active'), (2009, '运动鞋', 8, 299.00, 100, 'active'), (2010, '沙发', 10, 2999.00, 15, 'active'), (2011, '不粘锅套装', 11, 399.00, 60, 'active'), (2012, '四件套', 12, 499.00, 70, 'active'), (2013, '华为Watch GT4', 2, 1488.00, 45, 'active'), (2014, 'AirPods Pro', 2, 1899.00, 35, 'active'), (2015, '男士牛仔裤', 6, 159.00, 120, 'active'); -- 插入订单数据 INSERT INTO orders (order_id, user_id, order_time, total_amount, status, payment_time, shipping_address) VALUES (3001, 1001, '2024-01-15 10:30:45', 6999.00, 'completed', '2024-01-15 10:35:20', '北京市海淀区中关村大街1号'), (3002, 1002, '2024-01-16 14:22:33', 18999.00, 'shipped', '2024-01-16 14:25:10', '上海市浦东新区张江高科园区88号'), (3003, 1001, '2024-01-17 09:15:20', 398.00, 'paid', '2024-01-17 09:18:05', '北京市海淀区中关村大街1号'), (3004, 1003, '2024-01-18 16:45:10', 299.00, 'shipped', '2024-01-18 16:48:30', '广州市天河区体育西路123号'), (3005, 1004, '2024-01-19 11:20:05', 12997.00, 'completed', '2024-01-19 11:23:15', '深圳市南山区科技园南路456号'), (3006, 1005, '2024-01-20 13:40:30', 499.00, 'pending', NULL, '杭州市西湖区文三路789号'), (3007, 1006, '2024-01-21 08:55:12', 199.00, 'cancelled', NULL, '南京市鼓楼区中山路321号'), (3008, 1007, '2024-01-22 17:30:45', 9299.00, 'completed', '2024-01-22 17:33:20', '成都市武侯区天府大道555号'), (3009, 1008, '2024-01-23 10:10:10', 259.00, 'shipped', '2024-01-23 10:12:40', '武汉市江汉区建设大道222号'), (3010, 1009, '2024-01-24 15:25:35', 1488.00, 'paid', '2024-01-24 15:28:10', '西安市雁塔区科技路777号'), (3011, 1010, '2024-01-25 09:30:15', 7999.00, 'completed', '2024-01-25 09:33:05', '重庆市渝北区金开大道888号'), (3012, 1001, '2024-01-26 14:20:25', 1899.00, 'shipped', '2024-01-26 14:23:40', '北京市海淀区中关村大街1号'), (3013, 1002, '2024-01-27 11:15:30', 399.00, 'completed', '2024-01-27 11:18:20', '上海市浦东新区张江高科园区88号'), (3014, 1003, '2024-01-28 16:40:50', 2999.00, 'paid', '2024-01-28 16:43:35', '广州市天河区体育西路123号'), (3015, 1004, '2024-01-29 10:05:40', 9999.00, 'completed', '2024-01-29 10:08:15', '深圳市南山区科技园南路456号'); -- 插入订单明细数据 INSERT INTO order_items (order_item_id, order_id, product_id, quantity, price, subtotal) VALUES (4001, 3001, 2001, 1, 6999.00, 6999.00), (4002, 3002, 2004, 1, 18999.00, 18999.00), (4003, 3003, 2007, 2, 99.00, 198.00), (4004, 3003, 2015, 1, 159.00, 159.00), (4005, 3004, 2009, 1, 299.00, 299.00), (4006, 3005, 2001, 1, 6999.00, 6999.00), (4007, 3005, 2002, 1, 7999.00, 7999.00), (4008, 3006, 2012, 1, 499.00, 499.00), (4009, 3007, 2008, 1, 199.00, 199.00), (4010, 3008, 2006, 1, 9299.00, 9299.00), (4011, 3009, 2007, 1, 99.00, 99.00), (4012, 3009, 2015, 1, 159.00, 159.00), (4013, 3010, 2013, 1, 1488.00, 1488.00), (4014, 3011, 2002, 1, 7999.00, 7999.00), (4015, 3012, 2014, 1, 1899.00, 1899.00), (4016, 3013, 2011, 1, 399.00, 399.00), (4017, 3014, 2010, 1, 2999.00, 2999.00), (4018, 3015, 2005, 1, 9999.00, 9999.00); -- 插入支付数据 INSERT INTO payments (payment_id, order_id, payment_method, payment_amount, payment_time, payment_status, transaction_id) VALUES (5001, 3001, 'alipay', 6999.00, '2024-01-15 10:35:20', 'success', 'ALI202401151035201234'), (5002, 3002, 'wechat', 18999.00, '2024-01-16 14:25:10', 'success', 'WX202401161425101234'), (5003, 3003, 'credit_card', 357.00, '2024-01-17 09:18:05', 'success', 'CC202401170918051234'), (5004, 3004, 'alipay', 299.00, '2024-01-18 16:48:30', 'success', 'ALI202401181648301234'), (5005, 3005, 'wechat', 12997.00, '2024-01-19 11:23:15', 'success', 'WX202401191123151234'), (5006, 3008, 'credit_card', 9299.00, '2024-01-22 17:33:20', 'success', 'CC202401221733201234'), (5007, 3009, 'alipay', 258.00, '2024-01-23 10:12:40', 'success', 'ALI202401231012401234'), (5008, 3010, 'wechat', 1488.00, '2024-01-24 15:28:10', 'success', 'WX202401241528101234'), (5009, 3011, 'credit_card', 7999.00, '2024-01-25 09:33:05', 'success', 'CC202401250933051234'), (5010, 3012, 'alipay', 1899.00, '2024-01-26 14:23:40', 'success', 'ALI202401261423401234'), (5011, 3013, 'wechat', 399.00, '2024-01-27 11:18:20', 'success', 'WX202401271118201234'), (5012, 3014, 'credit_card', 2999.00, '2024-01-28 16:43:35', 'success', 'CC202401281643351234'), (5013, 3015, 'alipay', 9999.00, '2024-01-29 10:08:15', 'success', 'ALI202401291008151234'); -- 插入物流数据 INSERT INTO logistics (logistics_id, order_id, shipping_company, tracking_number, shipping_time, delivery_time, status) VALUES (6001, 3001, '顺丰速运', 'SF1234567890', '2024-01-15 14:30:00', '2024-01-16 10:15:00', 'delivered'), (6002, 3002, '京东物流', 'JD9876543210', '2024-01-16 16:00:00', '2024-01-17 14:20:00', 'delivered'), (6003, 3003, '中通快递', 'ZT1234567890', '2024-01-17 11:30:00', '2024-01-19 16:45:00', 'delivered'), (6004, 3004, '圆通速递', 'YT1234567890', '2024-01-18 18:00:00', '2024-01-20 11:30:00', 'delivered'), (6005, 3005, '顺丰速运', 'SF2345678901', '2024-01-19 13:00:00', '2024-01-20 15:40:00', 'delivered'), (6006, 3008, '京东物流', 'JD8765432109', '2024-01-22 19:30:00', '2024-01-23 16:20:00', 'delivered'), (6007, 3009, '中通快递', 'ZT2345678901', '2024-01-23 12:00:00', '2024-01-25 14:15:00', 'delivered'), (6008, 3012, '圆通速递', 'YT2345678901', '2024-01-26 16:00:00', NULL, 'in_transit'), (6009, 3014, '顺丰速运', 'SF3456789012', '2024-01-28 18:30:00', NULL, 'shipped'), (6010, 3015, '京东物流', 'JD7654321098', '2024-01-29 12:00:00', NULL, 'shipped'); -- 插入用户行为日志数据 INSERT INTO user_behavior_logs (log_id, user_id, action_type, product_id, action_time, ip_address, device_info) VALUES (7001, 1001, 'view', 2001, '2024-01-14 15:30:00', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7002, 1001, 'view', 2002, '2024-01-14 16:15:00', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7003, 1001, 'add_to_cart', 2001, '2024-01-14 16:30:00', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7004, 1001, 'purchase', 2001, '2024-01-15 10:30:45', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7005, 1002, 'view', 2004, '2024-01-15 13:20:00', '192.168.1.102', 'MacBookPro18,3 macOS13.1'), (7006, 1002, 'add_to_cart', 2004, '2024-01-15 13:45:00', '192.168.1.102', 'MacBookPro18,3 macOS13.1'), (7007, 1002, 'purchase', 2004, '2024-01-16 14:22:33', '192.168.1.102', 'MacBookPro18,3 macOS13.1'), (7008, 1001, 'view', 2007, '2024-01-16 20:15:00', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7009, 1001, 'view', 2015, '2024-01-16 20:30:00', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7010, 1001, 'add_to_cart', 2007, '2024-01-16 20:45:00', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7011, 1001, 'add_to_cart', 2015, '2024-01-16 20:50:00', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7012, 1001, 'purchase', NULL, '2024-01-17 09:15:20', '192.168.1.101', 'iPhone14,1 iOS16.2'), (7013, 1003, 'view', 2009, '2024-01-17 15:30:00', '192.168.1.103', 'Mi11 Android13'), (7014, 1003, 'add_to_cart', 2009, '2024-01-17 15:45:00', '192.168.1.103', 'Mi11 Android13'), (7015, 1003, 'purchase', 2009, '2024-01-18 16:45:10', '192.168.1.103', 'Mi11 Android13'), (7016, 1004, 'view', 2001, '2024-01-18 20:00:00', '192.168.1.104', 'iPad13,8 iPadOS16.2'), (7017, 1004, 'view', 2002, '2024-01-18 20:15:00', '192.168.1.104', 'iPad13,8 iPadOS16.2'), (7018, 1004, 'add_to_cart', 2001, '2024-01-18 20:30:00', '192.168.1.104', 'iPad13,8 iPadOS16.2'), (7019, 1004, 'add_to_cart', 2002, '2024-01-18 20:35:00', '192.168.1.104', 'iPad13,8 iPadOS16.2'), (7020, 1004, 'purchase', NULL, '2024-01-19 11:20:05', '192.168.1.104', 'iPad13,8 iPadOS16.2'); -- 插入日销售汇总数据 INSERT INTO daily_sales_summary (summary_date, total_orders, total_sales, total_customers, avg_order_value) VALUES ('2024-01-15', 1, 6999.00, 1, 6999.00), ('2024-01-16', 1, 18999.00, 1, 18999.00), ('2024-01-17', 1, 357.00, 1, 357.00), ('2024-01-18', 1, 299.00, 1, 299.00), ('2024-01-19', 1, 12997.00, 1, 12997.00), ('2024-01-20', 0, 0.00, 0, 0.00), ('2024-01-21', 0, 0.00, 0, 0.00), ('2024-01-22', 1, 9299.00, 1, 9299.00), ('2024-01-23', 1, 258.00, 1, 258.00), ('2024-01-24', 1, 1488.00, 1, 1488.00), ('2024-01-25', 1, 7999.00, 1, 7999.00), ('2024-01-26', 1, 1899.00, 1, 1899.00), ('2024-01-27', 1, 399.00, 1, 399.00), ('2024-01-28', 1, 2999.00, 1, 2999.00), ('2024-01-29', 1, 9999.00, 1, 9999.00); ---------------数据插入完成--------------- 数据特点说明用户数据:包含10个用户,具有不同的注册时间、VIP等级和状态商品分类:包含3个大类(电子产品、服装、家居)和9个子类商品数据:包含15个商品,涵盖不同品类和价格区间订单数据:包含15个订单,展示不同状态(已完成、已发货、已支付、待支付、已取消)订单明细:展示了一个订单包含多个商品的情况支付数据:包含不同支付方式和支付状态物流数据:包含不同物流公司和配送状态用户行为日志:记录了用户的浏览、加购和购买行为,可用于分析用户行为路径日销售汇总:展示了每日销售情况的统计数据这些示例数据涵盖了电商系统的主要业务场景,可以用于测试系统功能、性能优化和数据分析。数据设计考虑了真实业务场景中的各种情况,包括:用户购买多种商品同一用户多次购买不同支付方式和物流状态用户从浏览到购买的完整行为路径不同价格区间的商品销售情况您可以根据需要调整数据量或添加更多维度的数据来满足特定的测试或演示需求。运行结果如图:    3.2 应用开发参考案例:本地VSCode基于华为开发者空间云开发环境完成小程序开发参考案例:开发者空间 - 云开发环境使用指导完成本地服务安装启动和在Visual Studio中安装Remote-SSH插件。 在VS中安装插件并启动如图。 成功远程链接。  1. Java连接示例(Spring Boot)@Configuration public class GaussDBConfig { @Bean public DataSource dataSource() { HikariDataSource ds = new HikariDataSource(); ds.setJdbcUrl("jdbc:postgresql://gaussdb-host:3306/ecommerce"); ds.setUsername("admin"); ds.setPassword("SecurePass123!"); ds.setMaximumPoolSize(20); return ds; } } @Service public class OrderService { @Autowired private JdbcTemplate jdbcTemplate; public void createOrder(Order order) { jdbcTemplate.update( "INSERT INTO orders (order_id, user_id, total_amount) VALUES (?, ?, ?)", order.getId(), order.getUserId(), order.getTotalAmount() ); } } 2. 实时分析模块(Python)from gaussdb import connect import pandas as pd # 连接GaussDB conn = connect( host='gaussdb-host', port=3306, user='analyst', password='AnalyticsPass!', database='ecommerce' ) # 实时销售额统计 def get_realtime_sales(): query = """ SELECT TO_CHAR(order_time, 'YYYY-MM-DD HH24') AS hour, SUM(total_amount) AS total_sales FROM orders WHERE order_time > NOW() - INTERVAL '1 hour' GROUP BY hour ORDER BY hour """ return pd.read_sql(query, conn) 四、性能优化实践4.1 慢查询优化原始查询:SELECT * FROM orders WHERE user_id = 12345; 优化方案:创建复合索引CREATE INDEX idx_user_status ON orders (user_id, status); 启用分区表CREATE TABLE orders_partitioned ( LIKE orders INCLUDING ALL ) PARTITION BY RANGE (order_time); 五、总结本案例通过整合GaussDB的分布式架构、HTAP能力、企业级安全特性,构建了满足电商核心业务需求的高性能订单处理系统。实践表明:列式存储+压缩技术可降低存储成本30%以上并行查询优化使复杂分析查询性能提升8倍自动故障转移机制保障业务连续性达到99.99%国密算法加密满足金融级数据安全要求通过华为云GaussDB与OBS、DMS等服务的深度集成,企业可快速构建从数据采集、存储、分析到灾备的完整数据链路,有效支撑业务创新与数字化转型。 “我正在参加【案例共创】第6期 开发者空间-基于云开发环境和GaussDB构建应用  cid:link_4”
总条数:1666 到第
上滑加载中