数据库

数据库

【一】什么是数据库

一种用于存储、组织和管理大量数据的系统,它将数据以一定的结构形式组织起来,并提供了一套标准的操作接口(如 SQL 语言),使得用户能够有效地查询、更新、插入和删除数据。

【二】数据库的本质

  • 数据库其实就是一块基于网络通信的应用程序
  • 存储数据的基于TCP协议的客户端和服务端的服务器

【三】数据库的分类及对应的主流数据库

  • 关系型数据库
    • 主流数据库:Oracle、MySQL、Microsoft SQL Server、PostgreSQL、SQLite 等。
    • 关系型数据库采用表格的形式表示数据,基于 SQL 查询语言,强调数据之间的表结构关系以及 ACID(原子性、一致性、隔离性、持久性)事务处理。
  • 非关系型数据库(NoSQL Database)
    • 分布式文档型数据库(如 MongoDB):如MongoDB、Couchbase、CouchDB。
    • 键值对型数据库(如 Redis、Memcached):如Redis、Amazon DynamoDB。
    • 列族数据库(如 HBase):Apache HBase、Google Bigtable。
    • 图数据库(如 Neo4j):Neo4j、JanusGraph。
    • 时间序列数据库(如 InfluxDB):InfluxDB、OpenTSDB。
    • 对象数据库(如 OrientDB):OrientDB、ObjectDB。
    • NoSQL 数据库通常不强求严格的表结构,而是灵活的数据存储和查询方式,适用于大规模分布式系统和实时大数据场景。

【四】数据库操作

【1】创建数据库

create databases 数据库名;

【2】查看数据库

show databases;  -- 查看所有数据库
show create database 数据库名; -- 查看数据库的建库sql语句

【3】修改数据库

alter database 数据库名 [character set 编码字符集];

【4】删除数据库

  • 删除数据库后,数据库中存储的所有数据表和数据也将一同被删除,而且不能恢复。
drop database [if exists] 数据库名;

【5】切换到指定库

use 数据库名;

【五】表操作

【1】创建表

create table  表名 (
    字段名1    数据类型[ ( 存储空间 )   字段约束 ],
    .....
    primary key(一个 或 多个 字段名) 
)

【2】查看表

  • 列出当前数据库中所有的数据表
show tables;
  • 查看指定的表
show create table 表名;
  • 查看当前表的详细信息
describe 表名;
  • 查看建表语句
show create table 表名 \G;

【3】修改表

  • 修改表的字段类型 modify(只能改类型不能改名字)
alter table 表名 modify 字段名 字段类型(宽度);
  • change(名字类型都可)
alter table 表名 change 字段名 字段类型(宽度);
  • 修改表名字重命名
alter table 原表名 rename 新表名;
  • 添加字段默认是尾部追加字段
alter table 表名 add 字段名 字段类型;
  • 指定追加位置
alter table 表名 add 字段名 字段类型 after 原字段名;
  • 指定头部添加字段
alter table 表名 add 字段名 字段类型 first;
  • 删除字段
alter table 表名 drop 字段名;

【4】删除表

drop table 表名;

【六】约束条件

【1】非空约束(not null)

  • not null约束的字段不能为 NULL 值,必须赋具体数据
create table b1(
  id int(10) not null,
  ...
);

【2】唯一约束(unique)

  • unique约束的字段具有唯一性,不可重复,但是可以为空(null)。
alter table b2 modify cid int unique;

【3】主键约束(primary key)

  • 单一主键
create table b1(
	id int(10),
....
  primary key(id)
);
  • 复合主键
create table b2(
	id int(10);
  name varchar(32);
 ....
  primary key(id,name)
);
  • 自增字段auto_increment
create table db(
  id int(10) primary key auto_increment,
  name varchar(32)
);

【4】外键约束(foreign key)

create table 表名2(
	字段名1 字段类型1 约束条件1 comment 注释1,
	字段名2 字段类型2 约束条件2 comment 注释2,
  foreign key(在表名2中显示的字段名) references 表名1(表明1中需要建立外键关系的字段名)
);
  • 级联更新和级联删除
on update cascade  # 级联更新
on delete cascade  # 级联删除

【七】表数据操作

【1】增加数据

insert into 表名(字段名) value(值)

【2】修改数据

update  表名 set  字段名=值  where 条件

