Skip to content

数据库

1、⼀⼆三范式

  1. 第⼀范式,数据库表中的字段都是单⼀属性的,不可再分;每⼀个属性都是原⼦项,不可

分割;如果实体中的某个属性有多个值时,必须拆分为不同的属性通俗解释。1NF是关系模式应具备的最起码的条件,如果数据库设计不能满⾜第⼀范式,就不称为关系型数据库。也就是说,只要是关系型数据库,就⼀定满⾜第⼀范式。

  1. 第⼆范式,数据库表中不存在⾮关键字段对任⼀候选关键字段的部分函数依赖,即符合第

⼆范式;如果⼀个表中某⼀个字段A的值是由另外⼀个字段或⼀组字段B的值来确定的,就称为A函数依赖于B;当某张表中的⾮主键信息不是由整个主键函数来决定时,即存在依赖于该表中不是主键的部分或者依赖于主键⼀部分的部分时,通常会违反2NF。

  1. 第三范式,在第⼆范式的基础上,数据表中如果不存在⾮关键字段对任⼀候选关键字段的

传递函数依赖则符合3NF;第三范式规则查找以消除没有直接依赖于第⼀范式和第⼆范式形成的表的主键的属性。我们为没有与表的主键关联的所有信息建⽴了⼀张新表。每张新表保存了来⾃源表的信息和它们所依赖的主键;如果某⼀属性依赖于其他⾮主键属性,⽽其他⾮主键属性⼜依赖于主键,那么这个属性就是间接依赖于主键,这被称作传递依赖于主属性。通俗理

解:⼀张表最多只存2层同类型信息

2、数据库的索引类型,数据库索引的作⽤

  1. 数据库索引好⽐是⼀本书前⾯的⽬录,能加快数据库的查询速度。索引是对数据库表中⼀

个或多个列(例如,employee 表的姓⽒ (lname) 列)的值进⾏排序的结构。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的⾏相⽐,索引有助于更快地获取信息。

  1. 优点

⼤⼤加快数据的检索速度; 创建唯⼀性索引,保证数据库表中每⼀⾏数据的唯⼀性;加速表和表之间的连接; 在使⽤分组和排序⼦句进⾏数据检索时,可以显著减少查询中分组和排序的时间。

  1. 缺点

索引需要占⽤数据表以外的物理存储空间;创建索引和维护索引要花费⼀定的时间;当对表进⾏更新操作时,索引需要被重建,这样降低了数据的维护速度。

  1. 类型

唯⼀索引——UNIQUE,例如:create unique index stusno on student(sno);表明此索引的每⼀个索引值只对应唯⼀的数据记录,对于单列惟⼀性索引,这保证单列不包含重复的值。

对于多列惟⼀性索引,保证多个值的组合不重复。

主键索引——primary key,数据库表经常有⼀列或列组合,其值唯⼀标识表中的每⼀⾏。该列称为表的主键。在数据库关系图中为表定义主键将⾃动创建主键索引,主键索引是唯⼀索引的特定类型。该索引要求主键中的每个值都唯⼀。当在查询中使⽤主键索引时,它还允许对数据的快速访问。

聚集索引(也叫聚簇索引)——cluster,在聚集索引中,表中⾏的物理顺序与键值的逻辑(索引)顺序相同。⼀个表只能包含⼀个聚集索引,如果某索引不是聚集索引,则表中⾏的物理顺序与键值的逻辑顺序不匹配。与⾮聚集索引相⽐,聚集索引通常提供更快的数据访问速度。

  1. 实现⽅式

B+树、散列索引、位图索引

3、聚集索引和⾮聚集索引的区别

  1. 聚集索引表示表中存储的数据按照索引的顺序存储,检索效率⽐⾮聚集索引⾼,但对数据

更新影响较⼤。⾮聚集索引表示数据存储在⼀个地⽅,索引存储在另⼀个地⽅,索引带有指针指向数据的存储位置,⾮聚集索引检索效率⽐聚集索引低,但对数据更新影响较⼩。

  1. 聚集索引⼀个表只能有⼀个,⽽⾮聚集索引⼀个表可以存在多个。聚集索引存储记录是物

