
1) 【一句话结论】
为管理公司新媒体内容(官网文章、公众号推文),设计CMS的数据库方案需包含:内容表支持版本管理(通过乐观锁防并发冲突,版本表记录修改日志实现回滚),标签用关联表替代字符串存储,全文索引配置中文分词提升搜索体验,分库分表按发布时间(如月)分片避免热点,并引入Redis缓存优化跨库查询,确保数据一致性与性能。
2) 【原理/概念讲解】
老师会解释:
version字段(默认1),版本表记录每次修改的content_id、version、modify_time、modifier_id、body。更新时检查当前版本号是否与历史版本一致,若不一致则回滚,避免并发冲突。tags)和内容-标签关联表(content_tag),实现多对多关系,避免tag_ids字符串的查询性能问题。body)建FULLTEXT索引,配置中文分词器(如MySQL的IK分词器),支持忽略停用词、短语搜索,提升搜索准确性。content_202401存储1月内容),避免热点表;跨库查询通过Redis缓存热门内容,减少JOIN操作。类比:内容表是“内容仓库”,版本表是“仓库的版本日志”,标签表是“标签库”,关联表是“标签贴纸”,分库分表是“仓库按时间分成月度房间”,全文索引是“仓库的电子标签,能搜索内容里的关键词”。
3) 【对比与适用场景】
| 索引类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 主键索引 | 表的唯一标识,自增ID | 唯一、唯一索引,查询效率高 | 主键字段 | 不能重复 |
| 唯一索引 | 字段唯一,如标题 | 防止数据重复,加速唯一性检查 | 标题、用户名 | 不能有重复值 |
| 普通索引 | 加速查询,非唯一 | 提高查询速度,如按时间排序 | 创建时间、分类ID | 多个索引占用存储空间 |
| 全文索引 | 支持文本内容全文搜索 | 提升搜索效率,匹配关键词 | 正文内容搜索 | 需数据库支持(如MySQL的FULLTEXT) |
| 策略 | 定义 | 适用场景 | 注意点 |
|---|---|---|---|
| 垂直分库 | 按业务模块拆分表(如内容表、用户表分库) | 业务模块多,单库连接数限制 | 需跨库查询,数据一致性处理(事务) |
| 水平分表 | 按数据量或时间分片(如按内容ID范围、按月分表) | 数据量巨大,单表数据量超限(如内容表单表超1亿行) | 分片键选择(如时间、ID范围),分片规则复杂 |
4) 【示例】
-- 内容表(带版本管理)
CREATE TABLE content (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(20) NOT NULL, -- article(文章)、push(推文)
title VARCHAR(200) NOT NULL,
body TEXT NOT NULL,
category_id INT UNSIGNED,
status TINYINT DEFAULT 0, -- 0:草稿,1:发布
version INT DEFAULT 1, -- 版本号
create_time DATETIME NOT NULL,
update_time DATETIME,
UNIQUE KEY uq_title (title),
INDEX idx_create_time (create_time),
INDEX idx_category_id (category_id),
FULLTEXT KEY idx_body (body) -- 全文索引
);
-- 版本表(记录修改历史)
CREATE TABLE content_version (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
content_id BIGINT UNSIGNED NOT NULL,
version INT NOT NULL,
modify_time DATETIME NOT NULL,
modifier_id INT UNSIGNED NOT NULL,
body TEXT NOT NULL,
FOREIGN KEY (content_id) REFERENCES content(id) ON DELETE CASCADE
);
-- 分类表
CREATE TABLE category (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
UNIQUE KEY uq_category_name (name)
);
-- 标签表
CREATE TABLE tag (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
UNIQUE KEY uq_tag_name (name)
);
-- 内容-分类关联表
CREATE TABLE content_category (
content_id BIGINT UNSIGNED NOT NULL,
category_id INT UNSIGNED NOT NULL,
PRIMARY KEY (content_id, category_id),
FOREIGN KEY (content_id) REFERENCES content(id) ON DELETE CASCADE,
FOREIGN KEY (category_id) REFERENCES category(id) ON DELETE CASCADE
);
-- 内容-标签关联表
CREATE TABLE content_tag (
content_id BIGINT UNSIGNED NOT NULL,
tag_id INT UNSIGNED NOT NULL,
PRIMARY KEY (content_id, tag_id),
FOREIGN KEY (content_id) REFERENCES content(id) ON DELETE CASCADE,
FOREIGN KEY (tag_id) REFERENCES tag(id) ON DELETE CASCADE
);
-- 分库分表示例(按月分表)
-- 假设内容表按发布时间分表,如`content_202401`存储2024年1月内容
CREATE TABLE content_202401 (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(20) NOT NULL,
title VARCHAR(200) NOT NULL,
body TEXT NOT NULL,
category_id INT UNSIGNED,
status TINYINT DEFAULT 0,
version INT DEFAULT 1,
create_time DATETIME NOT NULL,
update_time DATETIME,
UNIQUE KEY uq_title (title),
INDEX idx_create_time (create_time),
INDEX idx_category_id (category_id),
FULLTEXT KEY idx_body (body)
);
5) 【面试口播版答案】
“面试官您好,我来设计一个管理官网文章、公众号推文的新媒体CMS数据库方案。核心是支持内容版本管理(通过乐观锁防并发冲突,版本表记录修改日志实现回滚),标签用关联表替代字符串存储,全文索引配置中文分词提升搜索体验,分库分表按发布时间(如月)分片避免热点,并引入Redis缓存优化跨库查询。具体来说,内容表存储标题、正文、状态,加版本字段;分类、标签通过中间表关联;索引包含主键、标题唯一、创建时间、正文全文;分库分表垂直分库(内容、用户分库),水平分表按月分表(如content_202401),跨库查询缓存热门内容。这样既能保证数据一致性,又能提升查询和写入性能,满足新媒体内容管理的需求。”
6) 【追问清单】
version字段,更新时检查当前版本号是否与历史版本一致,若不一致则回滚,避免冲突。MATCH...AGAINST语法,数据库自动用中文分词器(如IK)分词并匹配关键词,支持短语搜索。tag_id作为索引,查询时通过关联表快速匹配内容ID,避免字符串分割的效率问题。7) 【常见坑/雷区】
version字段,导致无法回滚内容,影响内容管理灵活性。