数据库学习总结

发布于:2025-07-29 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

引言

1 数据库管理系统 database

1.1 数据库概述

1.1.1 存储

1.1.2 数据库管理系统 DBMS

1.1.3 数据库管理系统分类

1.2 MySQL 核心操作

1.2.1 MySQL 命令(特有)

1.2.2 MySQL 服务

1.3 数据对象

1.4 表

2 SQL

2.1  数据库的数据类型

2.2 DDL 示例

2.3 DML 数据库操作语言

2.4 上传文件

2.4.1 mysql 导入 hr.sql

2.5 sql 查询

2.6 表连接

3 函数与子查询

4 函数和事务处理

4.1 函数

4.2 事务处理

4.2.1 事务

4.3 交集、并集、差集

4.4 事物操作

4.5 死锁

5 MySQL

5.1 安装客户端库

5.2 创建用户

5.3 MySQL API

5.4 索引

5.5 数据库备份与恢复

5.6 数据库调优

6 总结


引言

数据库索引是提升查询性能的关键技术之一,大多数现代数据库系统(如MySQL、Oracle、PostgreSQL等)的核心索引结构基于B+树实现。B+树通过其平衡的多层树形结构和有序的叶子节点链表,高效支持范围查询、等值查询及排序操作,同时减少了磁盘I/O次数。相比哈希索引的单一键值查找或B树的分散数据存储,B+树在范围扫描和顺序访问场景中表现更优,成为关系型数据库索引的主流选择。其设计权衡了查询效率、插入删除性能及存储开销,是数据库系统中平衡读写性能的重要基石。

1 数据库管理系统 database

1.1 数据库概述

1.1.1 存储

- 文件系统:FILE fopen fclose, 少量数据、配置信息

- 数据库管理系统:结构化、大量的数据

1.1.2 数据库管理系统 DBMS

是一套软件,用于创建、操作、管理 `数据库`

数据库:磁盘上的一组文件,包含:数据文件、日志文件、控制文件

数据库实例:由后台进程、内存结构、数据库构成

一个数据库,可以启动多个实例(集群),一个实例对应一个数据库,数据库实例是操作数据库的方式

1.1.3 数据库管理系统分类

- 关系型数据库:基于关系模型、使用SQL操作数据、传统的数据存储方式

    - 商业产品

        - Oracle #1

        - Db2 IBM #2

        - SQL Server

    - 开源产品

        - PostgreSQL    最先进的 C      

        - MySQL         最受欢迎 C++    #1

        - SQLite        嵌入式数据库

        - 国产的数据库产品:

- NoSQL:Not Only SQL,是在特定场景替代 关系数据库

    - 文档数据库:mongoDB 可以部分替代关系数据库

    - 键值数据库:redis 缓存、数据结构存储和运算

    - 列数据库:clickhouse/hbase 大数据场景的数据存储、

    - 图数据库:neo2j 数据结构图相关的操作与算法

1.2 MySQL 核心操作

1.2.1 MySQL 命令(特有)

1. 连接服务器

mysql

mysql -u用户名 -p密码 -h主机名127.0.0.1 -P端口号3306

2. 显示基本信息

\s 服务器状态信息

\h 帮助信息

3. 显示数据库

show databases;

4. 连接数据库

use 数据库名;

5. 显示表

show tables;

6. 显示表结构

desc 表名称;

显示表中的数据

select * from 表名称;

7. 创建数据库

create database xyz;
1.2.2 MySQL 服务

0. 查找服务是否存在

ps -ef | grep mysql

service mysql status

service mysql start

1. 安装服务

sudo apt update

sudo apt upgrade

sudo apt install mysql-server

1.3 数据对象

- 表:数据存储在表中,表由行和列构成的二维存储结构

- 索引:占空间,为提升搜索的速度

- 视图:虚拟的表,是查询语句,不占用存储空间

- 函数:

- 过程:存储过程,命名的 SQL 代码块,需要调用才执行

- 触发器:特殊的过程,在特定的时间或事件发生时自动执行

- 包:一个命名空间,把相关的数据对象封装起来

1.4 表

列:由多个‘字段’构成,每个字段存储单一的数据项,列的先后顺序对表没有影响

行:记录,一个表中不能存在完全相同的两行,行的顺序对表没有影响

主键:primary key 表中一列或多列组合起来唯一标识表中的一条记录

主键的选取:

