Java 面试中的数据库设计深度解析

news2025/6/4 17:56:11

🤟致敬读者

  • 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉

📘博主相关

  • 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息

文章目录

      • Java 面试中的数据库设计深度解析
        • 一、数据库设计核心原则
        • 二、表关系设计(Java 开发重点)
        • 三、高性能数据库设计策略
        • 四、数据一致性保障
        • 五、高频面试题精析
        • 六、数据库安全设计
        • 七、数据库设计评审 Checklist
      • 总结:Java 开发者数据库设计要点


📃文章前言

  • 🔷文章均为学习工作中整理的笔记。
  • 🔶如有错误请指正,共同学习进步。

Java 面试中的数据库设计深度解析

在这里插入图片描述

数据库设计是后端开发的核心能力,也是 Java 面试的高频考点。本文从范式理论到实战案例,全面解析数据库设计的关键知识点,包含代码示例和优化策略。


一、数据库设计核心原则
  1. 三范式 vs 反范式

    范式级别核心要求优点缺点
    第一范式字段原子性(不可再分)消除重复组增加表数量
    第二范式消除部分依赖(主键决定所有字段)减少数据冗余查询复杂度增加
    第三范式消除传递依赖(非主键字段独立)数据一致性高多表连接影响性能
    反范式化故意冗余字段提升查询性能更新异常风险

    实战选择

    • 金融系统 → 严格遵循三范式(强一致性)
    • 电商系统 → 适度反范式(如订单冗余商品名称)
  2. ER 建模方法

    CUSTOMER bigint id PK string name string email ORDER bigint id PK timestamp order_date bigint customer_id FK ORDER_ITEM PRODUCT places contains includes

二、表关系设计(Java 开发重点)
  1. 一对一关系
    场景:用户表与身份证表
    设计选择

    -- 方案1:主键共享(效率高)
    CREATE TABLE user (
      id BIGINT PRIMARY KEY,
      name VARCHAR(50)
    );
    
    CREATE TABLE id_card (
      user_id BIGINT PRIMARY KEY, -- 同时作为主键和外键
      card_number CHAR(18),
      FOREIGN KEY (user_id) REFERENCES user(id)
    );
    
    -- 方案2:外键唯一约束(更灵活)
    CREATE TABLE id_card (
      id BIGINT PRIMARY KEY,
      user_id BIGINT UNIQUE, -- 唯一约束保证一对一
      card_number CHAR(18),
      FOREIGN KEY (user_id) REFERENCES user(id)
    );
    
  2. 一对多关系
    场景:部门与员工

    CREATE TABLE department (
      id BIGINT PRIMARY KEY,
      name VARCHAR(50)
    );
    
    CREATE TABLE employee (
      id BIGINT PRIMARY KEY,
      name VARCHAR(50),
      dept_id BIGINT,
      FOREIGN KEY (dept_id) REFERENCES department(id) -- 外键在多的一方
    );
    
    -- Java 实体映射(JPA)
    @Entity
    public class Department {
        @Id
        private Long id;
        
        @OneToMany(mappedBy = "department")
        private List<Employee> employees;
    }
    
  3. 多对多关系
    场景:学生与课程

    CREATE TABLE student (
      id BIGINT PRIMARY KEY,
      name VARCHAR(50)
    );
    
    CREATE TABLE course (
      id BIGINT PRIMARY KEY,
      title VARCHAR(100)
    );
    
    -- 关联表
    CREATE TABLE student_course (
      student_id BIGINT,
      course_id BIGINT,
      PRIMARY KEY (student_id, course_id),
      FOREIGN KEY (student_id) REFERENCES student(id),
      FOREIGN KEY (course_id) REFERENCES course(id)
    );
    
    -- Spring Data JPA 实现
    @Entity
    public class Student {
        @ManyToMany
        @JoinTable(
            name = "student_course",
            joinColumns = @JoinColumn(name = "student_id"),
            inverseJoinColumns = @JoinColumn(name = "course_id"))
        private Set<Course> courses;
    }
    

