1. 数据库基础
-
数据库(Database): 数据库是一个用于存储、管理数据的系统。它可以有效地支持数据的存取、更新、删除和查询操作。常见的数据库系统有:MySQL、PostgreSQL、Oracle、SQL Server等。
-
关系数据库(RDBMS): 关系数据库管理系统通过表格结构来组织数据,并且使用SQL(结构化查询语言)进行操作。常见的关系型数据库管理系统包括MySQL、PostgreSQL、Oracle和SQL Server等。
-
非关系型数据库(NoSQL): 相较于传统的关系型数据库,非关系型数据库采用不同的数据存储方式,如键值对、文档、列族或图形结构。常见的NoSQL数据库有MongoDB、Redis、Cassandra、CouchDB等。
2. 数据库设计基本概念
-
数据表(Table): 数据表是存储数据的基本单元。每张表有若干列(字段),每列对应一种数据类型,每行代表一个数据实体。
-
主键(Primary Key): 主键是表中用于唯一标识每一行数据的列或列的组合。主键的值不能重复,且不能为NULL。
-
外键(Foreign Key): 外键是指一张表中的某一列(或列的组合),该列的值与另一张表的主键或唯一键的值相匹配,用于建立两表之间的关联。
-
索引(Index): 索引是为了提高查询效率而创建的数据结构。索引通常建立在一个或多个列上,它可以加速查询速度,但是会在数据插入、更新、删除时带来额外的开销。
常用的SQL语句
1. 查询操作(SELECT)
假设我们有一个公司员工管理系统,有两个表:employees
(员工表)和 departments
(部门表)。
表结构:
-
employees
表:-
id
(员工ID,主键) -
name
(员工姓名) -
age
(员工年龄) -
department_id
(员工所在部门ID)
-
-
departments
表:-
id
(部门ID,主键) -
department_name
(部门名称)
-
1.1 查询所有员工的基本信息
业务场景:我们需要查看公司所有员工的姓名和年龄。
SELECT name, age FROM employees;
-
这里我们从
employees
表中查询了所有员工的姓名和年龄信息。没有WHERE
子句,所以它会返回所有记录。
1.2 条件查询(WHERE)
业务场景:我们想要筛选出所有年龄大于 30 岁的员工。
SELECT name, age FROM employees WHERE age > 30;
-
WHERE
子句指定了一个条件,只返回那些符合age > 30
条件的员工。
1.3 排序查询(ORDER BY)
业务场景:我们希望查询所有员工的姓名和年龄,但按照年龄从大到小的顺序排列。
SELECT name, age FROM employees ORDER BY age DESC;
-
ORDER BY age DESC
表示我们希望按照age
字段的降序来排列员工。如果你想要按升序排列(从小到大),可以使用ASC
(默认就是ASC
)。
1.4 联接查询(INNER JOIN)
业务场景:我们想要查看每个员工的姓名和他所在部门的名称。
SELECT e.name, d.department_name FROM employees e INNER JOIN departments d ON e.department_id = d.id;
-
INNER JOIN
会把employees
表和departments
表根据department_id
和id
这两个字段的值匹配起来,返回两个表中匹配的记录。
1.5 左联接查询(LEFT JOIN)
业务场景:我们希望查看所有员工的姓名和他们的部门名称,但即使某些员工没有部门,也要在查询结果中显示出来。
SELECT e.name, d.department_name FROM employees e LEFT JOIN departments d ON e.department_id = d.id;
-
LEFT JOIN
会返回左表(employees
)中的所有记录,并且如果右表(departments
)有匹配的记录,就把对应的部门名称返回。如果右表没有匹配,部门名称字段就会显示为NULL
。
2. 数据操作
2.1 插入数据(INSERT INTO)
业务场景:公司有一个新员工加入,需要将他的基本信息插入到 employees
表中。
INSERT INTO employees (name, age, department_id) VALUES ('Alice', 28, 2);
-
这条 SQL 语句将一个新员工的姓名、年龄、部门ID 插入到
employees
表中。假设department_id = 2
对应的是“财务部”,所以这个员工被分配到了财务部门。
2.2 更新数据(UPDATE)
业务场景:Alice 在公司工作了 1 年,升职加薪了。她的年龄需要更新为 29。
UPDATE employees SET age = 29 WHERE name = 'Alice';
-
这里使用
UPDATE
语句修改了员工 Alice 的年龄。只有符合name = 'Alice'
条件的员工记录会被更新。
2.3 删除数据(DELETE)
业务场景:Alice 离职了,我们需要将她的记录从员工表中删除。
DELETE FROM employees WHERE name = 'Alice';
-
DELETE
语句删除了name
为Alice
的员工记录。如果WHERE
子句没有指定条件,所有记录都会被删除。
3. 数据库表结构操作
3.1 创建表(CREATE TABLE)
业务场景:我们要创建一个新的表 projects
来存储项目相关信息。
CREATE TABLE projects ( id INT PRIMARY KEY, project_name VARCHAR(100), start_date DATE, end_date DATE, budget DECIMAL(10, 2) );
-
该语句创建了一个新的
projects
表,包含项目ID(主键)、项目名称、开始日期、结束日期和预算。 -
DECIMAL(10, 2)
表示预算字段可以存储最多10位数字,且其中2位是小数。
3.2 修改表(ALTER TABLE)
业务场景:我们需要为 projects
表添加一个新的字段 status
来表示项目的状态。
ALTER TABLE projects ADD status VARCHAR(20);
-
ALTER TABLE
语句用于修改现有表结构。在这个例子中,我们向projects
表添加了一个新的status
列,用于存储项目的状态(如“进行中”或“已完成”)。
3.3 删除表(DROP TABLE)
业务场景:项目表 projects
已不再需要,我们要从数据库中完全删除它。
DROP TABLE projects;
-
DROP TABLE
语句将删除整个projects
表以及表中所有的数据。请小心使用,因为这个操作是不可恢复的。
4. 高级查询与优化
4.1 使用聚合函数(COUNT, AVG, SUM)
业务场景:我们想要统计每个部门的员工人数,并计算每个部门的平均年龄。
SELECT department_id, COUNT(*) AS employee_count, AVG(age) AS avg_age FROM employees GROUP BY department_id;
-
COUNT(*)
用于计算每个部门的员工数。 -
AVG(age)
用于计算每个部门的员工的平均年龄。 -
GROUP BY department_id
将员工按照部门进行分组。
4.2 使用 DISTINCT
去重
业务场景:我们想要查看所有不同的部门ID,而不是重复的部门ID。
SELECT DISTINCT department_id FROM employees;
-
DISTINCT
用于去除重复的记录。如果多个员工在同一个部门,那么查询结果中只会返回该部门ID一次。
4.3 使用 UNION
合并结果
业务场景:我们希望列出所有员工的姓名以及所有合同工的姓名(两个表的数据),并且去除重复的姓名。
SELECT name FROM employees UNION SELECT name FROM contractors;
-
UNION
用于合并两个查询的结果,自动去除重复项。这里它合并了employees
表和contractors
表的姓名数据。
4. 常见数据库框架
-
ORM框架(Object Relational Mapping): ORM是对象关系映射的简称,它可以使开发人员操作数据库时,直接使用对象而不是SQL语句进行操作。常见的ORM框架有:
-
Hibernate(Java)
-
Django ORM(Python)
-
Entity Framework(.NET)
-
SQLAlchemy(Python)
-
-
MyBatis(Java):MyBatis 是一个支持定制化 SQL、存储过程和高级映射的持久层框架,它与Hibernate不同,它需要开发者手写SQL语句。
-
Spring Data JPA(Java):基于JPA的Spring数据访问框架,简化数据库访问操作,并与Spring框架无缝集成。
4. 常见面试题
4.1 SQL基础
-
如何提高查询性能?
-
使用索引、避免全表扫描、避免不必要的子查询。
-
通过优化
JOIN
操作,避免使用SELECT *
。
-
-
解释一下主键和外键的区别?
-
主键:是一个表中唯一标识记录的列,不能有重复值且不能为空。
-
外键:是另一个表中引用主键的列,用于确保数据的完整性和关联性。
-
-
什么是事务?事务的ACID特性是什么?
-
事务(Transaction)是一个逻辑上完整的工作单元。
-
ACID特性:
-
Atomicity(原子性):事务内的所有操作要么全部成功,要么全部失败。
-
Consistency(一致性):事务完成后,数据库从一个一致性状态变到另一个一致性状态。
-
Isolation(隔离性):多个事务并发执行时,彼此独立,互不干扰。
-
Durability(持久性):事务一旦提交,其结果是永久性的。
-
-
4.2 SQL高级
-
解释JOIN的不同类型及其应用场景?
-
INNER JOIN:返回两个表中满足条件的记录。
-
LEFT JOIN:返回左表所有记录和右表满足条件的记录。
-
RIGHT JOIN:返回右表所有记录和左表满足条件的记录。
-
FULL OUTER JOIN:返回左表和右表所有记录,若没有匹配则返回NULL。
-
-
如何实现数据库的冗余设计?
-
通过增加冗余表或者缓存来提高读取性能。
-
应用场景:大规模查询时,减少数据库访问次数。
-
4.3 数据库设计
-
什么是数据库范式?
-
数据库范式是用于设计关系型数据库结构的规则,旨在消除数据冗余和避免数据异常。
-
-
如何设计一个规范化的数据库?
-
分析需求,确定实体和它们之间的关系,按照范式进行设计。
-
4.4 性能调优
-
如何优化MySQL查询性能?
-
使用适当的索引、避免在查询中使用
SELECT *
、减少复杂的子查询、避免使用OR
条件。
-
-
数据库的死锁问题如何解决?
-
通过调整事务的执行顺序、使用适当的锁级别或事务隔离级别来避免死锁。
-