一、关系型数据库和非关系型数据库
- 非关系型数据库,又被称之为NoSQL,描述的是大量结构化数据存储方法的集合。可分为:
- 面向检索的列式存储,典型代表GoogleAppengine的BigTable;
- 面向高性能并发读/写的缓存存储,其结构类似于数据结构中的Hash表,MemcacheDB、BerkeleyDB、Redis、Flare就是Key-Value数据库的代表;
- 面向海量数据访问的文档存储,典型代表为MongoDB、CouchDB等
- 关系型数据库,其实就是一些横行纵列的二维数据表。典型代表如下:
- MySQL: MySQL, MariaDB, Percona Server
- PostgreSQL: 简称为pgsql,EnterpriseDB
- Oracle:
- MSSQL:
- DB2:
二、数据库设计中的三范式
- 第一范式:每一列属性都是不可再分的属性值,确保每一列的原子性。
- 第二范式:属性完全依赖于主键。
- 第三范式:属性不依赖于其它非主属性,满足第三范式必须先满足第二范式。
三、SQL语言发展历史
- 20世纪70年代,IBM开发出SQL,用于DB2
- 1979年ORACLE公司首先提供商用的SQL,IBM公司在DB2和SQL/DS数据库系统中也实现了SQL。
- 1986年10月,美国ANSI采用SQL作为关系数据库管理系统的标准语言
- 1987年,“国际标准化组织(ISO)”把ANSI(美国国家标准化组织) SQL作为国际标准
四、SQL语句分类
- DDL:Data Definition Language
- CTREATE
- DROP
- ALTER
- DML: Data Manipulation Language
- UPDATE
- INSERT
- DELETE
- DCL: Data Control Language
- GRANT
- REVOKE
- DQL: Data Query Language
- SELECT
五、并发控制
在处理并发读或写时,通过实现一个由两种类型的锁组成的锁系统来解决问题。
- 共享锁,也叫读锁:多个客户同时读取同一资源,是互补干扰的,是相互不阻塞的。
- 排他锁,也叫写锁:只有一个用户能够执行写操作,其他用户只能等待写锁释放才能读写同一个资源,所以写锁是阻塞其他的写锁和读锁的。
六、什么是事务
简单来说就是:事务就是一组原子性的SQL查询,如果事务中有一条语句无法执行,那么所有的语句都将不会执行。即是事务要么全部都执行成功,要是全部都执行失败。
事务的ACID概念:
- 原子性(atomicity):事务必须被看成是一个不可再分的最小工作单元,要么多成功,要么都失败。
- 一致性(consistency):事务总是从一个一致性状态转换到另一个一致性状态,没有资源神秘消失的情况。
- 隔离性(isolation):一个事务在最终提交之前的修改,其他事务一般是不可见的。
- 持久性(durability):事务一旦提交操作,那么修改将永久保存在数据库中。
解释事务的一个经典例子:
银行的储户A需要向储户B转账200元,那么这个需求至少要三个步骤
- 检查储户A的账户余额是否高于200元
- 从账户A的余额中减去200元
- 在账户B的余额中增加200元
想象一下,假如执行第2步后系统崩溃会造成什么后果,账户A平白无故少了200元,这显然是非常严重的事故。但是事务的ACID特性确保银行不会发生这样的事,它将整个需求当成一个事务,只有全部执行成功了,才会在数据库中修改。
七、什么是死锁
死锁是指两个或多个事务在同一个资源上相互占用的,并请求锁定对方占有的资源,从而导致等待对方释放锁死循环的想象。
下面一个简单的例子:
# 事务一
start transaction;
update students set age=20 where id=13;
update students set age=40 where id=14;
commit;
# 事务二
start transaction;
update students set classid=2 where id=14;
update students set classid=5 where id=13;
commit;
假设两个事务都执行了第一条update语句,同时也锁定了相应行数据,接下来它们执行第二条update语句时,发现改行数据被对方锁定,然后两个事务就等待对方释放锁,则陷入死循环。
那怎么解决死锁的问题呢?
数据库系统实现各种死锁检测和死锁超时机制,比如InnoDB存储引擎,检测到死锁就返回一个错误,将持有较少行级排他锁的事务进行回滚。
# MySQL中发现死锁直接返回错误,此时一个事务自动回滚,另一个事务继续完成并自动提交
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
八、MySQL中PRI、UNI、MUL的含义
- PRI :主键
- UNI :唯一键
- MUL:复合键
那这些表示怎么查看呢
desc students;
+-----------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+----------------+
| StuID | int(10) unsigned | NO | PRI | NULL | auto_increment |
| Name | varchar(50) | NO | UNI | NULL | |
| Age | tinyint(3) unsigned | NO | MUL | NULL | |
| Gender | enum('F','M') | NO | | NULL | |
| ClassID | tinyint(3) unsigned | YES | | NULL | |
| TeacherID | int(10) unsigned | YES | | NULL | |
+-----------+---------------------+------+-----+---------+----------------+
UNI、MUL是怎么来的呢,答案是创建索引
show indexes from students;
+----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| students | 0 | PRIMARY | 1 | StuID | A | 25 | NULL | NULL | | BTREE | |
| students | 0 | uni_name | 1 | Name | A | 25 | NULL | NULL | | BTREE | |
| students | 1 | index_age | 1 | Age | A | 25 | NULL | NULL | | BTREE | |
+----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
九、事务的隔离级别
四种四五隔离级别如下:
- READ UNCOMMITED:别的事务可以读到没有提交的数据,产生脏读。
- READ COMMITED:不可重复读。一个需要进行较长时间的事务,期间读到其他事务提交后的数据,导致这个事务每一次读的数据都不一样。
- REPEATABLE READ:可重复读。事务进行过程中每一次读到的数据都是一致的,但是这样会产生幻读的问题。
- SERIALIZIABLE:可序列化。一个事务的未提交读将会阻塞其他事务的修改操作,事务的未提交写将阻塞其他事务的读操作。
事务隔离级别 | 脏读可能性 | 不可重复读可能性 | 幻读可能性 | 加锁读 |
---|---|---|---|---|
读未提交(read-uncommitted) | 是 | 是 | 是 | 否 |
不可重复读(read-committed) | 否 | 是 | 是 | 否 |
可重复读(repeatable-read) | 否 | 否 | 是 | 否 |
串行化(serializable) | 否 | 否 | 否 | 是 |