JavaRush /Java 博客 /Random-ZH /开发者面试:数据库问题分析

开发者面试:数据库问题分析

已在 Random-ZH 群组中发布
大家好!我们都在这里为一个目标而努力——成为Java 开发人员。也许成为专业人士道路上最重要的阶段是技术面试。通常,面试官会浏览主要话题,并提出几个问题。在这篇文章中,我们将讨论这样一个关键主题——数据库。让我们看看最常见的问题,并尝试在不深入研究材料的情况下回答它们,因为在这种情况下,这本书的体积对我们来说是不够的!那么,我们走吧。开发者面试:数据库问题分析 - 1

1.什么是数据库?它们又分为哪些类型呢?

DBMS 是什么意思?

开发者面试:数据库问题分析——2数据库 (DB)是一种有组织的结构,设计用于存储、更改和处理相关信息(主要是大容量信息)。换句话说,数据库是结构化数据存储。例如,电话簿。

数据库类型

  1. 关系数据库是数据的集合,它们之间具有预定义的关系。数据存储为一组由列和行组成的表。表存储有关数据库中表示的对象的信息。每个表列存储特定的数据类型,每个单元格存储一个属性值。
  2. 非关系系统(NoSQL)是为具有灵活模式的特定数据模型而设计的系统。换句话说,这些数据库不是以表格方案、行和列的形式存储数据,而是以其他格式存储数据。
您可以在本文中阅读有关非关系数据库的更多信息:NoSQL 开发人员指南数据库管理系统(DBMS)是一套软件,用户可以使用它创建数据库(DB)并对其执行各种操作:补充、更新、删除、选择等。DBMS保证数据的安全性、完整性、安全性存储并允许您授予对数据库管理的访问权限。例如,MySql 是一种 DBMS,它提供对关系数据库或非关系数据库的 MongoDB 的访问。

2.什么是标准化?标准化形式?标准化有多少种形式?说出前三个的名称。

规范化是在数据库中组织和构建数据的过程,它通过消除依赖关系的冗余和不一致来提供更大的数据库灵活性。 范式是表的一个属性,在规范化的背景下考虑,它在结构的简单性和正确性方面表征了表。范式被定义为表必须满足的一组要求。总共有六种范式,但在实践中只使用前三种:
  1. 第一范式:
    • 所有属性都是简单的(即原子且不可分割);
    • 所有数据都是标量(即正数);
    • 没有重复的行(为此,为每行创建一个主键)。
  2. 第二范式:
    • 满足第一范式的条件;
    • 每个非键属性都引用一个主键。
  3. 第三范式:
    • 满足第二正常组的条件;
    • 非键字段独立于其他非键字段:它们只能与主键关联。

3. 非规范化

非规范化是故意减少或违反数据库规范化的形式,通常是通过添加冗余数据来加快从数据库的读取速度。一般来说,这是一个与标准化相反的过程。发生这种情况是因为范式理论并不总是适用于实践。例如,非原子值并不总是“邪恶的”:有时甚至相反。在某些情况下,执行查询时,特别是处理大量信息时,需要额外的联接。这最终可以提高性能。用于分析的数据库通常会被非规范化,以加快查询执行速度。例如,您经常会对报表中的一些数据进行采样,其中非关键列彼此相关。您有意删除第三种形式的标准化,并将所有内容合并到一个表中以便于采样 - 这样您就不必对其他表进行额外的查询。

4. 索引