- 业务主键:使用业务中有实际意义的一个字段做主键;身份证、手机号、学号、车牌号

- 代理主键:使用一个无意义的数值;自增长的序列、UUID

外键:foreign key ,用于连接另一张表,是连接表中的主键或唯一键

外键约束,数据的一致性。

关系范式:一套约束、确保表格式的设计符合关系模型

- 1NF:列的值是单一的数据项,不可拆分

- 2NF:主键依赖,表中的非键字段都直接依赖于主键

- 3NF:非键字段之间不存在依赖关系

意义:

- 降低数据冗余(一些数据,只存一次,而非存储多次)

- 完整性

- 一致性


反范式:满足了范式后,基于业务、性能的需求去打破或违反范式

- 业务

- 性能

2 SQL

- DDL       数据定义语言

- DML       数据操作语言

- TCL       事物控制语言

DDL 创建、修改、删除数据对象(表、视图、索引 ...)

- 'CREATE'              创建

- 'ALTER'               修改

- 'DROP'                删除

- 'TRUNCATE'            截断

- 'GRANT'               授权

DML 数据操作语言(CRUD CreateReadUpdateDelete 增删改查)

- INSERT                插入

- SELECT                查找

- UPDATE                更新

- DELETE                删除

TCL 事物控制语句 *

- BEGIN             开始

- COMMIT            提交

- ROLLBACK          回滚

    -- 创建数据库

    create database 数据库名称;

    use 数据库名称;



    -- 创建表

    CREATE TABLE order

    (

        'id'        INT PRIMARY KEY,

        'name'  VARCHAR(16),

        'tel'       CHAR(11),

        ''

    );

2.1  数据库的数据类型

- 数值

    - bit

    - tinyint       1

    - smallint      2

    - int           4   *

    - bigint        8

    - decimal           *

    - double

- 字符串(文本)

    - CHAR          固定

    - VARCHAR       可变长度  n+1

    - BINARY            二进制

    - BLOB          大二进制对象

    - TEXT          比较长的字符串

    - LONGTEXT  

    - ENUM          枚举

    - SET           集合

- 日期与时间

    - DATE

    - TIME

    - DATETIME

    - timestamp     时间戳,精度高,秒之后六位

    - YEAR

- JSON(非关系型数据库范畴,文档数据库的核心)

    - 数组 []

    - 对象 {}

- 空间数据

    CREATE TABLE staff

    (

        id          INT PRIMARY KEY AUTO_INCREMENT,

        name        VARCHAR(16) NOT NULL,

        gender      ENUM('M', 'F') DEFAULT 'M',

        tel         CHAR(11),

        birthday        DATE DEFAULT '2000-1-1'

    );

2.2 DDL 示例

    create table tb1

    (

        id int primary key auto_increment,

        info1 char(6) not null,

        info2 char(6),

        time datetime default now()

    );



    desc tb1;       查看表



    insert into tb1 values(1, 'info 1', 'info 2', '2025-5-28');

    insert into tb1(info1) values('hello');



    select * from tb1;

    select id, info1, info2, time from tb1;



    -- 投影

    select id, info1, 1+2 from tb1;



    -- 修改表结构

    alter table tb1 add age int;

    alter table tb1 add tel char(11) default '10086';

    alter table tb1 drop age;

    alter table tb1 change tel phone char(14);



    delete from tb1 where id=9;



    -- 备份一张表,包括了结构与数据

    create table tb2

    select * from tb1;



    -- 创建一张空表

    create table tb3

    select * from tb1 where 1>2;



    create table tb4

    select id, info1 from tb1;



    -- 删除表:结构和数据

    drop table tb1;



    -- 删除表中的一行或多行数据

    delete from tb1;

    delete form tb1 where id=2;



    -- 截断:删除数据,保留表结构,先drop再create(会释放空间,自动增长从头开始)

    truncate table tb2;



    -- 更新

    update tb1 set info2='x1', time='1999-2-2', info1='aaa' where id=1;



    -- 导入 SQL 脚本

    source /opt/data.sql


 

2.3 DML 数据库操作语言

- 'INSERT'

- 'SELECT'  *

- 'UPDATE'

- 'DELETE'

    -- 投影

        select

            col1,

            col2 as col_xxx,

            col3 nick

        from

            tb1

        (LEFT | RIGHT | FULL) JOIN

            tb2;

        ON

            tb1.pk = tb2.pk

        WHERE

            col1 > 42

        GROUP BY

            col2

        HAVING

            col < 3

        ORDER BY

            col1, col2 DESC

        LIMIT

            5

        OFFSET

            100;

