什么是数据库?数据库是按照数据结构来组织、存储和管理数据的仓库。使用数据库可以简单高效的完成对于数据的管理。

基本概念

DB:DataBase,数据库

DBMS:DataBaseManagerSystem,数据库管理系统,数据库管理系统就是用来管理数据库的。常见的DBMS有MySQL、SqlServer等

DBS:数据库系统,数据库、数据库操作系统和使用的操作系统等统称为数据库系统,是一个完整使用数据库的系统。

DQL:数据查询语言,对数据库中数据进行查询

DML:数据管理语言,对数据库中数据进行增删改等管理

DDL:数据库操作语言,对数据库、数据库中的数据表进行管理

TCL:事务控制语言,对事务进行管理

DCL:数据控制语言,对数据的访问权限进行管理

DQL

对数据表中的数据进行查询操作显示在输出台中,常见的基本语法为

SELECT * FROM 表
WHERE 
GROUP BY
HAVING 
ORDER BY
LIMIT int,int;

select 后跟需要查询的内容字段名,*表示查询所有,查询多个字段名之间用“,”隔开,from后跟需要在哪个表中查询,也可以从多个表中查询不同表中内容。where是条件语句,后面跟需要满足的条件。group by是分组条件,可以根据字段名进行分组。分组后显示内容为每组中的所有成员信息,也可是使用聚合函数求分组中的集合信息。having是分组后的条件语句,后跟分组后需要筛选的组。order by是排序根据选定字段的排序规则对整行记录进行排序。limit是分页查询,根据索引和个数进行查询,后跟两个参数时,根据第一个参数查询第二个参数个数;只有一个参数时从首位查询参数个数,相当于

limit 0,int。例如:limit 2,3 ,在第二个数开始查,共查3个数

扩充概念

distinct :去除重复值,跟在select之后,将查询到的记录中重复值去除

模糊查询:不等值查询,表示查询条件不为确定,而是一个范围。常见关键字为in、like、between...and。例如 where id in(3,2,4)表示id在3、2、4中任何一个都可以。where name like‘%d%’表示名字包含d都可以。

函数 :字符函数、数字函数、日期函数。其中字符函数中concat(Str,Str)是将多个字符拼接成一个 函数。分组函数,对分组后的查询进行计算操作,常见的有sum、count、min、max等。流程控制函数if和case,if进行双分支判断,如果条件成立,进行语句1,不成立则进行语句2 。case进行多重分支判断,when结果then语句,当case中结果和when相等时进行语句,可以有多条when..then...。

内连接

两张表符合条件的结合成一张大表,常用格式为两种,

SELECT * FROM 表1,表2
WHERE 表1.字段=表2.字段;

SELECT * FROM 表1 
JOIN 表2 ON 表1.字段=表2.字段;

将两张表连接成一张虚表后可以使用基本的查询语句对虚表进行操作。

外连接

左外连接和右外连接。外连接分主从表,主表中所有数据都放入虚表中,在从表中需要满足条件的数据和虚表结合成一张大表。常用格式

SELECT * FROM 表1 
LEFT JOIN  表2 ON 表1.字段=表2.字段;
SELECT * FROM 表1 
RIGHT JOIN  表2 ON 表1.字段=表2.字段;

交叉连接

交叉连接是将表1中每一行记录与表2中每一行记录结合成一张大的虚表,得到的表是一张笛卡尔积

DML

对表中的数据进行增删改等操作,常用语法为:添加

INSERT INTO 表名 VALUES (字段1,字段2...);
INSERT INTO 表名(字段2,字段1...) VALUES (字段2,字段1...);

表名后不跟字段名默认全部字段都需要添加,如果添加了字段名,则需要非空的字段全部添加。

修改

UPDATE 表名 SET 字段名 =修改值
WHERE 条件;

满足条件的记录的这个字段被修改。

删除

DELETE FROM 表名
WHERE 条件;

满足条件的记录都被删除。

DDL

CREATE

添加

新建一个数据库,也可以新建一个数据表。CREATE DATABASE 库名新建一个数据库。在新建数据表的时候,可以将相关的设计也设置好。

CREATE TABLE 表名 (
                字段1 类型 [约束],
                字段2 类型 [约束]...
                [约束]
);

其中约束可以不添加,在表创建好后再行设计。

ALTER

修改库,对数据库进行修改,一般对库的字符集进行修改,更改库名可能出现库中数据丢失,一般不适用。对数据表进行修改,可以修改表名,表的结构,对表的约束进行修改,对表的字段进行修改,修改字段名、添加字段、删除字段等。常用语法

DROP

删除库,表。删除库是库中数据全部清除,删除表可以使用drop 是直接将表格删除,无法找回。

truncate 是删除表中所有数据,连带结构删除,但是其索引会保留下来。delete 也是删除表中数据,但无法删除表中结构和约束等。

TCL

事务控制语言。用于对事务的控制

事务

事务

事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。

事务开始结束:

  • COMMIT 或ROLLBACK 语句
  • DDL 或DCL 语句(自动提交)
  • 用户会话正常结束
  • 系统异常终了

事务的四个特性

① 原子性(atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

事务是一个原子操作, 由一系列动作组成。 组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有的操作执行成功,整个事务才提交。

事务中的任何一个数据库操作失败,已经执行的任何操作都必须被撤销,让数据库返回初始状态。

② 一致性(consistency)

事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

一旦所有事务动作完成, 事务就被提交。数据和资源就处于一种满足业务规则的一致性状态,即数据不会被破坏。

③ 隔离性(isolation)

事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对对方产生干扰。准确地说,并非要求做到完全无干扰。

数据库规定了多种事务隔离级别,不同的隔离级别对应不用的干扰程度。隔离级别越高,数据一致性越好,但并发行越弱。

比如对于A对B进行转账,A没把这个交易完成的时候,B就不知道A要给他转多少钱。

④ 持久性(durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

一个事务与其他事务隔离的程度称为隔离级别。

数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题。

对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题。

READ_UNCOMMITTED(读取未提交)

这是事务最低的隔离级别,允许当前事务读取未被其他事务提交的变更。

这种隔离级别会产生脏读,不可重复读和幻读。

产生脏读场景:A事务读取一个字段,但是这个字段被另外一个事务更新却未提交,

再次读取该字段时如果另外一个事务回滚则出现了脏读现象(读到的数据与第一次,

数据库中的数据都不同)。

产生不可重复读场景:A事务读取一个字段,但是这个字段被另外一个事务更新并提交,

再次读取该字段值不一样则出现了不可重复读现象(同一个事务中,不能保证读取的字段值相同)。

产生幻读场景:A事务读取一个字段集合,但是这个表被另外一个事务更新并提交(如插入了几行),

再次读取该表可能会多几行则出现了幻读现象。

③ READ_COMMITTED(读取已提交)

保证一个事务修改的数据提交后才能被另外一个事务读取,

另外一个事务不能读取该事务未提交的数据。可以避免脏读,但不可重复读和幻读的现象仍然可能出现。

不可重复读

A事务读取一个字段,但是这个字段被另外一个事务更新并提交,再次读取该字段值不一样则出现了不可重复读现象(同一个事务中,不能保证读取的字段值相同)。

幻读

读取一个字段集合,但是这个表被另外一个事务更新并提交(如插入了几行),

再次读取该表可能会多几行则出现了幻读现象。

⑤ SERIALIZABLE :(可串行化)

在并发情况下和串行化的读取的结果是一致的,没有什么不同。这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻读。但性能十分低下!

⑥ 什么是脏读、不可重复读和幻读?

脏读: 对于两个事务 T1, T2。T1 读取了已经被 T2 更新但还没有被提交的字段。之后, 若 T2 回滚, T1读取的内容就是临时且无效的,也就是脏数据。

不可重复读:对于两个事务 T1, T2。 T1 读取了一个字段, 然后 T2 更新了该字段。之后, T1再次读取同一个字段, 值就不同了。

幻读:事务T1读取一条指定where条件的语句,返回结果集。此时事务T2插入一些新记录,恰好满足T1的where条件。然后T1使用相同的条件再次查询,结果集中可以看到T2插入的记录,这些多出来的新纪录就是幻读。

不可重复读和幻读的区别:

不可重复读重点是在update,即事务前后对比特定数据内容的修改。而幻读是insert和delete,即事务前后数据结果集的对比。

数据库设计

约束:

约束的作用:对表中的数据进行限定,保证数据的正确性、有效性和完整性。

常见约束

- 非空约束:not null。SQL中的null不区分大小写,所有数据类型的值都可以是null,

唯一约束:unique。同一个表内可建多个唯一约束,唯一约束也可由多列组合而成。当为某列创建唯一约束时,MySQL会为该列相应地创建唯一索引

主键约束:primary key。主键约束相当于非空约束和唯一约束,即主键约束的列既不允许出现重复值,也不允许出现null值;如果对多列组合建立主键约束,则多列里包含的每一列都不能为空,但只要求这些列组合不能重复。

外键约束:foreign key。当主表的记录被从表记录参照时,主表记录不允许被删除,必须先把从表里参照该记录的所有记录全部删除后,才可以删除主表的该记录。还有一种方式,删除主表记录时级联删除从表中所有参照该记录的从表记录。

从表外键参照的只能是主表主键列或者唯一键列,这样才可保证从表记录可以准确定位到被参照的主表记录。同一个表内可以拥有多个外键。

检查:check

默认:DEFAULT。默认,该字段的内容不用手动插入有默认值

为数据表指定约束有如下两个时机:

建表的同时为相应的数据列指定约束。

建表后创建,以修改表的方式来增加约束。

范式:

第一范式:属性(字段)的原子性约束,要求属性具有原子性,不可再分割;  

第二范式:记录的惟一性约束,要求记录有惟一标识,每条记录需要有一个属性来做为实体的唯一标识。  

第三范式:属性(字段)冗余性的约束,即任何字段不能由其他字段派生出来,在通俗点就是:主键没有直接关系的数据列必须消除(消除的办法就是再创建一个表来存放他们,当然外键除外)

主键:根据第二范式,需要有一个字段去标识这条记录,主键无疑是最好的标识,需要满足唯一性、非空性,但是很多表也不一定需要主键,但是对于数据量大,查询频繁的数据库表,一定要有主键,主键可以增加效率、防止重复等优点。

索引

在数据之外,数据库还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用指向数据,这样就可以在这些数据结构上实现高效查找,这些数据结构就是索引。

索引的优势

1)提高数据检索效率,降低磁盘IO成本

2)通过对数据的排序,降低排序成本

索引的劣势

1)索引虽提高了查询效率,但同时降低了更新、修改、删除的效率,因为MySQL不仅要保存数据,还要维护数据和索引的关系。

2)需要成本去维护索引。一个性能良好的索引需要不断的去尝试,以找到最优解。

什么情况下创建索引

1)主键自动建立唯一索引

2)频繁作为查询条件的字段(where后面的字段)

3)查询中与其他表关联的字段(各种join on后面的字段)

4)单值/复合索引选择?(高并发下倾向选择复合索引)

5)查询中排序的字段

6)查询中统计或分组的字段

索引优化

创建索引的可以快速定位到一条记录,提高查询的速度,但是因为需要创建索引表,会占用一定的内存空间,而且每次对原有表进行更新的时候,索引页要一起更新,减缓更新的速率。因此在建立索引时,我们需要根据不同的表的需求建立不同的索引表。

存储过程

是事先经过编译并存储在数据库中的一段SQL语句的集合。调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是很有好处的。

存储过程的优劣:

1. 简化对变动的管理。如果表名、列名、或业务逻辑有了变化。只需要更改存储过程的代码。使用它的人不用更改自己的代码。

2. 通常存储过程都是有助于提高应用程序的性能。当创建的存储过程被编译之后,就存储在数据库中,可重复使用。

3. 存储过程有助于减少应用程序和数据库服务器之间的流量。

因为应运程序不必发送多个冗长的SQL语句,只用发送存储过程中的名称和参数即可。

缺点:

  1. 不易维护,阅读性差
  2. 如果使用大量的存储过程,那么使用这些存储过程的每个连接的内存使用量将大大增加。此外,如果在存储过程中过度使用大量的逻辑操作,那么CPU的使用率也在增加,因为MySQL数据库最初的设计就侧重于高效的查询,而不是逻辑运算。
  3. 很难调试存储过程。只有少数数据库管理系统允许调试存储过程。不幸的是,MySQL不提供调试存储过程的功能。
  4. 开发和维护存储过程都不容易。

开发和维护存储过程通常需要一个不是所有应用程序开发人员拥有的专业技能。这可能导致应用程序开发和维护阶段的问题。