fix period user metric aggregation

This commit is contained in:
zhx 2026-05-22 18:10:26 +08:00
parent cfbc50a3fb
commit 84e29c689f
3 changed files with 56 additions and 15 deletions

View File

@ -31,6 +31,7 @@ func (r *MySQLRepository) EnsureSchema(ctx context.Context) error {
KEY idx_dashboard_cdc_user_country_origin_country (sys_origin, country_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`,
createDailyMetricTable,
createDailyUserMetricTable,
createPeriodMetricTable,
createPeriodUserMetricTable,
createGamePeriodMetricTable,
@ -64,6 +65,20 @@ const createDailyMetricTable = `CREATE TABLE IF NOT EXISTS country_dashboard_dai
KEY idx_daily_origin_date (sys_origin, stat_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`
const createDailyUserMetricTable = `CREATE TABLE IF NOT EXISTS country_dashboard_daily_user_metric (
id bigint NOT NULL AUTO_INCREMENT,
stat_date date NOT NULL,
sys_origin varchar(50) NOT NULL,
country_code varchar(64) NOT NULL,
country_name varchar(128) NOT NULL,
user_id bigint NOT NULL,
metric_type varchar(32) NOT NULL,
created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_daily_user_metric (stat_date, sys_origin, country_code, user_id, metric_type),
KEY idx_daily_user_metric (sys_origin, user_id, metric_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`
const createPeriodMetricTable = `CREATE TABLE IF NOT EXISTS country_dashboard_period_metric (
id bigint NOT NULL AUTO_INCREMENT,
period_type varchar(16) NOT NULL,

View File

@ -12,13 +12,7 @@ func (r *MySQLRepository) applyDailyUserMetric(ctx context.Context, tx *sql.Tx,
if c.DeltaSign < 0 {
return r.deleteDailyUserMetric(ctx, tx, c, day, metricType)
}
inserted, err := insertPeriodUserMetric(ctx, tx, c, dashboard.PeriodWindow{
Type: dashboard.PeriodDay,
Key: day.Format("2006-01-02"),
Name: day.Format("2006-01-02"),
StartDate: dashboardPtr(day),
EndDate: dashboardPtr(day.AddDate(0, 0, 1)),
}, r.cfg.Dashboard.StorageTimezone, metricType)
inserted, err := insertDailyUserMetric(ctx, tx, c, day, metricType)
if err != nil || !inserted {
return err
}
@ -59,14 +53,7 @@ ON DUPLICATE KEY UPDATE `+column+` = `+column+` + 1, country_name = VALUES(count
}
func (r *MySQLRepository) deleteDailyUserMetric(ctx context.Context, tx *sql.Tx, c dashboard.Contribution, day time.Time, metricType string) error {
window := dashboard.PeriodWindow{
Type: dashboard.PeriodDay,
Key: day.Format("2006-01-02"),
Name: day.Format("2006-01-02"),
StartDate: dashboardPtr(day),
EndDate: dashboardPtr(day.AddDate(0, 0, 1)),
}
deleted, err := deletePeriodUserMetric(ctx, tx, c, window, r.cfg.Dashboard.StorageTimezone, metricType)
deleted, err := deleteDailyUserMetricRow(ctx, tx, c, day, metricType)
if err != nil || !deleted {
return err
}
@ -99,6 +86,31 @@ WHERE period_type = ? AND period_key = ? AND stat_timezone = ? AND sys_origin =
return err
}
func insertDailyUserMetric(ctx context.Context, tx *sql.Tx, c dashboard.Contribution, day time.Time, metricType string) (bool, error) {
result, err := tx.ExecContext(ctx, `
INSERT IGNORE INTO country_dashboard_daily_user_metric (
stat_date, sys_origin, country_code, country_name, user_id, metric_type
) VALUES (?, ?, ?, ?, ?, ?)
`, day, c.SysOrigin, c.Country.Code, c.Country.Name, c.UserID, metricType)
if err != nil {
return false, err
}
affected, err := result.RowsAffected()
return affected > 0, err
}
func deleteDailyUserMetricRow(ctx context.Context, tx *sql.Tx, c dashboard.Contribution, day time.Time, metricType string) (bool, error) {
result, err := tx.ExecContext(ctx, `
DELETE FROM country_dashboard_daily_user_metric
WHERE stat_date = ? AND sys_origin = ? AND country_code = ? AND user_id = ? AND metric_type = ?
`, day, c.SysOrigin, c.Country.Code, c.UserID, metricType)
if err != nil {
return false, err
}
affected, err := result.RowsAffected()
return affected > 0, err
}
func (r *MySQLRepository) applyGamePeriodUserMetric(ctx context.Context, tx *sql.Tx, c dashboard.Contribution, window dashboard.PeriodWindow, statTimezone string) error {
result, err := tx.ExecContext(ctx, `
INSERT IGNORE INTO country_dashboard_game_period_user_metric (

View File

@ -26,3 +26,17 @@ CREATE TABLE IF NOT EXISTS dashboard_cdc_user_country (
PRIMARY KEY (user_id),
KEY idx_dashboard_cdc_user_country_origin_country (sys_origin, country_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS country_dashboard_daily_user_metric (
id bigint NOT NULL AUTO_INCREMENT,
stat_date date NOT NULL,
sys_origin varchar(50) NOT NULL,
country_code varchar(64) NOT NULL,
country_name varchar(128) NOT NULL,
user_id bigint NOT NULL,
metric_type varchar(32) NOT NULL,
created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_daily_user_metric (stat_date, sys_origin, country_code, user_id, metric_type),
KEY idx_daily_user_metric (sys_origin, user_id, metric_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;