目录
一.数据库的约束类型
一.创建数据库、修改数据库名、修改表名,修改列名、修改某个属性的语法
三.索引的类型、优缺点以及使用场景
四.索引的常见的索引数据结构
五.数据库中常用的锁
六.事务的四大特性
七.什么是脏读?幻读?不可重复读?
八.WHERE 和 HAVING
WHERE 子句:
HAVING 子句:
本专栏全是博主自己收集的面试题,仅可参考,不能相信面试官就出这种题目。
面试题专栏:http://t.csdnimg.cn/iVera
一.数据库的约束类型
MySQL的约束类型如下:
- NOT NULL 非空约束,规定某个字段不能为空
- UNIQUE 唯一约束,规定某个字段在整个表中是唯一的
- PRIMARY KEY 主键(非空且唯一)约束
- FOREIGN KEY 外键约束
- CHECK 检查约束
- DEFAULT 默认值约束
创建数据表的语法:
create table 表名(
字段名1 数据类型 约束类型,
字段名1 数据类型 约束类型,
..............................................
字段名n 数据类型 约束类型
)
而不一样的是外键约束已经条件约束:
检查约束:age INT CHECK (age > 35)
外键约束需要在表名的最后一行,例如 :FOREIGN KEY (字段名) REFERENCES 表(字段名)。
扩展学习:设置自增: 字段名 数据类型 PRIMARY KEY AUTO_INCREMENT
一.创建数据库、修改数据库名、修改表名,修改列名、修改某个属性的语法
创建数据库:create database 数据库名;
创建使用xxx字符集的数据库:create database if not exists 数据库名 character set 字符集名;(常用的是utf-8)
修改数据库名的方法:创建新的数据库,然后直接复制旧数据库的数据到新的数据库中。
CREATE TABLE new_database_name.table_name AS SELECT * FROM old_database_name.table_name;
修改表名:RENAME TABLE 原表名 TO 新表名;
删除某列:ALTER TABLE 表名 DROP COLUMN 列名;
修改列名和数据类型等:
修改列名:ALTER TABLE 表名 CHANGE COLUMN 原列名 新列名 新列定义;修改数据类型:ALTER TABLE 表名 MODIFY COLUMN 列名 新数据类型;
三.索引的类型、优缺点以及使用场景
索引在哪?
在数据库中,索引是一种特殊的数据结构,用于加快对表中数据的访问速度和查询性能。索引并不是存储在表的数据行中,而是存储在单独的数据结构中,这些数据结构通常位于磁盘或内存中,具体取决于数据库管理系统的实现和配置。
索引的作用:
- 设置了合适的索引之后,数据库利用各种快速定位技术,能够大大加快查询速度,这是创建索引的最主要的原因。
- 可以降低数据库的IO成本,并且索引还可以降低数据库的排序成本。
- 加快表与表之间的连接。
索引的类型:
1.普通索引 2.主键索引 3.组合索引 4.唯一索引 5.B-tree 索引 6.哈希索引 7全文索引 8.空间索引
在以上当中,主键索引和唯一索引会自动创建。
普通索引:
用于加速常规的等值查询,允许列中值重复:CREATE INDEX index_name ON table_name (column_name);
组合索引:
组合索引基于多个列创建,适用于多列查询的情况:CREATE INDEX index_name ON table_name (column1, column2);
哈希索引:
MySQL并不直接支持哈希索引,但可以通过内存表模拟类似效果。需要快速的等值查找
全文索引
全文索引用于在文本列上执行全文搜索。需要在文本数据中进行全文搜索的情况,如文章内容、日志等。CREATE FULLTEXT INDEX index_name ON table_name (column_name);
空间索引:
空间索引用于地理数据或几何数据类型的列。如地图应用 CREATE SPATIAL INDEX index_name ON table_name (geometry_column);
四.索引的常见的索引数据结构
-
B-树(B-tree): 是一种自平衡的树数据结构,能够保持数据有序,支持快速的范围查找和排序。在数据库中广泛应用于索引结构,如普通索引和唯一索引等。
-
B+树(B+ tree): 是 B-树的一种变种,相比于 B-树,B+树在内部节点只存储键值信息,而数据记录存储在叶子节点中,这样能够提升范围查询效率。
-
哈希表(Hash table): 哈希索引将索引键的哈希值映射到数据存储的位置,适合等值查找。在某些数据库中,如某些内存数据库或者特定引擎下,可以使用哈希索引。
总结:数据库系统通常使用B+树而不是简单的B树作为索引结构,因为B+树的叶子结点形成了一个有序的链表,可以更快定位和遍历符合条件的数据。B+树的叶子节点只存储数据和指针,而非叶子节点只存储键值,这种结构使得B+树能够更有效地利用内存和磁盘空间。B+树在插入和删除操作后,由于只影响到叶子节点链表和少量的非叶子节点,因此整棵树的平衡性和性能更为稳定
五.数据库中常用的锁
在 MySQL 中,锁可以按多种方式分类,主要有以下几种类型:
-
共享锁(Shared Locks): 也称读锁(Read Locks),允许多个事务同时读取同一资源,但不允许任何事务对资源进行写操作。
-
排他锁(Exclusive Locks): 也称写锁(Write Locks),只允许一个事务对资源进行写操作,其他事务无法同时读取或写入该资源。
-
意向锁(Intention Locks): 用于表示事务准备获取表级别锁(表锁)或行级别锁(行锁),分为意向共享锁和意向排他锁。
MySQL 的锁可以针对不同的粒度进行管理:
-
表锁(Table-level Locks): 锁定整张表,适用于大批量操作或需要修改整张表数据的场景。表锁可以是读锁(共享锁)或写锁(排他锁)。
-
行锁(Row-level Locks): 锁定表中的单行数据,只有在需要修改或读取具体行时才会加锁。行锁一般使用排他锁。
-
页级锁(Page-level Locks): 锁定表中的一页数据,不是 MySQL 默认的锁粒度,而是某些存储引擎如 InnoDB 在特定情况下使用的锁粒度。
六.事务的四大特性
事务(Transaction)是数据库管理系统中的基本单位,它必须具备四个特性,通常被称为ACID特性:
-
原子性(Atomicity): 原子性指事务是一个不可分割的工作单位,事务中的所有操作要么全部提交成功,要么全部失败回滚,不存在部分执行的情况。原子性保证了数据库在执行事务时要么完全执行成功,要么完全不执行,从而保持数据的一致性。
-
一致性(Consistency): 一致性指事务执行的结果必须使数据库从一个一致性状态变到另一个一致性状态。在事务开始之前和事务结束之后,数据库的完整性约束(例如,唯一性约束、外键约束等)。没有被破坏。换句话说,事务在执行过程中如果不满足数据库的完整性约束,系统会自动回滚事务,使数据回到事务开始之前的状态。
-
隔离性(Isolation): 隔离性指多个事务并发执行时,每个事务都有各自独立的操作空间,互不干扰。事务的隔离性能防止多个事务并发执行时由于交叉执行而导致数据的不一致性。数据库系统通过各种并发控制技术来实现事务的隔离性,如锁机制等。
-
持久性(Durability): 持久性指一旦事务提交,其结果就应该是永久性的,即使系统发生故障,已经提交的事务对数据库的修改也不应该丢失。数据库系统通常通过将事务的操作持久化到非易失性存储设备(如硬盘)来保证持久性。
注:
- 数据库系统是通过并发控制技术和日志恢复技术来避免这种情况发生的。
- 并发控制保证事务的隔离性和一致性,日志恢复保证了原子性、持久性
七.什么是脏读?幻读?不可重复读?
脏读(Dirty Read)问题:脏读是指一个事务在读取另一个事务未提交的数据时,导致数据不一致。
不可重复读(Non-repeatable Read)问题:不可重复读是指在同一个事务中多次读取同一数据,但另一个事务修改数据,得到的结果却不一致。
幻读(Phantom Read)问题:幻读是指一个事务在读取到某个范围内的数据后,另一个事务插入了新的数据,导致第一个事务再次读取时,发现有新增的数据。
解决方案-事务的隔离级别.:
- Read Committed(读已提交): 解决脏读问题,但仍可能出现幻读和不可重复
- Repeatable Read(可重复读): 解决脏读和不可重复读问题,但仍可能出现幻读
- Serializable(串行化): 最高隔离级别,可以解决脏读、幻读和不可重复读问题,但性能开销较大。
- 读取未提交:这种什么都解决不了,摆设。
解析:假设我们有一张表,商品表,有两个用户A、B。
第一种解决方案:A在输入新商品时,将商品表设为不可见,只有提交之后才可见。
第二种解决方案:A提交之后,B读取之后,A用户再次修改,而B再一次修改,但是A依然看见的是最开始的数据快照。
第三种解决方案:虽然A提交之后,B读取之后,A用户再次修改,对于B没有用,但是B只是固定住了范围,而A却再往范围里加了商品,因此也就发生了幻读,因此需要串行化。
八.WHERE
和 HAVING
WHERE 子句:
-
作用:
WHERE
子句用于从表中选择满足指定条件的行。它在查询中作为过滤条件使用,用来限定返回的行。
-
使用场景:
- 通常用于过滤行级数据,即在数据行被检索之前应用条件。
- 可以用来过滤基于列的条件,比如
age > 18
、name = 'John'
等。
SELECT *
FROM students
WHERE age > 18 ORDER BY AGE >18 DESC;
HAVING 子句:
-
作用:
HAVING
子句用于在 SQL 查询中对分组后的结果集进行过滤。它通常与GROUP BY
一起使用,用来过滤分组后的数据。
-
使用场景:
- 在需要对分组后的结果进行条件过滤时使用。通常用于聚合函数(如
SUM()
、COUNT()
等)的结果。 - 由于
HAVING
是在数据分组之后进行过滤,所以它可以使用聚合函数(如SUM()
、AVG()
等)作为条件。
- 在需要对分组后的结果进行条件过滤时使用。通常用于聚合函数(如
示例:
SELECT department, AVG(salary) as avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
二者之间最大的区别:
WHERE
子句出现在SELECT
语句中的FROM
子句之后和GROUP BY
子句(如果有的话)之前。HAVING
子句出现在GROUP BY
子句之后,ORDER BY
子句之前。WHERE
通常用于过滤行数据,不允许使用聚合函数;而HAVING
用于过滤分组后的数据,允许使用聚合函数。