索引是与具有特定列的表或视图关联的一组排序值,可加速数据检索。也就是说,这是一种索引:就像电话簿中的字母一样,可以帮助我们按姓氏进行搜索。如果使用得当,此功能可以极大地提高处理大型数据库时的性能。或者你可以降低很多。为了加快搜索速度,这些关键字存储在平衡树结构中,通过该结构执行搜索。通常,需要在最常搜索的字段上输入索引。当您拥有至少 10,000 条记录时,您应该考虑创建索引。否则,您将看不到明显的结果,因为过早的优化是邪恶的。您可能会问,索引如何影响系统性能?当插入新数据或删除旧数据时,平衡树结构将重新计算。实际上,数据和索引越多,需要统计的树就越多。想象一下这种情况:这张表上有大约 20,000 条记录和 7 个索引。即插入数据时,需要重新计算7棵树,每棵树有20000条记录。严格来说,对于经常增删数据的表,完全不建议使用索引。最后,我想指出的是,经常在其中找到值的列的索引null不会那么有效,因此不值得将它们添加到此类列中。

SQL中聚集索引和非聚集索引有什么区别?

聚类:

  • 提供所选字段的物理顺序;
  • 如果一个表有聚集索引,则称其为聚集索引;
  • 每个表不需要超过一个索引;
  • 在MySQL中,聚集索引不是由用户显式指定的,因为如果你没有在表上定义主键,MySQL会找到UNIQUE所有键列所在的第一个索引NOT NULL,而InnoDB将其用作聚集索引。

非集群:

  • 单个表上最多可以有 999 个非聚集索引;
  • 包含指向表中包含实际数据的行的指针;
  • 不提供实物订单;
  • 对于非聚集索引来说,数据是有序的,有单独的表,即索引所在的一列一张表,因此,当请求不属于给定字段的数据时,会首先在该字段上进行查询。该表中的字段,然后才针对原始表中的行进行附加查询。
创建非聚集索引:
CREATE INDEX index_name ON table_name(column_name)

6. 什么是综合指数?

复合索引- 通过同时发送到多个列来构建。换句话说,它是一个由多个列组成的复杂索引。当一个查询中出现多于一列时,将使用此类索引。创建复合索引:
CREATE INDEX index_name ON table_name(first_column_name, second_column_name, third_column_name)
通常,当多列中的数据在逻辑上相关时使用这些索引。

7. 什么是覆盖索引?唯一索引?

覆盖索引是一种足以回答查询而无需访问表本身的索引。使用这个索引,你可以得到整行数据,但实际上这是根本没有必要的。因为您不必直接访问源表并且可以仅使用索引来回答,所以使用覆盖索引会稍微快一些。同时,不要忘记列越多,索引本身就会变得越麻烦、越慢。所以你不应该滥用这个。上面我们讲了聚集索引和非聚集索引,它们可以是唯一的。这意味着没有两个字段具有相同的索引键值。否则,索引将不是唯一的,因为多行可能包含相同的值。创建唯一非聚集索引的示例:
CREATE UNIQUE INDEX index_name ON table_name(column_name)

8.什么是主键

主键是表中的一个字段,用于标识数据库表中的每一行。一张表中只能有一个这样的字段,并且所有值必须是唯一的。没有提醒你什么吗?开发者面试:数据库问题分析 - 3毕竟,主键只不过是一个唯一的聚集索引。通常,主键是在创建表时创建的:
CREATE TABLE table_name(
column_name int PRIMARY KEY,..)
限制将自动添加到此列 - NOT NULL。您还可以为已创建的表设置键:
ALTER TABLE table_name ADD PRIMARY KEY (column_name);
如果按照上述方式添加主键,则会检查指定为主键 ( column_name) 的字段的值,以确保它们不包含空值(还会添加约束 - NOT NULL)。

什么是外键?

外键是为提供表之间的关系而创建的属性。通常,外键设置在子表中的列上,并指向主表中的列之一。可以在创建表时指定为:
CREATE TABLE table_name{
column_name int,..
FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name) }
所以创建表后:
ALTER TABLE table_name
ADD FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name));
您可以在操作外键引用的字段时设置外键的行为。操作可以有以下ON DELETE类型ON UPDATE:可能的行为选项:
  • CASCADE— 使用此属性,当主表中删除或更改相关行时,从属表中的行将自动删除或更改;
  • SET NULL— 使用此属性,当从主表中删除或更新相关行时,NULL将设置外键列的值;
  • NO ACTION— 如果从属表中存在相关行,则拒绝尝试删除或更改主表中的行;
  • RESTRICT- 相当于NO ACTION;
  • SET DEFAULT- 使用此属性,当从主表中删除或更新相关行时,将设置外键列的默认值(如果有)。