2.4 上传文件

ssh 安全 shell

scp 安全 copy

scp 源 目标(root@地址ip:路径)

2.4.1 mysql 导入 hr.sql
source /home/jkh/mysql/hr.sql

2.5 sql 查询

    -- 查询员工的编号,姓名,工资

    select id,name,salary

    from staff

   

    -- 按照工资降序排列

    order by salary desc



    -- 只要前三个

    limit 3;



    -- 查询 2000 年以后出生的员工信息,编号、姓名、生日、工资

    select id,name,birth,salary

    from staff

    where birth >= '1990-01-01' and birth < '2000-01-01';

    (where birth between '1990-01-01' and '2000-01-01';)



    -- 工资在 5000-10000;

    where salary between 5000 and 10000;



    -- 查询2000年以后出生的员工,编号、姓名、生日、工资,按照工资降序排列,只要前三

    select id,name,birth,salary

    from staff

    where birth >= '2000-01-01'

    order by salary desc

    limit 3;

2.6 表连接

- 笛卡尔乘积

- 内连接(等值连接)

- 外连接

    - 左外连接

    - 右外连接

    - 全连接

    -- 笛卡尔乘积

    select * from staff,dept;



    -- 内连接(两张表中的交集部分)

    select

        *

    from

        staff

    inner join

        dept

    on

        staff.dept_id = dept.id;



   

    select

        *

    from

        staff,dept

    where

        staff.dept_id = dept.id;



    -- 左外连接

    select

        *

    from

        staff s

    left join

        dept d

    on

        s.dept_id = d.id;



    -- 右外连接

    select

        *

    from

        staff s

    right join

        dept d

    on

        s.dept_id = d.id;




    -- 查询各个员工的编号、姓名、部门及工作地点

    select

        s.id,s.name,d.name dept,city

    from

        staff s

    left join

        dept d

    on

        s.dept_id = d.id;

   



    -- 查询员工的编号、姓名、老板的名字

    select

        s.id,s.name,b.name

    from

        staff s

    left join

        staff b

    on

        s.mgr = b.id;

3 函数与子查询

函数

- 内置函数

- 自定义函数

分类

- 多行(聚合)函数

    - `max`

    - `min`

    - `avg`

    - `sum`

    - `count`

- 单行函数

    - 数值

    - 字符串

    - 时间和日期

    - 其他

    --

    select

        min(salary),max(salary),avg(salary),sum(salary),count(salary),

        sum(salary)/count(salary) avg

    from

        staff;




    select

        gender,

        min(salary),

        max(salary),

        avg(salary),

        count(gender)

    from

        staff

    group by

        gender;




    select

        level,

        min(salary),

        max(salary),

        avg(salary),

        count(id) n

    from

        staff

    group by

        level

    having

        n > 1;




    select

        count(id)

    from

        staff;




    select

        d.name dept,

        min(s.salary) sal

    from

        staff s

    right join

        dept d

    on

        s.dept_id = d.id

    group by

        d.name

    order by

        min(s.salary);



    select distinct gender from staff;



    -- 各个部门有多少员工,部门编号、部门名称、员工人数

    select

        d.id,

        d.name,

        count(s.id)

    from

        staff s

    right join

        dept d

    on

        s.dept_id = d.id

    group by

        d.id, d.name;




    -- 各个城市有多少个员工

    select

        d.city city,

        count(s.id) n,

        avg(salary) sal

    from

        staff s

    right join

        dept d

    on

        s.dept_id = d.id

    group by

        city

    order by

        n desc;



   

    select

        m.id,

        m.name,

        count(s.id)

    from

        staff s

    left join

        staff m

    on

        s.mgr = m.id

    where

        m.id is not null

    group by

        m.id;



   

    -- 工资大于平均工资的员工

    select

        *

    from

        staff

    where

        salary > (

            select

                avg(salary)

            from

                staff

        );




    -- 获得与 jack 同一个部门的员工

    select

        *

    from

        staff

    where

        dept_id = (

            select

                dept_id

            from

                staff

            where

                name = 'jack'

        );

4 函数和事务处理

4.1 函数

- 聚合函数 group by having

    - max

    - min

    - avg

    - sum

    - count

