-- Users: Snowflake PK (not AUTO_INCREMENT), public spark_id, email map, login t_devices. CREATE TABLE IF NOT EXISTS t_users ( id BIGINT PRIMARY KEY COMMENT 'Snowflake 用户 id(uid),时间有序,非自增', spark_id VARCHAR(32) NOT NULL COMMENT '对外展示的账号,用户可改,全局唯一', nickname VARCHAR(64) NOT NULL DEFAULT '' COMMENT '昵称', avatar VARCHAR(512) NOT NULL DEFAULT '' COMMENT '头像对象存储 key 或 URL,不存图片二进制', qrcode VARCHAR(512) NOT NULL DEFAULT '' COMMENT '个人二维码对象存储 key 或 URL,不存图片二进制', birthday DATE NULL COMMENT '生日,未填为空', gender TINYINT NOT NULL DEFAULT 0 COMMENT '0=未知 1=男 2=女', status TINYINT NOT NULL DEFAULT 1 COMMENT '1=正常 0=禁用', last_login_at DATETIME(3) NULL COMMENT '最近一次登录时间', last_active_at DATETIME(3) NULL COMMENT '最近一次活跃时间(登录、心跳、发消息等)', created_at DATETIME(3) NOT NULL COMMENT '注册时间(create_time)', updated_at DATETIME(3) NOT NULL COMMENT '资料最近更新时间(update_time)', UNIQUE KEY uk_spark_id (spark_id) ) COMMENT='用户账号。主键 Snowflake 即 uid;登录身份在 t_user_emails,设备在 t_user_devices'; CREATE TABLE IF NOT EXISTS t_user_emails ( email VARCHAR(255) NOT NULL COMMENT '规范化后的小写邮箱,登录账号', user_id BIGINT NOT NULL COMMENT '绑定的 t_users.id,一对一', created_at DATETIME(3) NOT NULL COMMENT '绑定时间', PRIMARY KEY (email), UNIQUE KEY uk_user_id (user_id) ) COMMENT='邮箱与用户的一对一映射。登录用邮箱查此表再读 t_users'; CREATE TABLE IF NOT EXISTS t_user_devices ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT '行 id,表内自增,仅内部用;业务唯一键是 (user_id, device_id)', user_id BIGINT NOT NULL COMMENT '所属用户', device_id BIGINT UNSIGNED NOT NULL COMMENT 't_devices.device_id,JWT did', last_login_at DATETIME(3) NOT NULL COMMENT '该用户在此设备最近登录成功', last_active_at DATETIME(3) NULL COMMENT '该用户在此设备最近活跃', created_at DATETIME(3) NOT NULL COMMENT '该用户首次在此设备绑定', PRIMARY KEY (id), UNIQUE KEY uk_user_device (user_id, device_id), KEY idx_user_id (user_id), KEY idx_device_id (device_id) ) COMMENT='用户与设备关系;设备属性见 t_devices,当前 App 见 JWT aid';