【3】删除数据

delete from 表名  where 条件

【4】查看数据

select * from 表名 where 条件

【八】筛选过滤条件

【1】where

select * 
from db 
where 条件;

【2】group by(分组)

  • 用于计数、平均、最高、最低等函数
select * 
from db 
group by class;
  • group_concat

  • 聚合函数:group_concat- 获得分组之后的具体的值

  • 关键字 where 和 group by 同时出现的时候,group by 必须在 where 后面

    • where 先对整体数据进行过滤
    • group by 再对数据进行分组

【3】having(分组之后筛选)

select * 
from db 
group by class
having  ...

【4】distinct(去重)

select distinct age from db;

【5】order by(排序)

  • order by : 默认是升序
  • asc 默认可以省略不写 ---> 修改降序
  • desc : 降序
select * from db order by age;

【6】 limit(限制展示条数)

  • limit x,y : 第一个参数是起始位置,第二个是条数
select * from emp limit 10;
select * from emp limit 0,6;

【7】正则

 属性名 REGEXP '匹配方式'
选项 说明 例子 匹配值示例
^ 匹配文本的开始字符 ‘^b’ 匹配以字母 b 开头的字符串 book、big、banana、bike
$ 匹配文本的结束字符 ‘st$’ 匹配以 st 结尾的字符串 test、resist、persist
. 匹配任何单个字符 ‘b.t’ 匹配任何 b 和 t 之间有一个字符 bit、bat、but、bite
* 匹配前面的字符 0 次或多次 ‘f*n’ 匹配字符 n 前面有任意个字符 f fn、fan、faan、abcn
+ 匹配前面的字符 1 次或多次 ‘ba+’ 匹配以 b 开头,后面至少紧跟一个 a ba、bay、bare、battle
? 匹配前面的字符 0 次或1次 ‘sa?’ 匹配0个或1个a字符 sa、s
字符串 匹配包含指定字符的文本 ‘fa’ 匹配包含‘fa’的文本 fan、afa、faad
[字符集合] 匹配字符集合中的任何一个字符 ‘[xz]’ 匹配 x 或者 z dizzy、zebra、x-ray、extra
[^] 匹配不在括号中的任何字符 ‘[^abc]’ 匹配任何不包含 a、b 或 c 的字符串 desk、fox、f8ke
字符串 匹配前面的字符串至少 n 次 ‘b{2}’ 匹配 2 个或更多的 b bbb、bbbb、bbbbbbb
字符串 匹配前面的字符串至少 n 次, 至多 m 次 ‘b{2,4}’ 匹配最少 2 个,最多 4 个 b bbb、bbbb

【九】多表操作

【1】子查询

  • =返回一条数据
select * from 表1 where id = (select id from 表2 where 条件)
  • in 返回多条数据
select * from 表1 where id in (select id from 表2 where 条件)

【2】联表查询

  • inner join(内连接)
select *
from 表1 inner join 表2 on 表1.字段名=表2.字段名
  • left join(左连接)
select *
from 表1 left join 表2 on 表1.字段名=表2.字段名
  • right join(右连接)
select *
from 表1 right join 表2 on 表1.字段名=表2.字段名
  • union(全连接)
select * from 表1 left join 表2 on 表1.字段名=表2.字段名
union
select * from 表1 right join 表2 on 表1.字段名=表2.字段名

【3】关键字exist

  • 只返回布尔值
  • 返回true时,外层查询语句执行
  • 返回false时,外层查询语句不执行
select * from db where exists (select age from db1 where age > 18);

【十】触发器

【1】什么是触发器

  • 在满足对表数据进行增删改的情况下,自动触发的功能,称为触发器

  • 触发器可以作为一种数据库的约束,用于保证数据的完整性和一致性。

【2】触发器的特点

  • 触发器通常与表一起创建、修改和删除。
  • 触发器可以在特定的数据操作之前或之后触发执行。
  • 触发器可以根据用户定义的条件判断是否执行相应的逻辑。
  • 触发器可以调用存储过程、函数、触发其他触发器等,实现更复杂的业务逻辑。

【3】使用情况

  • 增前
create trigger 触发器的名字 
before insert on 表名 
for each row 
begin
	SQL语句
end
  • 增后
create trigger 触发器的名字 
after insert on 表名 
for each row 
begin
	SQL语句
end
  • 删前
create trigger 触发器的名字 
before delete on 表名 
for each row 
begin
	SQL语句
end
  • 删后
create trigger 触发器的名字 
after delete on 表名 
for each row 
begin
	SQL语句
end
  • 改前
create trigger 触发器的名字 
before update on 表名 
for each row 
begin
	SQL语句
end
  • 改后
create trigger 触发器的名字 
after update on 表名 
for each row 
begin
	SQL语句
end

【4】删除触发器

drop 触发器的名字;

【十一】索引

【1】什么是索引

  • 索引(在MySQL中也叫做“键(key)”)是存储引擎用于快速找到记录的一种数据结构,这也是索引最基本的功能。

  • 简单的说,数据库索引类似于书前面的目录,能加快数据库的查询速度。

【2】索引的类型

  • 创建主键约束(PRIMARY KEY)、唯一约束(UNIQUE)、外键约束(FOREIGN KEY)时,会自动创建 对应列的索引。

  • foreign key:不是用来加速查询的

  • primary key/unique key:不仅可以加速查询速度,还具有对应的约束条件

  • index key:只有加速查询速度的功能

【3】索引操作

  • 创建索引
create index  索引名 on 表名(字段名);
  • 查看索引
show index from 表名;
  • 删除索引
drop index 索引名 on 表名

【4】聚集索引(主键索引)

  • 聚集索引(Clustered Index)是关系型数据库中的一种索引类型,它决定了表中数据的物理存储顺序。
  • 聚集索引对表进行了重新组织,使得数据按照聚集索引的键值顺序存储在磁盘上。
  • 由于聚集索引决定了数据的物理存储顺序,因此通过聚集索引可以快速地找到特定范围内的数据
  • MySQL的聚簇索引是基于B+树的数据结构实现的,它会把数据存储在索引的叶子节点上,叶子节点之间按顺序链接,使得按主键进行搜索时速度最快。
  • 如果没有主键,如果按主键搜索,速度是最快的。

特点

  • 查询速度很快。

  • 聚集索引的键值必须是唯一的,不允许重复值存在。

  • 如果表中没有定义聚集索引,那么表的数据存储顺序将按照物理地址来存储。

  • 表不建立主键,也会有个隐藏字段是主键,是主键索引。

  • 主键索引对于按照主键进行查询的性能非常高。

语法

  • 数据列不允许重复,不允许为NULL,一个表只能有一个主键。
ALTER TABLE table_name ADD PRIMARY KEY (column);

【5】唯一索引(unique)

  • 唯一索引是指该索引的所有值都是唯一的,不允许出现重复值。
ALTER TABLE table_name ADD UNIQUE KEY index_name (column);

【6】组合索引(联合索引)

  • 组合索引是一种由两个或更多列组成的索引。
  • 当查询涉及多个列时,组合索引可以大大提高查询性能。
ALTER TABLE table_name ADD INDEX index_name (column1, column2, ...);

【十二】视图

【1】什么是视图

  • 视图就是通过查询得到一张虚拟表,然后保存下来,下次可以直接使用

【2】视图的优点

  • 简化复杂查询:
    • 视图可以对基本表进行复杂的操作,包括连接多个表、过滤条件、聚合函数等。
    • 通过定义视图,可以将复杂的查询逻辑封装到一个简单的视图中,使用户能够以更简洁明了的方式进行数据检索。
  • 数据安全性:
    • 视图可以限制用户对数据的访问权限,通常用于隐藏敏感数据或只提供部分数据给特定的用户。
    • 通过定义视图并设置相应的权限,可以保护数据的安全性,防止未经授权的用户访问敏感信息。
  • 数据完整性:
    • 视图可以用于实现数据完整性约束,即对数据的有效性进行验证。
    • 通过定义视图并添加计算列、过滤条件等约束,可以确保所返回的数据满足一定的条件,提高数据的准确性和一致性。
  • 逻辑数据独立性:
    • 视图使得应用程序与数据之间解耦,即应用程序不需要了解底层表结构的细节。
    • 这样,当底层数据库发生变化时(如表结构修改),只需调整底层视图的定义而无需修改应用程序,从而提高系统的可维护性和扩展性。
  • 性能优化:
    • 物化视图是一种缓存机制,可以将视图的查询结果存储在磁盘上,以提高查询性能。
    • 当基本表的数据频繁变动时,物化视图可以减少查询的计算开销和响应时间,提升系统的性能。