理上连续存在,⽽⾮聚集索引是逻辑上的连续,物理存储并不连续。

4、唯⼀性索引和主键索引的区别

对于主健索引,oracle/sql server/mysql 等都会⾃动建⽴唯⼀索引;

主键不⼀定只包含⼀个字段,所以如果你在主键的其中⼀个字段建唯⼀索引还是必要的;

主健可作外健,唯⼀索引不可;

主健不可为空,唯⼀索引可以;

主健也可是多个字段的组合;

主键与唯⼀索引不同的是主键索引有 not null 属性;

主键索引每个表只能有⼀个。

5、数据库引擎,innodb和myisam的特点与区别

  1. Innodb引擎提供了对数据库ACID事务的⽀持,并且实现了SQL标准的四种隔离级别,关于

数据库事务与其隔离级别的内容请⻅数据库事务与其隔离级别这篇⽂章。该引擎还提供了⾏级锁和外键约束,它的设计⽬标是处理⼤容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运⾏时Innodb会在内存中建⽴缓冲池,⽤于缓冲数据和索引。但是该引擎不⽀持FULLTEXT类型的索引,⽽且它没有保存表的⾏数,当SELECT COUNT(*)FROM TABLE时需要扫描全表。当需要使⽤数据库事务时,该引擎当然是⾸选。由于锁的粒度更⼩,写操作不会锁定全表,所以在并发较⾼时,使⽤Innodb引擎会提升效率。但是使⽤⾏级锁也不是绝对的,如果在执⾏⼀个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。

  1. MyIASM是MySQL默认的引擎,但是它没有提供对数据库事务的⽀持,也不⽀持⾏级锁和

外键,因此当INSERT(插⼊)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低⼀些。不过和Innodb不同,MyIASM中存储了表的⾏数,于是SELECT COUNT(*) FROM TABLE时只需要直接读取已经保存好的值⽽不需要进⾏全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的⽀持,那么MyIASM也是很好的选择。

  1. ⼤尺⼨的数据集趋向于选择InnoDB引擎,因为它⽀持事务处理和故障恢复。数据库的⼤⼩

决定了故障恢复的时间⻓短,InnoDB可以利⽤事务⽇志进⾏数据恢复,这会⽐较快。主键查询在InnoDB引擎下也会相当快,不过需要注意的是如果主键太⻓也会导致性能问题,关于这个问题我会在下⽂中讲到。⼤批的INSERT语句(在每个INSERT语句中写⼊多⾏,批量插⼊)在MyISAM下会快⼀些,但是UPDATE语句在InnoDB下则会更快⼀些,尤其是在并发量⼤的时候。

6、关系型和⾮关系型数据库的区别

数据库 图 128

7、数据库的隔离级别

  1. 隔离级别⾼的数据库的可靠性⾼,但并发量低,⽽隔离级别低的数据库可靠性低,但并发

量⾼,系统开销⼩。

  1. READ UNCIMMITTED(未提交读),事务中的修改,即使没有提交,其他事务也可以看得

到,⽐如说上⾯的两步这种现象就叫做脏读,这种隔离级别会引起很多问题,如⽆必要,不要随便使⽤;这就是事务还没提交,⽽别的事务可以看到他其中修改的数据的后果,也就是脏读;

  1. READ COMMITTED(提交读),⼤多数数据库系统的默认隔离级别是READ

COMMITTED,这种隔离级别就是⼀个事务的开始,只能看到已经完成的事务的结果,正在执⾏的,是⽆法被其他事务看到的。这种级别会出现读取旧数据的现象

  1. REPEATABLE READ(可重复读),REPEATABLE READ解决了脏读的问题,该级别保证

了每⾏的记录的结果是⼀致的,也就是上⾯说的读了旧数据的问题,但是却⽆法解决另⼀个问题,幻⾏,顾名思义就是突然蹦出来的⾏数据。指的就是某个事务在读取某个范围的数据,但是另⼀个事务⼜向这个范围的数据去插⼊数据,导致多次读取的时候,数据的⾏数不⼀致。虽然读取同⼀条数据可以保证⼀致性,但是却不能保证没有插⼊新的数据。

  1. SERIALIZABLE(可串⾏化),SERIALIZABLE是最⾼的隔离级别,它通过强制事务串⾏执

