feat: add im tenant db routing and chapter seven flows
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
-- IM 第一至七章数据库增量审核稿
|
||||
-- 仅供审核,不要直接在生产库盲执行。
|
||||
-- 适用目标:已有 Tinode MySQL 库,补齐本项目 1-7 章业务层依赖表与关键字段。
|
||||
-- 注意:本稿使用 MySQL 8 functional index 处理空 idempotency_key 唯一性。
|
||||
-- 第一阶段多库方案:本 SQL 的 im_tenant 放 hotgo 公共库;tinode/各租户业务库表暂时保留 tenant_id 字段。
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
-- hotgo 公共后台库需要先存在;如果你审核通过,可先执行:
|
||||
-- CREATE DATABASE IF NOT EXISTS hotgo CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
-- USE hotgo;
|
||||
--
|
||||
-- 租户业务库 tinode 也需要存在并完成 Tinode 基础表初始化:
|
||||
-- CREATE DATABASE IF NOT EXISTS tinode CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ============================================================
|
||||
-- 1. 租户、认证、安全基础表
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_tenant(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
code VARCHAR(64) NOT NULL,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
tenant_desc VARCHAR(256),
|
||||
db_name VARCHAR(128) NOT NULL DEFAULT '' COMMENT 'tenant business database name, e.g. tinode_acme',
|
||||
db_dsn VARCHAR(1024) NOT NULL DEFAULT '' COMMENT 'optional full tenant DB DSN, empty means reuse base MySQL config',
|
||||
state SMALLINT NOT NULL,
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
created_by BIGINT NOT NULL,
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
updated_by BIGINT NOT NULL,
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE INDEX uk_im_tenant_code(code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
INSERT INTO im_tenant(code,name,tenant_desc,db_name,db_dsn,state,created_by,updated_by)
|
||||
VALUES('default','Default Tenant',NULL,'tinode','',1,0,0)
|
||||
ON DUPLICATE KEY UPDATE name=VALUES(name), db_name=VALUES(db_name), updated_at=CURRENT_TIMESTAMP(3);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_tenant_config(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
max_users BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0 means unlimited',
|
||||
max_groups BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0 means unlimited',
|
||||
max_group_members INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0 means unlimited',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
created_by BIGINT NOT NULL,
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
updated_by BIGINT NOT NULL,
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE INDEX uk_im_tenant_config_tenant_id(tenant_id),
|
||||
CONSTRAINT fk_im_tenant_config_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_verification_codes(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
challenge_id VARCHAR(64) NOT NULL,
|
||||
scene VARCHAR(32) NOT NULL,
|
||||
action VARCHAR(64) NOT NULL DEFAULT '',
|
||||
phone_hash CHAR(64) NOT NULL,
|
||||
phone_mask VARCHAR(32) NOT NULL,
|
||||
target_user BIGINT,
|
||||
code_hash CHAR(64) NOT NULL,
|
||||
verification_token_hash CHAR(64),
|
||||
state SMALLINT NOT NULL,
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
max_attempts INT NOT NULL,
|
||||
expires_at DATETIME(3) NOT NULL,
|
||||
resend_after DATETIME(3) NOT NULL,
|
||||
verified_at DATETIME(3),
|
||||
consumed_at DATETIME(3),
|
||||
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(id),
|
||||
UNIQUE INDEX uk_im_verification_tenant_challenge(tenant_id, challenge_id),
|
||||
INDEX idx_im_verification_tenant_scene_phone_state(tenant_id, scene, phone_hash, state, expires_at),
|
||||
CONSTRAINT fk_im_verification_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_user_security(
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
auth_version INT NOT NULL DEFAULT 1,
|
||||
password_updated_at DATETIME(3),
|
||||
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(tenant_id,user_id),
|
||||
CONSTRAINT fk_im_user_security_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_realname_verifications(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
submission_id VARCHAR(64) NOT NULL,
|
||||
status VARCHAR(16) NOT NULL,
|
||||
name_cipher TEXT NOT NULL,
|
||||
id_type VARCHAR(32) NOT NULL,
|
||||
id_number_cipher TEXT NOT NULL,
|
||||
id_number_hash CHAR(64) NOT NULL,
|
||||
masked_name VARCHAR(64) NOT NULL,
|
||||
masked_id_number VARCHAR(64) NOT NULL,
|
||||
review_reason VARCHAR(256),
|
||||
verified_at DATETIME(3),
|
||||
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(id),
|
||||
UNIQUE INDEX uk_im_realname_submission(tenant_id, submission_id),
|
||||
INDEX idx_im_realname_user_latest(tenant_id, user_id, created_at),
|
||||
INDEX idx_im_realname_id_hash(tenant_id, id_number_hash),
|
||||
CONSTRAINT fk_im_realname_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_action_tokens(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
token_id VARCHAR(64) NOT NULL,
|
||||
action VARCHAR(64) NOT NULL,
|
||||
target VARCHAR(128) NOT NULL DEFAULT '',
|
||||
token_hash CHAR(64) NOT NULL,
|
||||
state SMALLINT NOT NULL,
|
||||
expires_at DATETIME(3) NOT NULL,
|
||||
consumed_at DATETIME(3),
|
||||
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(id),
|
||||
UNIQUE INDEX uk_im_action_tokens_token(tenant_id, token_id),
|
||||
INDEX idx_im_action_tokens_user_action(tenant_id, user_id, action, target, state, expires_at),
|
||||
CONSTRAINT fk_im_action_tokens_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_youth_mode_settings(
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
purpose VARCHAR(64) NOT NULL,
|
||||
password_hash VARBINARY(255) NOT NULL,
|
||||
failed_attempts INT NOT NULL DEFAULT 0,
|
||||
locked_until DATETIME(3),
|
||||
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(tenant_id, user_id, purpose),
|
||||
CONSTRAINT fk_im_youth_settings_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_system_notifications(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
event_id VARCHAR(64) NOT NULL,
|
||||
event_type VARCHAR(64) NOT NULL,
|
||||
title VARCHAR(128) NOT NULL,
|
||||
summary VARCHAR(512) NOT NULL,
|
||||
action JSON,
|
||||
read_at DATETIME(3),
|
||||
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(id),
|
||||
UNIQUE INDEX uk_im_system_notifications_event(tenant_id, user_id, event_id),
|
||||
INDEX idx_im_system_notifications_inbox(tenant_id, user_id, id DESC),
|
||||
CONSTRAINT fk_im_system_notifications_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ============================================================
|
||||
-- 2. 好友、黑名单
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_friend_requests(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
request_id VARCHAR(64) NOT NULL,
|
||||
applicant_id BIGINT NOT NULL,
|
||||
target_id BIGINT NOT NULL,
|
||||
message VARCHAR(200) NOT NULL DEFAULT '',
|
||||
source VARCHAR(32) NOT NULL DEFAULT '',
|
||||
source_topic VARCHAR(64) NOT NULL DEFAULT '',
|
||||
status VARCHAR(16) NOT NULL,
|
||||
idempotency_key VARCHAR(128) NOT NULL DEFAULT '',
|
||||
expires_at DATETIME(3) NOT NULL,
|
||||
handled_at DATETIME(3),
|
||||
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(id),
|
||||
UNIQUE INDEX uk_im_friend_requests_request(tenant_id, request_id),
|
||||
INDEX idx_im_friend_requests_pair(tenant_id, applicant_id, target_id, status, created_at),
|
||||
INDEX idx_im_friend_requests_inbox(tenant_id, target_id, status, created_at),
|
||||
CONSTRAINT fk_im_friend_requests_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE UNIQUE INDEX uk_im_friend_requests_idempotency
|
||||
ON im_friend_requests(tenant_id, applicant_id, (NULLIF(idempotency_key, '')));
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_friendships(
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
peer_id BIGINT NOT NULL,
|
||||
status VARCHAR(16) NOT NULL,
|
||||
remark VARCHAR(64) NOT NULL DEFAULT '',
|
||||
topic CHAR(25) NOT NULL DEFAULT '',
|
||||
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(tenant_id, user_id, peer_id),
|
||||
INDEX idx_im_friendships_peer(tenant_id, peer_id, status),
|
||||
CONSTRAINT fk_im_friendships_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_user_blocks(
|
||||
tenant_id BIGINT NOT NULL,
|
||||
blocker_id BIGINT NOT NULL,
|
||||
blocked_id BIGINT NOT 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(tenant_id, blocker_id, blocked_id),
|
||||
INDEX idx_im_user_blocks_blocked(tenant_id, blocked_id),
|
||||
CONSTRAINT fk_im_user_blocks_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ============================================================
|
||||
-- 3. 收藏、转发、消息增强
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_favorites(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
favorite_id VARCHAR(64) NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
item_type VARCHAR(16) NOT NULL,
|
||||
source_topic CHAR(25) NOT NULL,
|
||||
source_seq INT NOT NULL,
|
||||
snapshot JSON,
|
||||
attachment_refs JSON,
|
||||
availability VARCHAR(16) NOT NULL DEFAULT 'available',
|
||||
idempotency_key VARCHAR(128) NOT NULL DEFAULT '',
|
||||
collected_at DATETIME(3) NOT 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(id),
|
||||
UNIQUE INDEX uk_im_favorites_favorite(tenant_id, favorite_id),
|
||||
UNIQUE INDEX uk_im_favorites_source(tenant_id, user_id, source_topic, source_seq),
|
||||
INDEX idx_im_favorites_inbox(tenant_id, user_id, id DESC),
|
||||
INDEX idx_im_favorites_type(tenant_id, user_id, item_type, id DESC),
|
||||
CONSTRAINT fk_im_favorites_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE UNIQUE INDEX uk_im_favorites_idempotency
|
||||
ON im_favorites(tenant_id, user_id, (NULLIF(idempotency_key, '')));
|
||||
|
||||
CREATE TABLE IF NOT EXISTS im_message_revisions(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
topic CHAR(25) NOT NULL,
|
||||
seqid INT NOT NULL,
|
||||
version INT NOT NULL,
|
||||
actor BIGINT NOT NULL,
|
||||
head JSON,
|
||||
content JSON,
|
||||
reason VARCHAR(256) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE INDEX uk_im_message_revisions_version(tenant_id, topic, seqid, version),
|
||||
CONSTRAINT fk_im_message_revisions_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ============================================================
|
||||
-- 4. Tinode 基础表需补齐的字段/索引
|
||||
-- 如果你的库是用当前 schema.sql 初始化,这些已经存在。
|
||||
-- 如果是旧库,需要逐项核对后再 ALTER。
|
||||
-- ============================================================
|
||||
|
||||
-- users:租户隔离字段和索引。
|
||||
-- ALTER TABLE users ADD COLUMN tenant_id BIGINT NOT NULL DEFAULT 1 AFTER id;
|
||||
-- CREATE INDEX users_tenant_id_id ON users(tenant_id, id);
|
||||
|
||||
-- topics:租户隔离、群治理 Aux、租户维度唯一索引。
|
||||
-- 第六章群邀请、入群审批、群公告、群治理配置、成员禁言目前存放在 topics.aux JSON。
|
||||
-- 后续若要强状态机和审计,应拆 im_group_join_requests、im_group_announcements、im_group_mutes 等表。
|
||||
-- ALTER TABLE topics ADD COLUMN tenant_id BIGINT NOT NULL DEFAULT 1 AFTER id;
|
||||
-- ALTER TABLE topics ADD COLUMN aux JSON AFTER tags;
|
||||
-- CREATE UNIQUE INDEX topics_tenant_name ON topics(tenant_id, name);
|
||||
-- CREATE INDEX topics_tenant_owner ON topics(tenant_id, owner);
|
||||
|
||||
-- subscriptions:租户字段和按租户查成员索引。
|
||||
-- ALTER TABLE subscriptions ADD COLUMN tenant_id BIGINT NOT NULL DEFAULT 1 AFTER id;
|
||||
-- CREATE INDEX subscriptions_tenant_userid ON subscriptions(tenant_id, userid);
|
||||
-- CREATE INDEX subscriptions_tenant_topic ON subscriptions(tenant_id, topic);
|
||||
-- CREATE INDEX subscriptions_userid_topic_deletedat ON subscriptions(userid, topic, deletedat);
|
||||
|
||||
-- messages:租户、客户端消息幂等、编辑撤回字段、搜索/文件授权需要的索引。
|
||||
-- ALTER TABLE messages ADD COLUMN tenant_id BIGINT NOT NULL DEFAULT 1 AFTER id;
|
||||
-- ALTER TABLE messages ADD COLUMN client_msg_id VARCHAR(64) AFTER `from`;
|
||||
-- ALTER TABLE messages ADD COLUMN version INT NOT NULL DEFAULT 1 AFTER client_msg_id;
|
||||
-- ALTER TABLE messages ADD COLUMN recalled_at DATETIME(3) AFTER version;
|
||||
-- ALTER TABLE messages ADD COLUMN recalled_by BIGINT AFTER recalled_at;
|
||||
-- CREATE INDEX messages_tenant_topic ON messages(tenant_id, topic);
|
||||
-- CREATE UNIQUE INDEX messages_sender_client_mid ON messages(tenant_id, `from`, client_msg_id);
|
||||
|
||||
-- dellog:用户侧删除过滤需要 tenant_id。
|
||||
-- ALTER TABLE dellog ADD COLUMN tenant_id BIGINT NOT NULL DEFAULT 1 AFTER id;
|
||||
-- CREATE INDEX dellog_tenant_topic ON dellog(tenant_id, topic);
|
||||
-- CREATE INDEX dellog_topic_deletedfor_low_hi ON dellog(topic, deletedfor, low, hi);
|
||||
|
||||
-- fileuploads:文件 ACL、租户隔离、ETag。
|
||||
-- ALTER TABLE fileuploads ADD COLUMN tenant_id BIGINT NOT NULL DEFAULT 1 AFTER id;
|
||||
-- ALTER TABLE fileuploads ADD COLUMN etag VARCHAR(128) AFTER size;
|
||||
-- CREATE INDEX fileuploads_tenant_status ON fileuploads(tenant_id, status);
|
||||
|
||||
-- filemsglinks:文件资源级 ACL 需要租户、topic 和 userid 引用。
|
||||
-- ALTER TABLE filemsglinks ADD COLUMN tenant_id BIGINT NOT NULL DEFAULT 1 AFTER id;
|
||||
-- ALTER TABLE filemsglinks ADD COLUMN topic CHAR(25) AFTER msgid;
|
||||
-- ALTER TABLE filemsglinks ADD COLUMN userid BIGINT AFTER topic;
|
||||
-- CREATE INDEX filemsglinks_tenant_fileid ON filemsglinks(tenant_id, fileid);
|
||||
|
||||
-- usertags/topictags/devices/auth/credentials 也已按租户增加 tenant_id;
|
||||
-- 若旧库缺字段,需要参照当前 server/db/mysql/schema.sql 逐项补齐。
|
||||
Reference in New Issue
Block a user