@@ -76,8 +76,8 @@ type AlertEventStore struct {
7676
7777 // New fields for AlertEvent
7878 EventId string
79- StartTime uint64
80- EndTime uint64
79+ StartTime uint32
80+ EndTime uint32
8181 Duration uint32
8282 State uint32
8383 AlertTime uint64
@@ -118,8 +118,8 @@ func AlertEventColumns() []*ckdb.Column {
118118
119119 // New columns
120120 ckdb .NewColumn ("event_id" , ckdb .String ),
121- ckdb .NewColumn ("start_time" , ckdb .UInt64 ),
122- ckdb .NewColumn ("end_time" , ckdb .UInt64 ),
121+ ckdb .NewColumn ("start_time" , ckdb .DateTime ),
122+ ckdb .NewColumn ("end_time" , ckdb .DateTime ),
123123 ckdb .NewColumn ("duration" , ckdb .UInt32 ),
124124 ckdb .NewColumn ("state" , ckdb .UInt32 ),
125125 ckdb .NewColumn ("alert_time" , ckdb .UInt64 ),
@@ -204,12 +204,24 @@ func (e *AlertEventStore) GenerateNewFlowTags(cache *flow_tag.FlowTagCache) {
204204}
205205
206206// GenAlertEventCKTable creates the alert_event table definition.
207- // Engine: ReplacingMergeTree(_id), ORDER BY (time, event_id).
207+ //
208+ // Design rationale:
209+ // - Engine: ReplacingMergeTree(time) — for the same ORDER BY key, keep the row
210+ // with the highest _id (i.e., the most recently written row).
211+ // - ORDER BY (event_id): dedup key is event_id alone, guaranteeing globally
212+ // unique event_id. ClickHouse ReplacingMergeTree dedup key == ORDER BY key,
213+ // so time cannot be added to ORDER BY without making it part of the dedup key.
214+ // - PARTITION BY toYYYYMM(time) (TimeFuncDay): provides time-based partition
215+ // pruning for fast time-range queries without requiring time in ORDER BY.
216+ // Queries with a time filter skip entire month partitions automatically.
208217func GenAlertEventCKTable (cluster , storagePolicy , ckdbType string , ttl int , coldStorage * ckdb.ColdStorage ) * ckdb.Table {
209218 table := common .ALERT_EVENT .TableName ()
210219 timeKey := "time"
211220 engine := ckdb .ReplacingMergeTree
212- orderKeys := []string {"time" , "event_id" }
221+ // Dedup key is event_id only — guarantees at most one row per event_id
222+ // within each daily partition (same event_id always has the same time,
223+ // so it always lands in the same partition → globally unique event_id).
224+ orderKeys := []string {"event_id" }
213225
214226 return & ckdb.Table {
215227 Version : basecommon .CK_VERSION ,
@@ -219,9 +231,9 @@ func GenAlertEventCKTable(cluster, storagePolicy, ckdbType string, ttl int, cold
219231 GlobalName : table ,
220232 Columns : AlertEventColumns (),
221233 TimeKey : timeKey ,
222- ReplacingKey : "_id " ,
234+ ReplacingKey : "time " ,
223235 TTL : ttl ,
224- PartitionFunc : DefaultPartition ,
236+ PartitionFunc : DefaultAlertEventPartition ,
225237 Engine : engine ,
226238 Cluster : cluster ,
227239 StoragePolicy : storagePolicy ,
0 commit comments