⾏(注意是串⾏),避免了前⾯的幻读情况,由于他⼤量加上锁,导致⼤量的请求超时,因此性能会⽐较底下,再特别需要数据⼀致性且并发量不需要那么⼤的时候才可能考虑这个隔离级别。

8、数据库连接池的作⽤

  1. 在内部对象池中,维护⼀定数量的数据库连接,并对外暴露数据库连接的获取和返回⽅

法,如外部使⽤者可通过getConnection⽅法获取数据库连接,使⽤完毕后再通过releaseConnection⽅法将连接返回,注意此时的连接并没有关闭,⽽是由连接池管理器回收,并为下⼀次使⽤做好准备。

  1. 资源重⽤,由于数据库连接得到重⽤,避免了频繁创建、释放连接引起的⼤量性能开销。

在减少系统消耗的基础上,增进了系统环境的平稳性(减少内存碎⽚以级数据库临时进程、线程的数量)

  1. 更快的系统响应速度,数据库连接池在初始化过程中,往往已经创建了若⼲数据库连接置

于池内备⽤。此时连接池的初始化操作均已完成。对于业务请求处理⽽⾔,直接利⽤现有可⽤连接,避免了数据库连接初始化和释放过程的时间开销,从⽽缩减了系统整体响应时间。

  1. 新的资源分配⼿段,对于多应⽤共享同⼀数据库的系统⽽⾔,可在应⽤层通过数据库连接

的配置,实现数据库连接技术。

  1. 统⼀的连接管理,避免数据库连接泄露,较较为完备的数据库连接池实现中,可根据预先

的连接占⽤超时设定,强制收回被占⽤的连接,从⽽避免了常规数据库连接操作中可能出现的资源泄露。

9、数据的锁的种类,加锁的⽅式

1)锁是⽹络数据库中的⼀个⾮常重要的概念,当多个⽤户同时对数据库并发操作时,会带来

数据不⼀致的问题,所以,锁主要⽤于多⽤户环境下保证数据库完整性和⼀致性。

  1. 数据库锁出现的⽬的:处理并发问题;

  2. 并发控制的主要采⽤的技术⼿段:乐观锁、悲观锁和时间戳。

  3. 从数据库系统⻆度分为三种:排他锁、共享锁、更新锁。从程序员⻆度分为两种:⼀种是

悲观锁,⼀种乐观锁。

10、数据库union join的区别

  1. join 是两张表做交连后⾥⾯条件相同的部分记录产⽣⼀个记录集,union是产⽣的两个记录

集(字段要⼀样的)并在⼀起,成为⼀个新的记录集。

  1. union在数据库运算中会过滤掉重复数据,并且合并之后的是根据⾏合并的,即:如果a表

和b表中的数据各有五⾏,且有两⾏是重复数据,合并之后为8⾏。运⽤场景:适合于需要进⾏统计的运算

  1. union all是进⾏全部合并运算的,即:如果a表和b表中的数据各有五⾏,且有两⾏是重复数

据,合并之后为10⾏。

  1. join是进⾏表关联运算的,两个表要有⼀定的关系。即:如果a表和b表中的数据各有五⾏,

且有两⾏是重复数据,根据某⼀列值进⾏笛卡尔运算和条件过滤,假如a表有2列,b表有2列,join之后是4列。

11、⾯试前必知的 MySQL 常⽤命令

启动与退出指定 IP 地址和端⼝号登录 MySQL 数据库命令格式为:

cpp
mysql -h ip -u root -p -P 3306

例如:

cpp
mysql -h 127.0.0.1 -u root -p -P 3306

退出 MySQL使⽤ quit 或 exit 退出 MySQL

查看数据库SHOW DATABASES;

创建数据库CREATE DATABASE IF NOT EXISTS dbname;

选择数据库USE 数据库名 ;

查看数据库中的数据表SHOW TABLES;

删除数据库

cpp
DROP DATABASE IF EXISTS dbname;