【3】使用视图

  • 创建视图
CREATE VIEW my_view AS SELECT column1, column2 FROM my_table WHERE condition;
# condition 是过滤条件。
  • 使用视图
SELECT * FROM my_view;
  • 更新视图
UPDATE my_view SET column1 = value1 WHERE condition;
  • 删除视图
DROP VIEW my_view;

【4】总结

  • 创建视图咋硬盘上只会有表结构,没有表数据
    • 表数据还是来自之前的表
  • 视图一般只用来查询
    • 不建议对视图内的数据进行更改,有可能会对原始数据产生影响
  • 视图的使用频率并不高
    • 当创建了较多视图后,会造成数据的难以维护

【十三】存储过程

【1】什么是存储过程

  • 存储过程是在关系型数据库中存储的一组预定义的SQL语句集合,可以接收参数并返回结果。
  • 它们被封装在数据库服务器中,并由应用程序通过调用存储过程来执行特定的数据库操作。

【2】存储过程的特点

  • 代码复用 : 存储过程只需要编写一次,可以在多个地方被调用,提高了代码的复用性。
  • 数据库性能优化 : 存储过程在数据库中被编译、优化和缓存,可以减少网络传输开销,提高查询性能。
  • 安全性增强: 存储过程可以限制直接对表的访问权限,通过存储过程来进行数据操作,可以为数据库提供更好的安全性。

【3】使用存储过程

  • 定义存储器
create procedure 存储器的名字(形参1,形参2...)
begin
	sql 代码
end
  • 调用
call 存储器的名字();
  • 查看存储过程具体信息
show create procedure pro1;
  • 查看所有存储过程
show procedure status;
  • 删除存储过程
drop procedure pro1;

【十四】事务

【1】什么是事务

  • 开启一个事务可以包含多条语句,这些语句要么同时成功,要么都不成功
  • 事务是指一系列相关操作的集合,这些操作被视为一个不可分割的工作单元。
  • 事务的目标是确保在多个操作中的每一个都要么全部成功执行,要么全部失败回滚。
    • 即事务的原子性

【2】事务的四大特性

  • 原子性(Atomicity):事务中的所有操作被视为不可分割的整体,要么全部完成,要么全部不执行,没有部分成功的可能。
  • 一致性(Consistency):事务开始前和结束后,数据库都必须处于一致状态。这意味着事务的操作不会违反任何实体完整性、参照完整性和用户定义的完整性约束。
  • 隔离性(Isolation):在同一时间点上,不同的事务看到的是数据库的不同视图,彼此之间互不影响,避免了数据竞态条件(Race Condition)的发生。
  • 持久性(Durability):一旦事务被提交,无论后续发生什么情况(如系统故障、电源中断等),事务对数据库的修改都会永久保存下来,不会丢失。

【3】事务的作用

  • 事务的主要作用在于在多个并发操作下保证数据的一致性和完整性,特别是在分布式系统和多用户环境中。
  • 通过控制事务边界,可以防止脏数据(Dirty Data)的产生,确保每个操作都在数据库中按照预期的方式执行。

【4】如何开启事务和事务回滚

  • 开启事务(以MySQL为例):

    START TRANSACTION;
    
    • 提交事务(MySQL):
    COMMIT;
    
  • 回滚事务(MySQL):

    ROLLBACK;
    

    当事务处理过程 ** 现错误或者操作未按预期执行时,通常会调用 ROLLBACK 来撤销已执行的所有操作,回到事务开始前的状态。

【5】结束事务

  • 不论是提交还是回滚事务,都需要通过特定的语句来结束事务。
START TRANSACTION; -- 开始事务

-- 执行事务操作
INSERT INTO 表名 (列1, 列2, 列3) VALUES (值1, 值2, 值3);
UPDATE 表名 SET 列1 = 值1 WHERE 条件;
DELETE FROM 表名 WHERE 条件;

COMMIT; -- 提交事务,将修改永久保存
OR
ROLLBACK; -- 回滚事务,撤销所有修改

END; -- 结束事务

