Files
im_server/docs/sql/IM-群消息按月分表SQL.sql
T

81 lines
3.5 KiB
SQL

-- IM group-message monthly sharding, baseline month: 2026-09 (UTC).
-- Run in each tenant database. The application pre-creates subsequent months.
CREATE TABLE IF NOT EXISTS im_group_message_shards (
shard_month CHAR(6) NOT NULL,
table_name VARCHAR(64) NOT NULL,
shard_start DATETIME(3) NOT NULL,
shard_end DATETIME(3) NOT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'prepared',
row_count BIGINT NOT NULL DEFAULT 0,
min_created_at DATETIME(3) NULL,
max_created_at DATETIME(3) NULL,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (shard_month),
UNIQUE KEY uk_im_group_message_shards_table (table_name),
KEY idx_im_group_message_shards_status (status, shard_month)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
DROP TABLE IF EXISTS im_group_message_topic_shards;
DROP TABLE IF EXISTS im_group_message_dedup;
CREATE TABLE IF NOT EXISTS im_group_messages_202609 (
message_id BIGINT NOT NULL,
topic VARCHAR(64) NOT NULL,
group_id BIGINT NOT NULL,
seqid BIGINT NOT NULL,
from_user BIGINT NOT NULL,
client_msg_id VARCHAR(64) NULL,
msg_type VARCHAR(32) NOT NULL DEFAULT 'text',
status VARCHAR(32) NOT NULL DEFAULT 'normal',
content JSON NULL,
head JSON NULL,
mentioned_user_ids JSON NULL,
mention_all TINYINT(1) NOT NULL DEFAULT 0,
reply_seqid BIGINT NULL,
root_seqid BIGINT NULL,
file_count INT NOT NULL DEFAULT 0,
content_size INT NOT NULL DEFAULT 0,
has_risk TINYINT(1) NOT NULL DEFAULT 0,
audit_status VARCHAR(32) NOT NULL DEFAULT 'pass',
version INT NOT NULL DEFAULT 1,
recalled_at DATETIME(3) NULL,
recalled_by BIGINT NULL,
deleted_at DATETIME(3) NULL,
expires_at DATETIME(3) NULL,
created_at DATETIME(3) NOT NULL,
updated_at DATETIME(3) NOT NULL,
PRIMARY KEY (message_id),
UNIQUE KEY uk_202609_group_seq (group_id, seqid),
UNIQUE KEY uk_202609_topic_seq (topic, seqid),
UNIQUE KEY uk_202609_sender_client (topic, from_user, client_msg_id),
KEY idx_202609_group_status_seq (group_id, status, seqid),
KEY idx_202609_topic_created (topic, created_at),
KEY idx_202609_topic_from_seq (topic, from_user, seqid),
KEY idx_202609_audit_created (audit_status, created_at),
KEY idx_202609_expires (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE IF NOT EXISTS im_group_messages_202608 LIKE im_group_messages_202609;
CREATE TABLE IF NOT EXISTS im_group_messages_202610 LIKE im_group_messages_202609;
CREATE TABLE IF NOT EXISTS im_group_messages_202611 LIKE im_group_messages_202609;
INSERT INTO im_group_message_shards
(shard_month,table_name,shard_start,shard_end,status)
VALUES
('202608','im_group_messages_202608','2026-08-01 00:00:00.000','2026-09-01 00:00:00.000','sealing'),
('202609','im_group_messages_202609','2026-09-01 00:00:00.000','2026-10-01 00:00:00.000','writable'),
('202610','im_group_messages_202610','2026-10-01 00:00:00.000','2026-11-01 00:00:00.000','prepared'),
('202611','im_group_messages_202611','2026-11-01 00:00:00.000','2026-12-01 00:00:00.000','prepared')
ON DUPLICATE KEY UPDATE
table_name=VALUES(table_name),
shard_start=VALUES(shard_start),
shard_end=VALUES(shard_end),
status=IF(status IN ('sealed','archived'),status,VALUES(status));
-- Historical migration is deliberately separate from schema deployment.
-- Backfill im_group_messages into the matching month table in bounded batches,
-- then warm Redis topic routes before removing legacy reads.