数据库 基础面试第一弹

1. SQL语句类型

1. DDL(Data Definition Language,数据定义语言):

DDL语句用于定义数据库对象(如表、索引、视图等)。常见的DDL语句包括:

  CREATE:用于创建数据库对象,如创建表、索引、视图等。

  ALTER:用于修改数据库对象的结构,如修改表的列、添加约束等。

  DROP:用于删除数据库对象,如删除表、索引、视图等。

  TRUNCATE:用于删除表中的所有数据,但保留表结构

DDL(数据定义语言)示例:

# 创建表
CREATE TABLE employees (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  age INT,
  salary DECIMAL(10, 2)
);

# 修改表结构
ALTER TABLE employees ADD COLUMN department VARCHAR(50);

DROP TABLE employees; #删除表

2. DML(Data Manipulation Language,数据操作语言):

DML语句用于对数据库中的数据进行操作(插入、更新、删除)。常见的DML语句包括:

  • SELECT:用于从数据库中查询数据。
  • INSERT:用于向表中插入新的数据。
  • UPDATE:用于更新表中的数据。
  • DELETE:用于删除表中的数据。

DML(数据操作语言)示例:

INSERT INTO employees (id, name, age, salary)
VALUES (1, 'John Doe', 30, 5000);  # 插入数据

UPDATE employees SET salary = 6000 WHERE id = 1; #更新数据

DELETE FROM employees
WHERE id = 1;  # 删除数据

3. DQL(Data Query Language,数据查询语言):

DQL语句用于从数据库中查询数据。DQL语句的核心是SELECT语句,可以使用SELECT语句查询满足特定条件的数据,并对结果进行排序、分组等处理

DQL(数据查询语言)示例:

SELECT * FROM employees; 

SELECT * FROM employees
WHERE age > 25;     # 查询特定条件的数据


SELECT name, salary FROM employees; # 查询特定列的数据

4. DCL(Data Control Language,数据控制语言)

DCL语句用于对数据库的访问权限进行管理。常见的DCL语句包括:

  • GRANT:用于授予用户访问权限。
  • REVOKE:用于撤销用户的访问权限。
  • DENY:用于拒绝用户的访问权限。

DCL(数据控制语言)示例:

GRANT SELECT, INSERT ON employees TO user1;  #授予用户访问权限

REVOKE SELECT, INSERT ON employees FROM user1; # 撤销用户的访问权限

DENY SELECT, INSERT ON employees TO user1; # 拒绝用户的访问权限

2. 索引作用,底层结构及常见类型

索引在数据库中起着重要的作用,它可以提高数据库的查询性能和数据的检索速度。索引是一种数据结构,用于快速定位和访问数据库中的特定数据。

作用:

  • 提高查询性能:通过使用索引,可以减少数据库查询的数据量,从而提高查询速度。
  • 加速数据检索:索引可以帮助数据库快速定位和访问满足特定条件的数据,减少数据的扫描时间。

底层结构:
数据库索引的底层结构可以有多种实现方式,常见的包括以下几种:

  1. B-树(B-Tree)索引:B-树是一种平衡的多路搜索树,它的特点是可以自动调整树的结构以适应数据的插入和删除操作。B-树索引常用于磁盘存储的数据库,因为它可以减少磁盘访问次数,提高查询效率。

  2. B+树(B+Tree)索引:B+树是在B-树的基础上进行优化的一种数据结构。它与B-树类似,但在叶子节点上存储了所有的关键字和对应的数据指针,这样可以加快范围查询和顺序访问的速度。B+树索引是大多数关系型数据库中最常用的索引类型。

  3. 哈希(Hash)索引:哈希索引使用哈希函数将关键字映射到一个固定长度的哈希值,然后将哈希值与数据的存储位置关联起来。哈希索引适用于等值查询,但不适用于范围查询或排序操作。

  4. 全文(Full-Text)索引:全文索引用于对文本内容进行搜索,它可以对文本字段中的关键词进行索引和检索,支持全文搜索和模糊匹配。

常见类型:
在常见的关系型数据库中,常用的索引类型包括:

    1. 主键索引(Primary Key Index):用于唯一标识表中的记录,保证主键的唯一性和索引的快速访问。

    2. 唯一索引(Unique Index):用于保证某个列或列组合的唯一性,可以加速唯一性检查。

    3. 聚集索引(Clustered Index):指定表的物理顺序,表中的记录按照聚集索引的顺序存储。

    4. 非聚集索引(Non-Clustered Index):不指定表的物理顺序,独立存储索引的数据结构。

    5. 复合索引(Composite Index):使用多个列组合作为索引的键,支持多个列的联合查询。

    6. 全文索引(Full-Text Index):用于全文搜索和模糊匹配的索引类型,支持对文本内容进行搜索。

