为什么 DBMS 和 SQL 对后端开发者如此重要?
数据库管理系统 (DBMS) 和结构化查询语言 (SQL) 构成了几乎所有现代应用的核心。作为一名后端开发者,设计、查询和优化数据库的能力直接影响到系统的性能、可扩展性和可靠性。在技术面试中,公司期望后端工程师对 DBMS 概念有深刻理解,并能够编写高效的 SQL 查询。
本文将深入探讨后端开发者面试中常见的 DBMS 和 SQL 问题。从基本概念(如规范化和索引)到实操技能(如复杂联接和查询优化),我们将涵盖帮助你取得成功所需的一切内容。
如果你正在关注我的面试准备系列,这篇文章是对之前主题的补充,例如 数据库基础、数据库高级、数据库设计 和 数据库超负荷。这些资源共同构建了成为面试准备高手的全面指南。
让我们开始吧!
常见问题解答
1. DBMS 和 RDBMS 的区别是什么?
- 答案:
- DBMS(数据库管理系统): 一种用于数据存储、管理和检索的软件系统,不一定强制执行数据间的关系(如文件系统)。
- RDBMS(关系型数据库管理系统): DBMS 的一种,通过表(关系)存储数据,并通过主键和外键定义表之间的关系,确保数据一致性。示例:MySQL、PostgreSQL。
2. 什么是 DBMS,它有哪些优点?
- 答案:
DBMS 是一个用于创建、管理和查询数据库的软件系统。- 优点:
- 集中化数据管理。
- 最小化数据冗余。
- 支持并发访问。
- 强制执行数据完整性和安全性。
- 优点:
3. 什么是 DDL、DML、DCL 和 TCL?
- 答案:
这些是 SQL 命令的类别:- DDL(数据定义语言): 定义数据库的结构。例如:
CREATE、ALTER、DROP。 - DML(数据操作语言): 操作数据。例如:
SELECT、INSERT、UPDATE、DELETE。 - DCL(数据控制语言): 管理权限。例如:
GRANT、REVOKE。 - TCL(事务控制语言): 管理事务。例如:
COMMIT、ROLLBACK、SAVEPOINT。
- DDL(数据定义语言): 定义数据库的结构。例如:
4. 什么是查询优化,为什么重要?
- 答案:
查询优化是提高 SQL 查询效率以减少执行时间和资源使用的过程,确保数据库引擎选择最优的查询执行计划。- 重要性: 它提升了系统性能,确保了资源利用率,并高效处理大数据集。
5. 在数据库中,NULL、空格和 0 有什么区别?
- 答案:
- NULL: 表示缺失或未定义的数据,指示值的缺失。
- 空格(' '): 表示有效值,通常是一个空字符串。
- 0: 一个数值,与 NULL 或空格不同。
6. 什么是聚合和原子性?
- 答案:
- 聚合(Aggregation): 使用诸如
SUM()、AVG()和COUNT()等函数汇总数据,常用于GROUP BY查询。 - 原子性(Atomicity): 数据库事务的属性之一,确保事务中的所有操作要么全部成功,要么完全回滚。
- 聚合(Aggregation): 使用诸如
7. 数据库系统的抽象级别有哪些?
- 答案:
- 物理层(Physical Level): 描述数据如何在物理上存储(如文件、索引)。
- 逻辑层(Logical Level): 定义数据的结构和关系(如模式、表)。
- 视图层(View Level): 为用户提供数据的自定义视图,隐藏实现细节。
8. 什么是数据库中的实体-关系 (ER) 模型?
- 答案:
ER 模型是一种高层次的概念框架,用于设计数据库。它表示实体(对象)、属性(实体的特性)和关系(实体间的关联)。这有助于在数据库实现之前创建清晰的模式。
9. 数据库中的关系类型有哪些?
- 答案:
- 一对一(One-to-One): 一个表中的每条记录仅与另一个表中的一条记录相关联。例如:一个人和他们的护照。
- 一对多(One-to-Many): 一个表中的一条记录与另一个表中的多条记录相关联。例如:一个老师和他们的学生。
- 多对多(Many-to-Many): 一个表中的多条记录与另一个表中的多条记录相关联。例如:学生和课程。
10. 什么是数据库中的并发控制?
- 答案:
并发控制确保在多个用户或进程同时访问数据库时,数据库的正确性和一致性。它防止以下问题:- 脏读(Dirty Reads): 读取未提交的数据。
- 更新丢失(Lost Updates): 覆盖来自并发事务的更新。
- 死锁(Deadlocks): 两个事务无限期地相互等待。
常见技术包括锁、时间戳和乐观并发控制。
11. 什么是数据库中的 ACID 属性?
- 答案:
ACID 属性确保数据库中的事务可靠:- 原子性(Atomicity): 事务是“全有或全无”的,要么所有操作成功,要么不应用任何操作。
- 一致性(Consistency): 事务将数据库从一个有效状态带到另一个有效状态,同时保持完整性约束。
- 隔离性(Isolation): 并发事务不会互相干扰。
- 持久性(Durability): 一旦事务提交,其变化是永久的,即使发生故障也不受影响。
12. 什么是规范化,为什么重要?
- 答案:
规范化是组织数据库中数据的过程,旨在减少冗余并提高数据完整性。- 重要性:
- 最小化重复数据。
- 防止插入、更新或删除操作中的异常情况。
- 优化存储并确保更好的数据一致性。
- 重要性:
13. 数据库中的各种键有哪些?
- 答案:
- 主键(Primary Key): 唯一标识表中的一条记录。
- 候选键(Candidate Key): 任何可以作为主键的列。
- 外键(Foreign Key): 通过引用另一个表的主键来连接两个表。
- 复合键(Composite Key): 由两个或多个列组合而成,唯一标识记录。
- 唯一键(Unique Key): 确保列中的所有值是唯一的。
14. 什么是相关子查询,它是如何工作的?
- 答案:
相关子查询是依赖于外部查询的值的子查询。它会对外部查询处理的每一行重复执行。-
示例:
SELECT e1.name FROM employees e1 WHERE e1.salary > (SELECT AVG(e2.salary) FROM employees e2 WHERE e2.department_id = e1.department_id);在这里,子查询依赖于外部查询中的
department_id。
-
15. 什么是数据库分区?
- 答案:
分区是将大表划分为更小、更易管理的部分的过程,同时保持其为一个逻辑表。- 类型:
- 水平分区(Horizontal Partitioning): 按行划分分区。
- 垂直分区(Vertical Partitioning): 按列划分分区。
- 优点: 提高性能、简化管理并加快查询速度。
- 类型:
16. 什么是数据库中的函数依赖和传递依赖?
- 答案:
- 函数依赖(Functional Dependency): 一种关系,其中一个属性唯一决定另一个属性。例如:如果
A → B,知道A意味着B是固定的。 - 传递依赖(Transitive Dependency): 一种依赖类型,其中
A → B且B → C推导出A → C。在第三范式 (3NF) 中应消除传递依赖以避免冗余。
- 函数依赖(Functional Dependency): 一种关系,其中一个属性唯一决定另一个属性。例如:如果
17. 什么是两层和三层数据库架构?
- 答案:
- 两层架构(Two-Tier Architecture): 客户端直接与数据库服务器通信。示例:桌面应用程序。
- 三层架构(Three-Tier Architecture): 在客户端和数据库服务器之间增加了一个中间层(应用程序服务器)。示例:Web 应用程序。
- 三层架构的优点: 更好的可扩展性、安全性和关注点分离。
18. 唯一键和主键的区别是什么?
- 答案:
- 主键:
- 唯一标识表中的每条记录。
- 每个表只能有一个主键。
- 不能包含 NULL 值。
- 唯一键:
- 确保列中的值是唯一的。
- 每个表可以有多个唯一键。
- 可以包含一个 NULL 值。
- 主键:
19. 什么是数据库中的检查点(Checkpoint)?
- 答案:
检查点是 DBMS 中的一种机制,用于将数据库的当前状态保存到磁盘。- 目的:
- 减少故障情况下的恢复时间。
- 标记事务日志中的一致状态。
- 确保已提交的事务写入磁盘。
- 目的:
20. 什么是数据库中的触发器和存储过程?
- 答案:
- 触发器(Trigger): 一种数据库对象,当发生特定事件(如
INSERT、UPDATE、DELETE)时自动执行预定义的操作。- 示例:在更新行后自动更新审计日志。
- 存储过程(Stored Procedure): 一组预编译的 SQL 语句,可以作为一个单元执行。
- 示例:用于计算和更新员工奖金的过程。
- 触发器(Trigger): 一种数据库对象,当发生特定事件(如
21. 什么是数据库中的哈希连接、归并连接和嵌套循环?
- 答案:
这些是用于从多个表中检索数据的连接算法:- 哈希连接(Hash Join):
- 为较小的数据集创建哈希表,并用较大的数据集进行查找。
- 对于大型无序数据集效率较高。
- 归并连接(Merge Join):
- 需要已排序的输入;通过按排序顺序合并数据集来匹配行。
- 适合已排序的数据或有索引的场景。
- 嵌套循环(Nested Loops):
- 对外表的每一行,检查内表中匹配的行。
- 适合小数据集,但对大数据集效率较低。
- 哈希连接(Hash Join):
22. 什么是数据库中的前馈更新、追溯更新和同时更新?
- 答案:
- 前馈更新(Proactive Update): 在关联事件发生之前应用更改。
- 示例:预先安排目录中的价格变更。
- 追溯更新(Retroactive Update): 在关联事件发生之后进行更新。
- 示例:修正已经处理的错误交易。
- 同时更新(Simultaneous Update): 同时进行的更改,通常需要并发控制以避免冲突。
- 示例:多个用户同时更新同一记录。
- 前馈更新(Proactive Update): 在关联事件发生之前应用更改。
23. 什么是索引,聚簇索引和非聚簇索引有什么区别?
- 答案:
- 索引(Index): 一种数据库结构,用于通过更快的数据检索来提高查询性能。
- 聚簇索引(Clustered Index):
- 根据索引键对表中的数据行进行排序和存储。
- 每个表只能有一个聚簇索引。
- 示例:主键索引。
- 非聚簇索引(Non-Clustered Index):
- 存储一个单独的结构,指向数据行。
- 每个表可以有多个非聚簇索引。
24. 数据库中的意图和扩展有什么区别?
- 答案:
- 意图(Intension): 数据库的模式或结构(如表设计、列定义),随时间保持不变。
- 扩展(Extension): 数据库中在特定时间存储的实际数据。随着数据的添加、修改或删除而变化。
25. 什么是游标,隐式游标和显式游标有何区别?
- 答案:
- 游标(Cursor): 一种数据库对象,用于逐行检索、操作和导航结果集。
- 隐式游标(Implicit Cursor): 由数据库自动创建,用于单个 SQL 查询。例如:在
SELECT语句中获取数据。 - 显式游标(Explicit Cursor): 由程序员显式创建和控制,用于复杂操作。需要显式的
OPEN、FETCH和CLOSE命令。
26. 什么是数据库中的特化和泛化?
- 答案:
- 特化(Specialization): 从一个通用实体中创建子实体的过程。
- 示例:从
Employee实体派生出Manager和Intern。
- 示例:从
- 泛化(Generalization): 将多个实体合并为一个通用实体的过程。
- 示例:将
Car和Bike实体合并为Vehicle实体。
- 示例:将
- 特化(Specialization): 从一个通用实体中创建子实体的过程。
27. 什么是数据库中的数据独立性?
- 答案:
数据独立性是指在修改数据库模式的一层时,不会影响其他层的能力。- 类型:
- 物理数据独立性(Physical Data Independence): 物理存储的更改不会影响逻辑模式。
- 逻辑数据独立性(Logical Data Independence): 逻辑模式的更改不会影响应用程序或视图层。
- 类型:
28. 数据库中的完整性规则是什么?
- 答案:
完整性规则确保数据的准确性和一致性:- 实体完整性(Entity Integrity): 确保每个表都有一个主键,且主键的任何部分不能为 NULL。
- 参照完整性(Referential Integrity): 确保表中的外键值与被引用表中的主键值匹配。
29. 数据库中的填充因子是什么?
- 答案:
填充因子是为数据库索引页中的数据存储分配的空间百分比。- 目的: 通过为将来的插入留出空间来优化性能,减少页分裂的需求。
- 示例:填充因子为 80% 表示每个页保留 20% 的空间用于增长。
30. 什么是数据库中的索引优化(Index Hunting)?
- 答案:
索引优化是指识别并创建最佳索引以提高查询性能的过程。- 步骤:
- 分析慢查询。
- 评估执行计划。
- 根据使用模式创建索引。
- 在部署前测试性能影响。
- 步骤:
31. 什么是网络型和层次型数据库模型?
- 答案:
- 网络型模型(Network Model): 数据以记录的形式通过链接(类似图)组织,支持多对多关系,使用指针连接。
- 示例:CODASYL 模型。
- 层次型模型(Hierarchical Model): 数据以树状结构组织,具有单一根节点和子记录,关系为一对多。
- 示例:IBM 的 IMS 系统。
- 网络型模型(Network Model): 数据以记录的形式通过链接(类似图)组织,支持多对多关系,使用指针连接。
32. 什么是数据库中的死锁?
- 答案:
死锁是指两个或多个事务无限期地等待彼此持有的资源,从而无法继续执行的情况。- 示例:
- 事务 A 持有锁 1 并等待锁 2,而事务 B 持有锁 2 并等待锁 1。
- 解决方法:
- 死锁预防(如资源排序)。
- 死锁检测(如超时机制)。
- 示例:
33. 什么是独占锁和共享锁?
- 答案:
- 独占锁(Exclusive Lock, X Lock): 阻止其他事务对资源的读取和写入访问。通常用于写操作。
- 共享锁(Shared Lock, S Lock): 允许多个事务读取资源,但阻止写入操作。通常用于读操作。
34. DROP、DELETE 和 TRUNCATE 有何区别?
- 答案:
- DROP: 完全从数据库中删除表及其结构。
- DELETE: 根据条件删除表中的特定行。操作可回滚。
- TRUNCATE: 删除表中的所有行,但保留其结构。操作不可回滚。
35. 什么是 SQL 中的子查询?
- 答案:
子查询是嵌套在另一个查询中的查询,可用于SELECT、INSERT、UPDATE或DELETE语句中。-
示例:
SELECT name FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
-
36. UNION 和 UNION ALL 有什么区别?
- 答案:
- UNION: 合并两个查询的结果集,并移除重复值。
- UNION ALL: 合并结果集,但不移除重复值,对于大数据集执行速度更快。
37. SQL 中的子句是什么?
- 答案:
子句是 SQL 查询的一部分,用于指定条件或操作。常见的子句有WHERE、HAVING、ORDER BY和GROUP BY。
38. HAVING 子句和 WHERE 子句有什么区别?
- 答案:
-
WHERE: 在分组之前过滤行,适用于原始数据。
-
HAVING: 在聚合之后过滤组,适用于聚合函数。
-
示例:
SELECT department, AVG(salary) FROM employees GROUP BY department HAVING AVG(salary) > 50000;
-
39. 什么是 SQL 中的模式匹配?
- 答案:
模式匹配用于通过LIKE操作符和通配符搜索符合特定模式的数据:-
通配符:
%:匹配零个或多个字符。_:匹配单个字符。
-
示例:
SELECT name FROM employees WHERE name LIKE 'J%';
-
40. 什么是 SQL 中的大小写转换?
- 答案:
大小写转换函数用于更改字符串中字母的大小写:-
UPPER(): 将文本转换为大写。
-
LOWER(): 将文本转换为小写。
-
INITCAP(): 将每个单词的首字母大写。
-
示例:
SELECT UPPER(name) FROM employees;
-
41. 什么是 SQL 中的连接?有哪些类型?
- 答案:
连接用于基于相关列组合来自多个表的数据:- 内连接(INNER JOIN): 返回两个表中匹配的行。
- 左连接(LEFT JOIN): 返回左表的所有行以及右表中匹配的行。
- 右连接(RIGHT JOIN): 返回右表的所有行以及左表中匹配的行。
- 全外连接(FULL OUTER JOIN): 返回两个表中匹配或不匹配的所有行。
- 交叉连接(CROSS JOIN): 返回两个表的笛卡尔积。
42. 什么是 SQL 中的视图?
- 答案:
视图是基于 SQL 查询结果的虚拟表,它不存储数据,而是提供简化复杂查询或保护数据访问的方式。-
示例:
CREATE VIEW employee_view AS SELECT name, salary FROM employees WHERE department = 'HR';
-