
为满足中证数据行政数据的高并发、强一致性需求,设计包含历史版本表、混合分库分表、B树索引优化及Seata分布式事务的数据库模型,通过结构化设计、索引、分库分表、缓存与事务控制,平衡查询与写性能,保障数据一致性。
employee_history),记录数据变更时间、操作人、原值/新值等字段,通过触发器自动捕获变更,支持审计与回滚。status)建索引,平衡查询与写性能;控制索引数量,减少索引维护成本。| 对比项 | 历史版本表(employee_history) | 原始表(employee) |
|---|---|---|
| 定义 | 记录数据变更的日志(原值、新值、时间、操作人) | 存储当前有效数据 |
| 特性 | 支持审计、回滚 | 数据实时性 |
| 使用场景 | 员工信息变更、合同状态变更 | 查询当前员工/合同信息 |
| 注意点 | 定期清理历史记录,避免存储膨胀 | 严格遵循3NF,减少冗余 |
| 策略类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 哈希分库 | 按分片键哈希(如部门ID) | 数据均匀分布,避免倾斜 | 员工表(按部门分库) | 需全局ID分配,分片键分布均匀 |
| 范围分表 | 按时间/范围分片(如合同号) | 便于按时间查询 | 合同表(按签订时间分表) | 分片键需考虑业务增长 |
| 索引类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| B树索引 | 树形结构,支持范围查询 | 顺序访问效率高,支持等值/范围 | 主键、常用查询字段(如员工ID、合同号) | 避免过度索引,影响写性能 |
| 哈希索引 | 哈希函数定位记录 | 查询速度快,仅支持等值 | 单字段精确匹配(如员工姓名) | 不支持范围查询,需谨慎使用 |
| 全文索引 | 文本内容搜索 | 支持模糊匹配 | 项目文档关键词检索 | 需全文搜索引擎支持 |
设计核心表及历史版本表,分库分表与索引设计:
员工表(employee)
CREATE TABLE employee (
id BIGINT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
dept_id BIGINT NOT NULL,
position VARCHAR(50),
hire_date DATE,
INDEX idx_dept_name (dept_id, name) -- 联合索引,按部门+姓名查询
);
合同表(contract)
CREATE TABLE contract (
id BIGINT PRIMARY KEY,
contract_no VARCHAR(20) UNIQUE NOT NULL,
employee_id BIGINT,
sign_date DATE,
status ENUM('有效','过期'),
INDEX idx_contract_no (contract_no), -- 唯一索引,按合同号查询
INDEX idx_emp_date (employee_id, sign_date) -- 联合索引,按员工+日期查询
);
历史版本表(员工变更日志)
CREATE TABLE employee_history (
history_id BIGINT PRIMARY KEY,
employee_id BIGINT NOT NULL,
field_name VARCHAR(50),
old_value VARCHAR(255),
new_value VARCHAR(255),
change_time DATETIME NOT NULL,
operator VARCHAR(50)
);
分库分表说明:
dept_id % 8哈希分库(8个库),避免部门数据集中;sign_date范围分表(如按年份分表),按时间维度扩展。面试官您好,针对中证数据行政数据的高并发、强一致性需求,我设计了一个数据库模型,核心是通过历史版本表、混合分库分表、B树索引优化及Seata分布式事务,平衡查询与写性能,保障数据一致性。
具体来说,我们为员工、合同、项目文档设计了主表,并增加了历史版本表,记录数据变更日志,支持审计追溯。比如员工信息变更时,历史版本表会记录原部门、新部门、变更时间等,便于回溯。分库分表方面,员工表按部门ID哈希分库(避免数据倾斜),合同表按合同号范围分表(按签订时间),使用全局ID生成器保证唯一性。索引设计上,优先选择B树索引,比如员工表用(部门ID+姓名)的联合索引,快速按部门查找员工;合同表用合同编号唯一索引,确保查询合同号时直接定位。对于高并发下的数据一致性,采用Seata分布式事务,比如签订合同时,先扣减员工合同数量再更新合同状态,保证原子性。同时,对热点数据(如常用员工信息、合同列表)使用Redis缓存,设置合理的TTL(如5分钟),减少数据库压力,并采用缓存预热策略,确保冷启动时数据可用。
问:历史版本表如何设计?如何保证变更日志的完整性和可追溯性?
答:历史版本表包含员工ID、字段名、旧值、新值、变更时间、操作人等字段,通过触发器在数据变更时自动记录,支持审计和回滚。
问:分库分表的具体分片键选择原则?如何避免数据倾斜?
答:员工表按部门ID哈希分库(部门ID分布均匀),合同表按合同号范围分表(按签订时间分片),结合全局ID生成器(如雪花算法),确保数据均匀分布。
问:索引选择时,如何平衡查询性能与写性能?对频繁更新的字段(如合同状态)如何处理?
答:优先使用B树索引,避免对频繁更新的字段(如status)建立索引,减少写时索引维护成本,同时控制索引数量,避免过度索引影响写性能。
问:分布式事务中,如何处理高并发下的锁竞争?事务隔离级别如何选择?
答:采用Seata的AT模式,结合乐观锁或悲观锁优化,事务隔离级别选择可重复读(REPEATABLE READ),避免幻读,同时通过锁粒度控制减少锁竞争。
问:缓存如何保证数据一致性?缓存过期时间如何设置?
答:采用读写分离+缓存预热,写操作先更新数据库,再更新缓存;读操作先查缓存,缓存未命中再查数据库,设置合理的TTL(如5分钟),确保数据最终一致性。