3. 事务的特性

  1. 原子性(Atomicity):事务是一个原子操作单元,要么全部执行成功,要么全部失败回滚。原子性确保事务中的所有操作要么全都执行,要么全都不执行,不会出现部分操作成功而部分操作失败的情况。

  2. 一致性(Consistency):事务在执行之前和执行之后,数据库的完整性约束没有被破坏。一致性确保数据库从一个一致的状态转移到另一个一致的状态,它定义了数据在事务执行过程中的合法变化。

  3. 隔离性(Isolation):事务的执行是相互隔离的,一个事务的操作不会被其他并发事务所干扰。隔离性确保事务在并发执行时,每个事务的操作都像是在独立执行,避免了并发读写操作导致的数据不一致问题。

  4. 持久性(Durability):一旦事务提交,其所做的修改将永久保存在数据库中,即使系统发生故障或重启。持久性确保事务提交后的修改是永久性的,不会因为系统故障而丢失。

4. 事务的隔离级别

  1. 读未提交(Read Uncommitted):

    • 最低的隔离级别,事务中的未提交修改对其他事务都是可见的。
    • 可能导致脏读(Dirty Read),即读取到其他事务尚未提交的数据,可能是不一致的数据。
    • 存在幻读(Phantom Read),即在同一个事务中多次执行同样的查询,结果集不一致。
  2. 读已提交(Read Committed):

    • 事务只能读取到已经提交的数据,未提交的数据对其他事务不可见。
    • 避免了脏读的问题,但仍可能导致幻读。
    • 大多数常见数据库的默认隔离级别。
  3. 可重复读(Repeatable Read):

    • 保证了在同一事务中多次读取同一数据时,结果保持一致。
    • 读取的数据是在事务开始时确定的快照,即使其他事务对数据进行修改也不可见。
    • 避免了脏读和幻读的问题。
  4. 序列化(Serializable):

    • 最高的隔离级别,通过强制事务串行执行来避免并发问题。
    • 保证了事务之间的完全隔离,避免了脏读、幻读和不可重复读的问题。
    • 性能较差,一般情况下只在特殊需求下使用。

5. 事务并发引起的三大问题

  1. 脏读(Dirty Read):

    • 脏读指的是一个事务读取了另一个事务尚未提交的数据。当一个事务读取到了被另一个事务修改但尚未提交的数据时,如果另一个事务最终回滚,则读取到的数据是无效的。
    • 脏读可能导致数据不一致性和错误的结果。
  2. 不可重复读(Non-repeatable Read):

    • 不可重复读指的是在同一个事务中,多次读取同一数据时,得到的结果不一致。这是因为在读取过程中,其他并发事务对该数据进行了修改或删除。
    • 不可重复读可能导致事务在多次读取同一数据时无法保持一致性,破坏了事务的隔离性。
  3. 幻读(Phantom Read):

    • 幻读是指在同一个事务中,多次执行同样的查询,得到的结果集不一致。这是因为在查询过程中,其他并发事务插入了新的数据行,导致结果集发生了变化。
    • 幻读可能导致事务在同一查询中读取到不同的数据行,无法保持一致性。

6. 死锁的原因及解决办法:

死锁是指两个或多个事务因为互相等待对方释放资源而无法继续执行的状态。死锁的发生是由于以下原因之一或多个原因共同作用:

  1. 互斥条件(Mutual Exclusion):资源只能同时被一个事务占用,当某个事务占用了一个资源后,其他事务无法同时占用该资源。

  2. 请求与保持条件(Hold and Wait):一个事务在持有资源的同时,又申请其他事务所占有的资源。

  3. 不可剥夺条件(No Preemption):资源只能由持有者显式释放,其他事务无法强制抢占。

  4. 循环等待条件(Circular Wait):多个事务形成一个循环等待资源的链,每个事务都在等待下一个事务所占有的资源。

为了解决死锁问题,可以采取以下几种常用的解决办法:

  1. 预防死锁(Deadlock Prevention):

    • 通过破坏死锁发生的四个必要条件中的一个或多个,来预防死锁的发生。
    • 可以在系统设计阶段采用资源分配策略、事务调度策略等方式来预防死锁。
  2. 避免死锁(Deadlock Avoidance):

    • 在运行时动态判断是否分配资源,避免可能导致死锁的资源分配情况。
    • 通过资源分配的安全性检查和资源请求的合理判断,避免进入可能导致死锁的状态。
  3. 检测与恢复(Deadlock Detection and Recovery):

    • 允许死锁发生,但通过周期性地检测系统中的死锁状态,并采取恢复措施来解除死锁。
    • 可以使用图算法(如资源分配图)来检测死锁,并通过回滚、抢占资源等方式进行恢复。
  4. 死锁忽略(Deadlock Ignorance):

    • 假设死锁很少发生或发生死锁的代价较低,可以忽略死锁问题,不采取专门的死锁处理措施。
    • 此方法适用于某些特定环境下,如批处理系统等。

 

 

  

  

posted @ 2023-09-04 23:20  空慧居士  阅读(573)  评论(0编辑  收藏  举报