- 单行函数

    - 数值            : round,floor,ceiling,abs,pow

    - 字符串       : concat,trim,ltrim,rtrim,left,right,mid,char_length,replace,lower,upper,md5,sha1,sha2

    - 日期和时间  : now,sysdate,curdate,curtime,timestamp,adddate,datediff,timediff,date_format

    - json          

4.2 事务处理

4.2.1 事务

一个业务操作包含多个数据操作,多个数据操作构成一个事物

特性

- A     原子性: 构成一个事物的多个数据操作是一个整体,不可切分,执行的结果要么都成功(提交),要么都撤销(回滚)

- C     一致性: 事物执行前后,数据状态总体一致

- I     隔离性: 多个事物相互隔离,不能交织执行

- D     持久性: 事物结束,数据写入磁盘

隔离级别            脏读          不可重复读           幻读

- 读未提交           +                  +              +

- 读已提交           -                  +              +

- 不可重复读      -                  -              +        *

- 串行化           -                   -              -

    -- 账户

    create database bank;

    use bank;

    create table account

    (

        `id`            int primary key auto_increment,

        `name`          varchar(16),

        `balance`       decimal(9,2)

    );



    insert into account values(1,"alice",10000);

    insert into account values(2,"bob",10000);

    insert into account values(3,"jack",10000),(4,"rose",10000);




    -- 保存交易记录

    create table log

    (

        `id`            int primary key auto_increment,

        `from`          int,

        `to`            int,

        `amount`        decimal(9,2),

        `time`          datetime default now()

    );

ifnull(将null替换为其他值)(再SQL中任何数+null都为null)

    select

        name,ifnull(salary,0)+ifnull(bonus,0) income

    from

        staff;



   

    select

        name, bonus

    from

        staff

    where

        bonus is null;




    select

        name, bonus

    from

        staff

    where

        bonus is not null;




    -- in, not in

    select

        name,dept_id

    from

        staff

    where

        dept_id in (1,2,3);

        -- dept_id not in (1,2,3);

        -- dept_id = 1 or dept_id = 2 or dept_id = 3;



   

    select

        avg(salary),

        round(avg(salary),2),

        floor(avg(salary)),

        ceiling(avg(salary))

    from

        staff;




    select

        3*7,

        abs(-9),

        pow(2,3)

    from

        dual;




    select

        name,

        level,

        concat(name," is ",level)

    from

        staff;




    select

        quote('  hello  '),

        quote(ltrim('  hello  ')),

        quote(rtrim('  hello  ')),

        quote(trim('  hello  '))

    from

        dual;




    select

        name,

        left(name,1),

        mid(name,2,5),

        right(name,3)

    from

        staff;



   

    select

        name,

        char_length(name)

    from

        staff;




    select

        name,

        sha2(name,256)

    from

        staff;




    -- 时间与日期

    select

        now(),

        curdate(),

        curtime(),

        sysdate()

    from

        dual;



   

    select

        adddate(curdate(), 100),

        datediff(curdate(), '2000-1-1'),

        datediff(curdate(), '2025-12-31')

    from

        dual;




    select

        curtime(),

        timediff(curtime(), '12:06')

    from

        dual;




    select

        birth,

        date_format(birth, '%m/%d')

    from

        staff

    where

        date_format(birth, '%m') = '02';




    -- like 模糊查询

    -- _ 一个字符

    -- % 任意字符



    select

        name

    from

        staff

    where

        name like '%a%';

4.3 交集、并集、差集

    create table t1(

        id int,

        info char(4)

    );



    insert into t1 values(1, 'a');

    insert into t1 values(2, 'b');

    insert into t1 values(3, 'c');

    insert into t1 values(4, 'd');




    create table t2(

        id int,

        info char(4)

    );



    insert into t2 values(1, 'c');

    insert into t2 values(2, 'd');

    insert into t2 values(3, 'e');

    insert into t2 values(4, 'f');




    -- 交集

    select

        t1.info

    from

        t1

    inner join

        t2

    where

        t1.info = t2.info;



    -- 并集 加 all 相同值会重复出现

    select

        info

    from

        t1

    union all

    select

        info

    from

        t2;



    --  差集

    -- 性能差

    select

        info

    from

        t1

    where

        info

    not in(

        select

            info

        from

            t2

    );



    -- 推荐外连接再过滤

    select t1.info

    from t1

    left join t2

    on t1.info = t2.info

    where t2.id is null;

4.4 事物操作

默认为自动事物

手动事物: 

- begin

- rollback

- commit

    -- 1号给2号 1000 元

    begin;

        update account set balance = balance - 1000 where id = 1;

        update account set balance = balance + 1000 where id = 2;

        insert into log(`from`, `to`, `amount`) values(1,2,1000);

    commit;

4.5 死锁

    -- 事物1

    begin;

        update account set balance = balance - 1000 where id = 1;       -- 1

        update account set balance = balance + 1000 where id = 2;       -- 3

    commit;



    -- 事物2

    begin;

        update account set balance = balance - 10 where id = 2;         -- 2

        update account set balance = balance + 100 where id = 1;        -- 4

    commit;

5 MySQL

MySQL           C++

PostgreSQL      C

SQLite          C

数据库的**连接器**或**客户端**: C/C++, Python, Java, Go

5.1 安装客户端库

sudo apt-get install libmysqlclient-dev



安装头文件和库文件

/usr/include/mysql

/usr/lib/mysql



编译指令

gcc my.c -o my -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient



替代方案: makefile

5.2 创建用户

sudo mysql

create user jkh@'%' identified by 'jkh';

授权 root 访问数据库 bank 中所有的数据对象

grank all on bank.* to root@'%'

5.3 MySQL API

结构体

- MySQL             数据库连接,

- MySQL_RES         result 结果集, 查询返回的多行数据构成的内存结构

- MySQL_ROW         一行记录,字符串数组,row[0],row[1],row[n-1]

- MySQL_ROWS        由 MYSQL_ROW 构成的链表

函数

- `mysql_init`              初始化数据库连接,没有连接

- `mysql_close`             释放数据库连接

- `mysql_error`             显示错误信息,字符串显示

- `mysql_real_connect`      建立数据库连接,TCP

- `mysql_query`             执行SQL语句: insert,update,delete,select

- `mysql_store_result`      加载select结果集, 使用缓存,

- `mysql_use_result`        加载select结果集

- `mysql_free_result`       释放结果集

- `mysql_num_rows`          结果集中的元数据:行数

- `mysql_num_fields`        结果集中的元数据:列数

- `mysql_fetch_row`         从结果集获得一行数据

- `mysql_insert_id`         获得插入记录的自动生成的id

5.4 索引

没有索引,默认全表扫描,性能比较差

- 主键字段自动创建索引

- where 过滤条件中的字段可以手动创建索引

优点:提升搜索的速度

缺点:占存储空间,在插入数据和删除数据后索引会重建,性能有损耗

具体实现:B+ 树

B树:分支节点和叶子节点中都存储了数据

B+树:叶子节点存储数据,叶子节点使用双向链表连接了起来

5.5 数据库备份与恢复

备份:导出

mysqldump -u root -p --databases hr > d:\hr.sql

恢复:导入

mysql > source d:\hr.sql

Oracle/DB2

- exp 导出

- imp 导入

5.6 数据库调优

- SQL优化:不使用 select * ,使用 join 替代子查询,不使用 IN \ NOT IN ,使用执行计划分析 SQL 语句的性能

- 索引,提升到原有的 1/10

- 分表:垂直分表(业务:),水平分表

    - range

    - list

    - hash

- 分库:分布式的主从 Master/Worker 结构、做读/写分离

- 缓存:使用 redis 做缓存

-- 窗口函数

-- row_number()

-- union

select id,name,salary,

row_number() over(order by salary desc)

from staff;



select id,name,salary,

dense_rank() over(order by salary desc)

from staff;



create view v_staff

as

select id,name,salary,dept_id,

row_number() over(partition by dept_id order by salary desc) n

from staff;



select count(id) from dept

union all

select count(id) from staff;

6 总结

总结来说,B+树因其高效的查询性能、优秀的范围查询支持以及较低的磁盘I/O开销,成为大多数数据库系统索引的首选数据结构。相较于哈希索引和B树,B+树在保持数据有序性的同时,通过多路平衡和叶子节点链表优化了顺序访问和范围扫描,使其特别适合数据库的大规模数据存储和高并发访问需求。尽管索引会占用额外存储空间并可能影响写入性能,但其在加速数据检索方面的优势使其成为现代数据库不可或缺的核心技术之一。


网站公告

今日签到

点亮在社区的每一天
去签到