创建⼀个简单的数据库表字段类型(⻓度) 属性索引CREATE TABLE IF NOT EXISTS 表名(

cpp
id INT UNSTGND AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL
)ENGINE = InnoDB DEFAULT CHARSET=utf8;

添加数据

cpp
INSERT INTO table_name ( field1, field2,...fieldN )VALUES ( value1,

value2,...valueN );

查询数据SELECT * FROM table;

修改数据UPDATE table SET 字段1 = '值1', 字段1='值2' WHERE 条件;

删除数据DELETE FROM table WHERE 条件;

创建新普通⽤户GRANT 权限 ON 库名.表名 TO '⽤户名'@'主机名' IDENTIFIED BY '密码'

查询所有⽤户

cpp
SELECT user,host FROM mysql.user;

删除普通⽤户DROP USER '⽤户名'@'主机名';

修改 root ⽤户密码SET PASSWORD = PASSWORD('新密码');

root ⽤户修改普通⽤户密码SET PASSWORD FOR '⽤户名'@'主机名'=PASSWORD('新密码');

授权GRANT 权限 ON 库名.表名 TO '⽤户名'@'主机名' IDENTIFIED BY '密码';GRANT SELECT,INSERT,UPDATE,DELETE ON cendxia.user TO '⽤户名'@'主机名'IDENTIFIED BY '密码';

查看权限SHOW GRANTS FOR '⽤户名'@'主机名';

收回权限REVOKE 权限 ON 库名.表名 FROM '⽤户名'@'主机名';

备份mysqldump -u root -p 数据库名 > 要保存的位置

还原数据

cpp
mysql  -u yser  -p dbname < filename.sql;

建表引擎MyISAM -- 读取速度快,不⽀持事务InnoDB -- 读取速度稍慢⽀持事务事务回滚

⼀些常⽤属性UNSTGND ⽆符号属性AUTO_INCREMENT ⾃增属性(⼀般⽤在id字段上)ZEROFILL 零填充

字符串类型CHAR 定⻓的字符串类型 (0-255)个字符VARCHAR 变⻓的字符串类型,5.0以前(0-255)个字符,5.0版本以后(0-65535)个字符

查看表结构DESC 表名; (缩写版)DESCRIBE 表名;

查看建表语句SHOW CREATE TABLE 表名;

修改表名ALTER TABLE 原表名 RENAME TO 新表名;

修改字段的数据类型ALTER TABLE 表名 MODIFY 字段名数据类型属性索引;

cpp
ALTER TABLE testalter_tbl MODIFY c CHAR(10);

修改字段名ALTER TABLE 表名 CHANGE 原字段名新字段名数据类型属性索引;

增加字段ALTER TABLE 表名 ADD 字段名数据类型属性索引;

-- [FIRST|AFIER 字段名]

-- (FIRST 在最前⾯添加字段。AFIER 字段名在某字段后⾯添加)

删除字段ALTER TABLE 表名 DROP 字段名;

修改字段的排列位置ALTER TABLE 表名 MODIFY 字段名数据类型属性索引 AFIER 字段名;

修改表引擎ALTER TABLE 表名 ENGINE=引擎名; --MyISAM 或 InnoDB

⾼级⽤法

cpp
explain sql;

explain 命令我们可以学习到该条 SQL 是如何执⾏的,随后解析 explain 的结果可以帮助我们使⽤更好的索引,最终来优化它!

通过 explain 命令我们可以知道以下信息:

表的读取顺序,数据读取操作的类型,哪些索引可以使⽤,哪些索引实际使⽤了,表之间的引⽤,每张表有多少⾏被优化器查询等信息。

数据库 图 135

格式化输出

cpp
sql \G

在命令最后⾯加上 \G 即可。

查看帮助在 MySQL 提示符中输⼊ help;或者 \h 获取使⽤帮助。

链接:https://mp.weixin.qq.com/s/QyGtqBhT4YehX7LYwg8WvQ最后,数据库这块的知识点还有很多,具体可参考 GitHub上总结:https://github.com/rongweihe/CS_Offer

数据库 图 136

哈喽,我是⼩贺哥,就爱分享编程知识,如果觉得⽂章对你有帮助,别忘记关注我哦!

数据库 图 136

用心记录,持续成长