使用示例:
CREATE TABLE table_name{
column_name int,..
FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name) ON UPDATE CASCADE ON DELETE CASCADE }
ON DELETE如果和的行为 未显式设置ON UPDATE,则行为将设置为RESTRICT

10.表之间的连接类型(Join)

表之间的连接是基于公共数据(字段)提供的。这是使用 运算符 来实现的JOIN,该运算符将一个表中的行与另一个表中的行进行匹配。完成映射后,两个表的列是相邻的,尽管它们可以从单独的表中获取。如果我们有三个表的公共字段,我们可以将它们的数据显示为一张公共表。但是,值得考虑的是,连接的表越少,查询运行的速度就越快。所以,类型JOIN
  • INNER JOIN- 仅显示第一个表中与第二个表中的某些数据对应的那些数据的连接。其余的都下降。开发者面试:数据库问题分析——4
  • LEFT JOIN- 显示第一个表中的所有数据以及第二个表中的相应数据(如果有)的连接。如果没有对应的数据,则第二个表的数据字段将为空。开发者访谈:数据库问题分析 - 5
  • RIGHT JOIN- 显示第二个表中的所有数据以及第一个表中的相应数据(如果有)的连接。如果没有对应的数据,则第一个表中的数据字段将为空。开发者面试:数据库问题分析——6
  • FULL JOIN- 显示第一个和第二个表中的所有数据的连接。如果另一个表中没有相关数据,则该数据的字段将为空。开发者访谈:数据库问题分析 - 7
  • CROSS JOIN- 交叉联接,其中第一个表的每一行都联接到第二个表的每一行(每个到每个)。也就是说,如果两个表各有 3 行,那么在这次连接之后我们将得到 9 行的结果。开发者面试:数据库问题分析 - 8
例子Join(inner)
SELECT *
FROM first_table
INNER JOIN second_table ON first_table.some_column = second_table.some_column

11.什么是数据库中的 ACID 属性?

A - 原子性,确保没有事务部分提交给系统。要么执行其所有子操作,要么不执行。例如,将钱从银行转移到另一个帐户涉及两个操作:
  1. 将钱转入银行账户。
  2. 将资金从银行帐户转移到特定帐户。
但任何事情都有可能发生。例如,他们会去银行,然后会发生一些错误,并且第二个操作将无法完成。反之亦然:仅执行第二个操作。因此,这些操作是在一笔交易中执行的,其结果要么全部,要么全无。 C - 一致性:每笔成功的交易始终只记录可解析的结果。这可确保满足所有限制(例如NOT NULL),否则事务将回滚。 和 - 隔离:在事务执行期间,并行事务不应影响其结果。这使我们能够向所有人隐藏非最终数据状态。实际上,这就是为什么不成功的交易不会破坏任何东西。稍微低一点我们就会熟悉事务隔离级别。 D - 持久性:如果事务完成,那么您可以确定它所做的更改不会由于某些故障而被取消。

12. 事务隔离级别

每个隔离级别允许/禁止某些操作(机会):
  • 幻读- 在同一事务内,相同的数据请求给出不同的结果,这是由于另一个(并行)事务添加数据而发生的。
  • 非重复读取- 在同一事务内,相同的数据请求给出不同的结果,这是由于另一个(并行)事务更改或删除数据而发生的。
  • “脏”读——读取由事务添加或更改的数据,随后不会回滚;
  • 丢失更新- 当不同事务同时更改同一数据块时,除了最后一个之外的所有更改都会丢失(类似于多线程中的“竞争条件”)。