【6】数据库事务隔离机制

  • Read uncommitted(读未提交)
    • 存在脏读、不可重复读和幻读问题。
  • Read committed(读已提交)
    • 解决了脏读问题,但仍可能出现不可重复读和幻读。
  • Repeatable read(可重复读取)
    • 解决了脏读和不可重复读问题,但仍可能出现幻读。
  • Serializable(串行化)
    • 解决了脏读、不可重复读和幻读问题,但在效率方面有所牺牲。

【十五】数据库三大读现象

  • 幻读(Read Ghost):在一个事务中,如果两个查询返回的行数不同,即使它们使用了相同的 WHERE 子句和排序条件,这称为幻读。幻读通常发生在对行数可变的表(如日志表)上。
  • 不可重复读(Phantom Reads):在同一事务内部,多次读取同一行数据,发现结果不一致,原因是第二次读取时发生了新的插入操作,这种现象称为不可重复读。
  • 读已提交(Read Committed):这是大多数事务隔离级别的默认行为,在这一级别下,事务看到的都是已经提交的数据,但无法阻止其他事务在当前事务执行期间进行插入或更新操作,可能导致不可重复读和幻读的现象。

【十六】数据库锁机制

  • 锁保证并发的多个事务同一时间只有一个能运行
    • 会一定程度上降低程序的运行效率
    • 但是能大大提升数据的安全性。

【1】按粒度分类

1.表级锁
  • 每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、 InnoDB、 BDB 等存储引擎中。
2.行级锁
  • 每次操作锁住一行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB 存储引擎中。
3.页级锁
  • 页级锁:每次锁定相邻的一组记录,锁定粒度界于表锁和行锁之间,开销和加锁时间界于表锁和行锁之间,并发度一般。应用在BDB 存储引擎中。

【2】按级别分类

1.共享锁(读锁)

语法:

select … lock in share mode

若事务T对记录A加上共享锁,则事务T可以读A但不能修改A,其他事务只能再对A加共享锁,而不能加排它锁,直到事务T释放A上的共享锁。这保证了其他事务可以读A,但在事务T释放A上的共享锁之前不能对A做任何修改

2.排它锁(写锁、独占锁)

语法:

select … for update

若事务T对记录A加上排它锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁(共享锁/排它锁),直到T释放A上的排它锁。这保证了其他事务在事务T释放A上的排它锁之前不能再读取和修改A

【3】按使用方式分类

1.悲观锁
  • 顾名思义指的是对外界将要进行的数据修改操作持悲观态度
  • 因此,在整个数据处理过程中,将数据处于锁定状态。
  • 现在由于互联网的高并发架构,即使加上悲观锁也无法保证数据不被外界修改,因此不推荐使用。
2.乐锁
  • 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突
  • 所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测
  • 如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。
  • 通常乐观锁的实现是在表中加一个字段(可能是时间戳或版本号)
  • 在写入的时候会查询一下版本号
    • 如果版本号没有改变,就写入数据库并同时改变版本号。
  • 从本质上来说,乐观锁并没有加锁
    • 所以效率会大大提升
    • 但也有一定的缺陷,就是可能导致一部分任务的写入失败。

【十七】数据库的三大范式

  • 范式就是我们在设置数据库的表时,一些共同需要遵守的规范

  • 掌握这些设计时的范式,可以让我们在项目之初,设计库的表结构更加合理和优雅

  • 三大范式之间,是逐级递进的关系,也就是说后一个范式是在前一个范式的基础上推行。

【1】第一范式 1NF

  • 定义:一个关系模式必须满足属性域内的值都是原子的,即不可再分,不存在重复的值集。
  • 意义:消除了列值的重复,确保了数据的最小单位是单一且有意义的信息项,降低了数据冗余,有助于提高数据的一致性。

【2】第二范式 2NF

  • 定义:在1NF的基础上,关系模式中的非主键依赖于整个主键(键集合),而不仅仅是单个属性。
  • 意义:消除部分依赖,使得非关键属性与键之间存在完全函数依赖,减少数据冗余并提高数据 ** 性。

【3】第三范式 3NF

  • 定义:在2NF的基础上,关系模式中没有任何非主键属性传递依赖于其他非主键属性(也称为三元组依赖)。
  • 意义:消除传递依赖,保证数据的逻辑 ** 性,避免因非关键属性的变化导致冗余信息的不一致。
posted @ 2024-07-03 09:08  蓝幻ﹺ  阅读(8)  评论(0编辑  收藏  举报