三、高性能数据库设计策略
  1. 分库分表设计
    垂直拆分

    -- 原用户表
    CREATE TABLE user (
      id BIGINT,
      name VARCHAR(50),
      bio TEXT, -- 大字段
      last_login DATETIME
    );
    
    -- 拆分后
    CREATE TABLE user_base (
      id BIGINT PRIMARY KEY,
      name VARCHAR(50),
      last_login DATETIME
    );
    
    CREATE TABLE user_profile (
      user_id BIGINT PRIMARY KEY,
      bio TEXT,
      FOREIGN KEY (user_id) REFERENCES user_base(id)
    );
    

    水平拆分(Sharding):

    // Sharding-JDBC 分片配置
    shardingRule:
      tables:
        orders:
          actualDataNodes: ds${0..1}.orders_${0..15} # 16个分片
          tableStrategy:
            inline:
              shardingColumn: order_id
              algorithmExpression: orders_${order_id % 16}
    
  2. 读写分离设计

    // Spring Boot 多数据源配置
    @Bean
    @Primary
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create()
            .url("jdbc:mysql://master:3306/db")
            .username("user")
            .password("pass")
            .build();
    }
    
    @Bean
    public DataSource replicaDataSource() {
        return DataSourceBuilder.create()
            .url("jdbc:mysql://replica:3306/db")
            .username("user")
            .password("pass")
            .build();
    }
    
    // 使用注解切换数据源
    @Transactional(readOnly = true) // 读操作走从库
    public User getUser(Long id) {
        return userRepository.findById(id);
    }
    

四、数据一致性保障
  1. ACID 事务实现

    @Transactional(rollbackFor = Exception.class)
    public void transferMoney(Long from, Long to, BigDecimal amount) {
        // 扣款
        accountRepository.debit(from, amount);
        
        // 模拟异常
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
            throw new RuntimeException("金额非法");
        }
        
        // 加款
        accountRepository.credit(to, amount);
    }
    
  2. 分布式事务方案

    方案原理适用场景
    2PC两阶段提交强一致性,低并发
    TCCTry-Confirm-Cancel高一致性要求
    Saga补偿事务长事务场景
    本地消息表异步消息+本地事务最终一致性,高并发

    Seata TCC 示例

    @LocalTCC
    public interface AccountService {
        @TwoPhaseBusinessAction(name = "deduct", commitMethod = "commit", rollbackMethod = "rollback")
        boolean deduct(BusinessActionContext context, 
                      @BusinessActionContextParameter(paramName = "userId") Long userId,
                      @BusinessActionContextParameter(paramName = "amount") BigDecimal amount);
        
        boolean commit(BusinessActionContext context);
        boolean rollback(BusinessActionContext context);
    }
    

五、高频面试题精析
  1. 如何设计电商系统的数据库?
    核心表

    USER ORDER ORDER_ITEM PRODUCT SKU CATEGORY places contains includes has belongs_to

    优化点

    • 订单表垂直拆分(基础表 + 扩展表)
    • 商品表增加冗余字段(销量、评价数)
    • 价格字段使用 DECIMAL(10,2) 避免精度丢失
  2. 大字段存储如何优化?

    • 方案1:拆分到单独表(如 product_descriptions
    • 方案2:使用文件存储(OSS)+ DB存路径
    • 方案3:NoSQL 存储(MongoDB)
  3. 软删除 vs 硬删除?

    -- 软删除设计
    ALTER TABLE user ADD is_deleted TINYINT DEFAULT 0;
    UPDATE user SET is_deleted = 1 WHERE id = 1001; -- 删除操作
    
    /* 优点:保留历史数据,支持恢复
       缺点:查询需过滤,索引效率降低 */
    

六、数据库安全设计
  1. 权限控制

    -- 最小权限原则
    CREATE USER 'app_user'@'%' IDENTIFIED BY 'password';
    GRANT SELECT, INSERT, UPDATE ON ecommerce.orders TO 'app_user'@'%';
    REVOKE DELETE ON ecommerce.* FROM 'app_user'@'%'; -- 禁止删除
    
  2. SQL 注入防护

    // 错误示范(拼接SQL)
    String sql = "SELECT * FROM users WHERE name = '" + name + "'";
    
    // 正确方式:预编译语句
    String sql = "SELECT * FROM users WHERE name = ?";
    PreparedStatement stmt = conn.prepareStatement(sql);
    stmt.setString(1, name);
    
  3. 数据加密

    // Java 字段级加密
    @Convert(converter = CryptoConverter.class)
    private String bankCardNo;
    
    public class CryptoConverter implements AttributeConverter<String, String> {
        public String convertToDatabaseColumn(String attribute) {
            return AES.encrypt(attribute, SECRET_KEY);
        }
        public String convertToEntityAttribute(String dbData) {
            return AES.decrypt(dbData, SECRET_KEY);
        }
    }
    

七、数据库设计评审 Checklist
  1. 结构合理性

    • 是否满足业务扩展需求?
    • 表字段是否遵循命名规范?
    • 多对多关系是否有关联表?
  2. 性能设计

    • 高频查询字段是否建立索引?
    • 是否避免 SELECT *
    • 大表是否设计分页查询?
  3. 安全合规

    • 敏感字段是否加密?
    • 是否禁用数据库管理员账号?
    • 审计日志是否开启?
  4. 可维护性

    • 是否有完善的注释?
    • 是否避免存储过程?
    • 变更是否有版本管理(Liquibase/Flyway)?

总结:Java 开发者数据库设计要点

  1. 设计原则

    “先满足业务,再优化性能;
    先保证正确性,再提升效率;
    先考虑稳定性,再追求扩展”

  2. 面试回答框架

    1. 分析业务场景(电商/社交/金融)
    2. 确定核心实体和关系
    3. 选择范式级别
    4. 设计表结构和索引
    5. 规划分库分表策略
    6. 设计数据一致性方案
    7. 制定安全策略
    
  3. 经典案例参考

    系统类型设计重点典型表数量
    电商系统订单分片、购物车优化50+
    社交系统好友关系图、动态流30+
    物联网系统时间序列数据存储100+

掌握这些数据库设计知识和实战技巧,你将在 Java 面试中游刃有余,同时为构建高可用、高性能的系统打下坚实基础。


📜文末寄语

  • 🟠关注我,获取更多内容。
  • 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
  • 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
  • 🔵​加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
  • 🟣点击下方名片获取更多内容🍭🍭🍭👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国内首发!具有GPU算力的AI扫描仪

奥普思凯重磅推出的具有GPU算力的扫描仪&#xff0c;是一款真正意义上的AI扫描仪&#xff0c;奥普思凯将嵌有OCR发票识别核心的高性能NPU算力棒与高速扫描仪相结合&#xff0c;实现软件硬件相结合&#xff0c;采用一体化外观设计&#xff0c;实现高速扫描、快速识别表单&#x…

【开发技巧指北】IDEA修改默认绑定Maven的仓库地址

【开发技巧指北】IDEA修改默认绑定Maven的仓库地址 Microsoft Windows 11 家庭中文版 IIntelliJ IDEA 2025.1.1.1 默认的IDEA是有自己捆绑的Maven的&#xff08;这是修改完毕的截图&#xff09; 修改默认的Maven配置&#xff0c;路径是IDEA安装路径下的plugins D:\Softwares\I…

【2025最新】Java图书借阅管理系统:从课程作业到实战应用的完整解决方案

【2025最新】Java图书借阅管理系统&#xff1a;从课程作业到实战应用的完整解决方案 目录 【2025最新】Java图书借阅管理系统&#xff1a;从课程作业到实战应用的完整解决方案**系统概述** **核心功能模块详解****1. 系统登录与权限控制****2. 借阅管理模块****3. 用户角色管理…

springcloud openfeign 请求报错 java.net.UnknownHostException:

现象 背景 项目内部服务之间使用openfeign通过eureka注册中心进行服务间调用&#xff0c;与外部通过http直接调用。外部调用某个业务方提供的接口需要证书校验&#xff0c;因对方未提供证书故设置了忽略证书校验代码如下 Configuration public class IgnoreHttpsSSLClient {B…

【harbor】--配置https

使用自建的 CA 证书来自签署和启用 HTTPS 通信。 &#xff08;1&#xff09;生成 CA认证 使用 OpenSSL 生成一个 2048位的私钥这是 自建 CA&#xff08;证书颁发机构&#xff09; 的私钥&#xff0c;后续会用它来签发证书。 # 1创建CA认证 cd 到harbor [rootlocalhost harbo…

OptiStruct实例:消声器前盖ERP分析(2)RADSND基础理论

13.2 Radiated Sound Output Analysis( RADSND ) RADSND 方法通过瑞利积分来求解结构对外的辐射噪声。其基本思路是分为两个阶段&#xff0c;如图 13-12 所示。 图13-12 结构辐射噪声计算示意图 第一阶段采用有限元方法&#xff0c;通过频响分析(模态叠加法、直接法)工况计算结…

barker-OFDM模糊函数原理及仿真

文章目录 前言一、巴克码序列二、barker-OFDM 信号1、OFDM 信号表达式2、模糊函数表达式 三、MATLAB 仿真1、MATLAB 核心源码2、仿真结果①、barker-OFDM 模糊函数②、barker-OFDM 距离分辨率③、barker-OFDM 速度分辨率④、barker-OFDM 等高线图 四、资源自取 前言 本文进行 …

3.RV1126-OPENCV 图像叠加

一.功能介绍 图像叠加&#xff1a;就是在一张图片上放上自己想要的图片&#xff0c;如LOGO&#xff0c;时间等。有点像之前提到的OSD原理一样。例如&#xff1a;下图一张图片&#xff0c;在左上角增加其他图片。 二.OPENCV中图像叠加常用的API 1. copyTo方法进行图像叠加 原理…

使用 HTML + JavaScript 实现一个日历任务管理系统

在现代快节奏的生活中&#xff0c;有效的时间管理变得越来越重要。本项目是一个基于 HTML 和 JavaScript 开发的日历任务管理系统&#xff0c;旨在为用户提供一个直观、便捷的时间管理工具。系统不仅能够清晰地展示当月日期&#xff0c;还支持事件的添加、编辑和删除操作&#…

车载诊断架构SOVD --- 车辆发现与建连

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

Notepad++找回自动暂存的文件

场景&#xff1a; 当你没有保存就退出Notepad&#xff0c;下次进来Notepad会自动把你上次编辑的内容显示出来&#xff0c;以便你继续编辑。除非你手动关掉当前页面&#xff0c;这样Notepad就会删除掉自动保存的内容。 问题&#xff1a; Notepad会将自动保存的文件地址,打开Note…

DL00924-基于深度学习YOLOv11的工程车辆目标检测含数据集

文末有代码完整出处 &#x1f697; 基于深度学习YOLOv11的工程车辆目标检测——引领智能识别新潮流&#xff01; &#x1f680; 随着人工智能技术的飞速发展&#xff0c; 目标检测 已经在各个领域取得了显著突破&#xff0c;尤其是在 工程车辆识别 这一关键技术上。今天&#…

Axure RP11安装、激活、汉化

一:注册码 Axure RP11.0.0.4122在2025-5-29日亲测有效: 49bb9513c40444b9bcc3ce49a7a022f9

自编码器Auto-encoder(李宏毅)

目录 编码器的概念&#xff1a; 为什么需要编码器&#xff1f; 编码器什么原理&#xff1f; 去噪自编码器: 自编码器的应用&#xff1a; 特征解耦 离散隐表征 编码器的概念&#xff1a; 重构&#xff1a;输入一张图片&#xff0c;通过编码器转化成向量&#xff0c;要求再…

数据结构之堆(topk问题、堆排序)

一、堆的初步认识 堆虽然是用数组存储数据的数据结构&#xff0c;但是它的底层却是另一种表现形式。 堆分为大堆和小堆&#xff0c;大堆是所有父亲大于孩子&#xff0c;小堆是所有孩子大于父亲。 通过分析我们能得出父子关系的计算公式&#xff0c;parent(child-1)/2&#xff…

SpringBoot使用ffmpeg实现视频压缩

ffmpeg简介 FFmpeg 是一个开源的跨平台多媒体处理工具集&#xff0c;用于录制、转换、编辑和流式传输音频和视频。它功能强大&#xff0c;支持几乎所有常见的音视频格式&#xff0c;是多媒体处理领域的核心工具之一。 官方文档&#xff1a;https://ffmpeg.org/documentation.h…

2025-05-31 Python深度学习9——网络模型的加载与保存

文章目录 1 使用现有网络2 修改网络结构2.1 添加新层2.2 替换现有层 3 保存网络模型3.1 完整保存3.2 参数保存&#xff08;推荐&#xff09; 4 加载网络模型4.1 加载完整模型文件4.2 加载参数文件 5 Checkpoint5.1 保存 Checkpoint5.2 加载 Checkpoint 本文环境&#xff1a; Py…

长安链起链调用合约时docker ps没有容器的原因

在调用这个命令的时候&#xff0c;发现并没有出现官方预期的合约容器&#xff0c;这是因为我们在起链的时候没有选择用docker的虚拟环境&#xff0c;实际上这不影响后续的调用&#xff0c;如果想要达到官方的效果那么你只需要在起链的时候输入yes即可&#xff0c;如图三所示

Appium+python自动化(七)- 认识Appium- 上

简介 经过前边的各项准备工作&#xff0c;终于才把appium搞定。 一、appium自我介绍 appium是一款开源的自动化测试工具&#xff0c;可以支持iOS和安卓平台上的原生的&#xff0c;基于移动浏览器的&#xff0c;混合的应用&#xff08;APP&#xff09;。 1、 使用appium进…

模块联邦:更快的微前端方式!

什么是模块联邦 在前端项目中&#xff0c;不同团队之间的业务模块可能有耦合&#xff0c;比如A团队的页面里有一个富文本模块&#xff08;组件&#xff09;&#xff0c;而B团队 的页面恰好也需要使用这个富文本模块。 传统模式下&#xff0c;B团队只能去抄A团队的代码&#x…