为了方便起见,我们在表中考虑隔离级别及其功能:
绝缘等级 幻读 不重复阅读 “脏”读 丢失更新
可串行化 + + + +
可重复读取 - + + +
已提交读 - - + +
READ_UNCOMMITTED - - - +

13.什么是SQL注入?

SQL注入GET是黑客攻击网站的方法之一,其本质是通过查询或Cookies将一些SQL代码注入到数据中POST。如果网站执行此类注入,则有可能获得对数据库的访问权限并破解应用程序。例如,我们知道某个变量的名称。让我们column_name用 type来说boolean。如果系统容易受到注入,我们可以添加OR column_name=true然后写入数据库中我们需要的所有内容。OR将创建一个 OR 条件,并且它后面的表达式将始终是true,这将带我们走得更远。由于对 SQL 查询中使用的传入数据处理不当,可能会出现 SQL 注入等网站攻击。使用JDBC连接到数据库时,您可以使用各种Statements. 为了提高安全性,有必要使用PreparedStatement而不是通常的Statement,因为使用时,Statement查询字符串和值只是简单地添加在一起,使得注入成为可能。反过来,有PreparedStatement一个特定的请求模板,数据插入其中,并反映引号。因此,SQL 注入将仅被视为某个字段的字符串表示形式。为了防止 SQL 注入,您可以使用基于正则表达式的检查(您可以在本文中阅读有关正则表达式的更多信息)。Собеседование разработчика: разбор вопросов по базам данных - 9另一种选择是对传入参数的字符数设置限制:例如,如果您应该接收不超过 9999 的数字,则限制为四个传入字符即可。它将降低使用 SQL 注入进行黑客攻击的风险。您可以从文章《Java 安全性:最佳实践》中了解有关 Java 安全性的更多信息。

14.什么是存储过程?存储函数?扳机?

SQL中的存储过程是数据库中的一个实体,是一组一次性编译并存储在服务器上的SQL指令。简而言之,这类似于 Java 中的方法。存储过程可以对数据执行操作,包括普通查询和一些普通查询无法执行的操作。过程是一个 SQL 实体,创建一次,然后通过传递参数进行调用。这种方法的优点是这些指令可以多次重复使用。存储过程可提高性能、增强编程能力并支持数据安全功能。让我们考虑创建一个过程:
CREATE PROCEDURE procedure_name (first_param some_type, second_param some_type..)
 begin
……...
 end
调用过程:
CALL procedure_name (first_param, second_param…..);
存储函数是存储过程的一种。函数之间的区别在于它始终仅返回单个值,而过程始终返回一组值。存储过程不能与常规 SQL 混合,而存储函数可以 - 这就是它的优点。另一方面,存储函数比过程有更多的限制。创建存储函数:
CREATE FUNCTION function_name (first_param, second_param…..)
RETURNS some_type
 begin
……...
RETURN some_value;
end
调用存储的函数:
SELECT function_name(first_param, second_param…..);
触发器是另一种类型的存储过程,它不由用户直接调用,而是在数据修改时激活。也就是说,当满足某些条件时,例如 、INSERTDELETE、 或UPDATE给定表的某一列中的数据,该过程被激活。使用关键字BEFORE(触发器在关联事件之前触发)或AFTER(事件之后)确定何时触发触发器。
CREATE TRIGGER trigger_name
ON table_name
AFTER INSERT
 begin
……...
 end

15. 练习

尽管如此,面试中最常见的 SQL 问题是练习 - 解决问题。试图猜测你会遇到哪些任务是没有意义的,因为一切都取决于对方想象力的复杂程度。因此,唯一可行的选择是更好地处理不同复杂度的 SQL 查询。sql-ex.ru可以作为练习各种任务的资源。在完成前 20 个任务之后,对话者就很难用任何 SQL 任务来吓唬您了。Собеседование разработчика: разбор вопросов по базам данных - 11今天就到这里了:希望读完这篇文章后,有关数据库的问题不会造成任何困难或问题。感谢您的关注,再次见到您!
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION