python学习站 /第四周mysql数据库
阅读主题
正文字体
字体大小

数据库和SQL完整笔记

本节15936字2025-04-27 10:35:57
0. 相关概念
    ~ DB / RDB - relational database
    ~ DBMS / RDBMS - relational database management system
    ~ DBA - database administrator
    ~ DBS - database system
    ~ SQL / NoSQL / NewSQL - structured query language / not only SQL
        - KV数据库 - Redis / DynamoDB - 性能极好 - 游戏开发 / IoT应用 / 实时分析 
        - 文档数据库 - MongoDB / DynamoDB / CouchDB - 价值低体量大 / 扩展能力 - 内容管理 / 日志处理 / 实时协作同步
        - 列族数据库 - Cassandra / HBase - 大数据场景下提数性能好 / 实时查询
        - 图数据库 - Neo4j / MemGraph - Cypher - 社交网络 / 推荐系统 / 流数据处理
        - 时序数据库 - InfluxDB / Prometheus / DolphinDB - 时间序列分析 - 金融 / 监控
        - 搜索引擎 - ElasticSearch / Solr - 倒序索引 - 全文检索

1. 关系型数据库的特征
    ~ 理论基础 - 关系代数(集合论、一阶逻辑、关系运算)
    ~ 具体表象 - 用二维表组织数据
        - 表 - 实体(entity)- 关系(relation)
        - 行 - 记录(record)- 元组(tuple)
        - 列 - 字段(field)- 属性(attribute)
        - 主键(primary key)- 能够唯一标识一条记录的字段
        - 外键(foreign key)- 外来的主键(其他表的主键或唯一性字段) 
        - 行数 - 势(cardinality)
        - 列数 - 度(degree)
        - 数据取值范围 - 域(domain)
    ~ 编程语言 - 结构化查询语言 - SQL
        - 数据定义语言 - DDL - create / drop / alter / rename / truncate
        - 数据操作语言 - DML - insert / delete / update / select
        - 数据控制语言 - DCL - grant to / revoke from
        - 事务控制语言 - TCL - start transaction / commit / rollback

2. 关系型数据库相关产品
    ~ Oracle - PL/SQL
    ~ MySQL - Hive - HQL
    ~ IBM DB2
    ~ SQLServer - T-SQL
    ~ PostgreSQL
    ~ MariaDB
    -------------
    ~ Snowflake
    ~ Greenplum
    ~ Teradata

3. MySQL相关知识
    ~ 性能好、成本低、可靠性高
    ~ MySQL的SQL方言跟大数据平台的HiveSQL相似度最高
    ~ 安装和启动
        - Windows环境 - MySQL Installer - Windows服务 - MySQL80
        - macOS环境 - MySQL Server / MySQL Workbench - 系统设置 - MySQL
        - Linux环境 - CentOS / Redhat - 包管理工具RPM
    ~ 连接MySQL服务器
        - 命令行客户端 - mysql -h localhost -u root -p
        - 图形化客户端
            ~ Workbench - 功能比较完备,界面不够漂亮 - 官方工具
            ~ Navicat - 付费工具,界面漂亮,功能比较强大 - PremiumSoft
            ~ SQLyog - 付费/社区,功能比较强大,界面一般 - Webyog
            ~ DataGrip - 支持多种数据库,智能代码编辑器,资源占用高 - JetBrains

4. MySQL命令
    ~ show - 显示相关信息
        - 显示所有数据库:show databases;
        - 显示所有二维表:show tables;
        - 显示所有字符集:show charset;
        - 显示所有排序规则:show collation;
        - 显示存储引擎:show engines;
    ~ help - 获取帮助信息
    ~ system - 调用系统命令
        - 清屏:system clear; / system cls;
        - 查看文件:system ls; / system dir;
    ~ source - 执行SQL脚本
    ~ edit - 打开文本编辑器
    ~ quit - 退出客户端

5. 使用DDL建库建表
    ~ 创建数据库
    create database school default charset utf8mb4;

    ~ 删除数据库
    drop database school;

    ~ 切换上下文
    use school;

    ~ 创建二维表
    create table students
    (
    stu_id int not null,
    stu_name varchar(20) not null,
    stu_sex boolean not null default 1,
    stu_birth date not null,
    primary key (stu_id)
    ) engine innodb;

    ~ 显示表结构
    desc students;

    ~ 删除二维表
    drop table students;
    
    ~ 修改表添加列
    alter table students add column stu_tel char(11) not null;

    ~ 修改表删除列
    alter table students drop column stu_tel;

    ~ 修改表修改列
    alter table students modify column stu_sex char(1) not null default '男';
    alter table students change column stu_sex stu_gender char(1) not null default '女';

    ~ 修改表添加约束
    alter table students add constraint ck_students_gender check (stu_gender = '男' or stu_gender = '女');

    ~ 修改表删除约束
    alter table students drop constraint ck_students_gender;

    ~ 修改表名
    alter table students rename to tb_student;

6. SQL数据类型
    help 'data types';
    help 'decimal';
    help 'varchar';

    https://devdocs.io/mariadb/

    ~ 整数 - tinyint / smallint / mediumint / int(integer) / bigint
             1字节      2字节       3字节         4字节          8字节
        smallint - 取值范围从 -32768 到 32767
        smallint unsigned - 只能表示0和正数 - 取值范围从 0 到 65535
        ----------------------------------------------------------------
        int / integer - 取值范围从 -2^31 到 2^31-1
        int unsigned - 无符号整数 - 只能表示0和正数 - 取值范围从 0 到 2^32-1
        int(4) zerofill - 12 --> 0012 / 123 ---> 0123 / 1234 ---> 1234
        ----------------------------------------------------------------
        bigint - 取值范围从 -2^63 到 2^63-1
        bigint unsigned - 只能表示0和正数 - 取值范围从 0 到 2^64-1
    ~ 小数 - float / double / numeric / decimal / dec
        decimal(M,D) / numeric(M,D) - M位有效数字,小数点后面有D位有效数字
        最大值:M - 65, D - 30
        默认值:M - 10, D - 0
        经验:不要使用float和double两种类型!!!
    ~ 字节串 - binary / varbinary - 二进制数据
    ~ 字符串 - char / varchar
        char(M) / charater(M) - 定长字符串 - 255
        varchar(M) / character varying(M) - 变长字符串 - 65535
        注意:如果使用utf8mb4编码 ---> varchar(16383)
        经验:不要把大文本或大二进制数据放到数据库二维表中,比较好的做法是保存文件的资源路径
    ~ 日期和时间 - date / time / datetime / timestamp
        date - 日期 - 1998-05-08
        time - 时间 - 14:25:39
        datetime - 日期时间 1998-05-08 14:25:39
        经验:尽量不使用timestamp类型,避免出现2038问题!!!
    ~ 其他类型
        boolean - tinyint - 1 / 0
        enum / set - 有限选项 - enum('男', '女') / enum('东', '南', '西', '北')
        longtext / longblob - 文本大对象(CLOB)/ 二进制大对象(BLOB)- 4G
        json - JSON数组 / JSON对象 - [1, 2, 3] / {'name': '骆昊', 'age': 43} - 4G

7. 表关系的建立
    ~ 实体关系图(ER图)- 设计表以及表关系
        - 实体 - 矩形框
        - 属性 - 椭圆框
        - 关系 - 菱形框
    ~ 建模工具 - 正向工程 / 反向工程
        - PowerDesigner - 概念模型图 ---> 物理模型图 ---> SQL方言
        - ER/Studio
        - Enterprise Architect
        - Visual Paradigm
    ~ 一对一 - 多对一的特例,可以将任何一方视为多添加外键列,再给外键列加唯一约束即可
    ~ 一对多/多对一 - 在多的一方添加外键列,用于维系多对一关系(考虑性能可以不添加外键约束)
    ~ 多对多 - 创建中间表,将多对多关系变成两个多对一关系(经典做法)

8. 写数据操作
    ~ 需要考虑数据的完整性(data integrity)
        - 实体完整性 - 每条记录都是独一无二的 - 主键约束 / 唯一约束 - duplicate entry
        - 参照完整性 / 引用完整性 - 从表的数据要参照主表的数据 - 外键约束 - foreign key constraint fails
        - 域完整性 - 不能写入无效的数据 - 数据类型 / 长度限制 / 非空约束 / 默认值约束 / 检查约束

    ~ 插入数据 - insert
        insert into 表名 
            (字段1, 字段2, ...) 
        values 
            (值1, 值2, ...);
        
        insert into 表名 
            (字段1, 字段2, ...) 
        values 
            (值1, 值2, ...), 
            (值1, 值2, ...),
            (值1, 值2, ...);

    ~ 删除数据 - delete
        delete 
          from 表名 
         where 条件;

    ~ 更新数据 - update
        update 表名 
           set 字段1 = 值1
             , 字段2 = 值2
             , ... 
         where 条件;

9. 读数据操作 - 业务提数
    ~ 投影 - select子句
        - 别名 - as
        - 去重 - distinct
    ~ 数据来源 - from子句
        - 表连接 - 连接事实表和维度表
            ~ cross   join - 交叉连接 - 笛卡尔积
            ~ inner   join - 内连接 - on - 连表条件
            ~ natural join - 自然连接 - 同名列
            ~ left    join - 左外连接 - on - 连表条件 - 左表不满足连表条件的记录也能取到
            ~ right   join - 右外连接 - on - 连表条件 - 右表不满足连表条件的记录也能取到
            ~ full    join - 全外连接 - MySQL不支持全外连接
    ~ 分组前筛选 - where子句
        - 算术运算 - +、-、*、/
        - 比较运算 - =、<>、<、>、<=、>=
        - 范围运算 - between ... and ...
        - 逻辑运算 - and、or、not
        - 模糊查询 - like、regexp
        - 空值运算 - is null / is not null
        - 其他运算 - all、any、in、not in
        - 函数运算 - trim / char_length / substring / timestampdiff
    ~ 分组 - group by子句 - 给每个组做统计
        - 聚合函数
            ~ sum - 求和
            ~ avg - 算术平均
            ~ max - 最大值
            ~ min - 最小值
            ~ count / count(distinct) - 计数
            ~ variance / var_pop / var_samp - 方差
            ~ stddev / stddev_pop / stddev_samp - 标准差
    ~ 分组后筛选 - having子句 - 可以写聚合函数
    ~ 排序 - order by子句
        - 升序 - asc(默认)
        - 降序 - desc
    ~ 分页 - limit / offset 子句 - MySQL方言

10. 窗口函数 - 数据分析函数(OLAP函数) - 开窗打标
    ~ 函数() over ()
    ~ 函数() over (order by ...)
    ~ 函数() over (partition by ... order by ...)
    ~ 函数() over (order by ... rows between ... and ...)
    ~ 函数() over (order by ... range between ... and ...)
        - preceding / following / unbounded
        - current row
        - 定义窗口 - window w as (...) - 实现对窗口的复用

    ~ 有哪些函数可以在窗口函数语法中使用
        - 聚合函数 - sum() / avg() / count() / max() / min() / stddev() / variance()
        - 排名函数 - rank() / dense_rank() / row_number() / percent_rank()
        - 取数函数 - lag() / lead() / first_value() / last_value() / nth_value()

11. 使用DCL授予和召回权限
    ~ 创建用户
    create user 'guest'@'%' identified by 'Guest.618';

    ~ 授予权限
    grant insert, delete, update, select on hrs.* to 'guest'@'%';

    ~ 召回权限
    revoke insert, delete, update on hrs.* from 'guest'@'%';

    ~ 创建角色
    create role data_analyst;

    ~ 设置角色权限
    grant select, show view on hrs.* to data_analyst;

    ~ 通过角色授予权限
    grant data_analyst to 'guest'@'%';

    ~ 修改密码
    alter user 'guest'@'%' identified by '123456';

    ~ 密码过期
    alter user 'guest'@'%' password expire;

    ~ 修改用户名和主机
    rename user 'guest'@'%' to 'my_guest'@'192.168.100.%';

    ~ 删除用户
    drop user if exists 'guest'@'%';

12. 使用TCL实现事务管理
    ~ 事务:把多个对数据的操作视为不可分割的原子性操作,要么全做,要么全不做
    ~ ACID特性:
        - 原子性 - Atomicity
        - 一致性 - Consistency
        - 隔离性 - Isolation
        - 持久性 - Duration
     ~ 并发数据访问的五类问题 - 锁机制 - 保护数据
        - 脏读
        - 不可重复读
        - 幻读
        - 第一类丢失更新
        - 第二类丢失更新
    ~ 事务隔离级别 - 通过设置事务隔离级别让数据库选择适当的锁来保护数据
        - READ UNCOMMITTED
        - READ COMMITTED
        - REPEATABLE READ
        - SERIALIZABLE
    ~ 查看事务隔离级别
    show variables like 'transaction_isolation';

    ~ 修改事务隔离级别
    set session transaction isolation level read committed;
    set  global transaction isolation level read committed;

    ~ 开启事务环境
    start transaction;

    ~ 提交事务
    commit;

    ~ 回滚事务
    rollback;

13. Python程序接入MySQL数据库
    pip install pymysql cryptography

    ~ 创建连接 - pymysql.connect(host, port, user, password, database, charset) - Connection
    ~ 获取游标 - conn.cursor() - Cursor
    ~ 执行SQL - cursor.execute() / cursor.executemany() - int
    ~ 两种情况:
        - 写数据:提交或回滚 - conn.commit() / conn.rollback()
        - 读数据:通过游标抓取 - cursor.fetchone() / cursor.fetchall() / cursor.fetchmany(size)
    ~ 关闭连接 - conn.close()

14. 视图 - view - 查询的快照 - 命名查询
    ~ 作用:
        - 实现对数据的预处理 - 数据分析师
        - 隐藏表结构
        - 将访问权限控制到列
        - 实现对查询的复用
    ~ 限制:
        - 视图可以嵌套 - 基于视图创建视图
        - 视图中的排序会被查询的排序覆盖
        - 视图无法使用索引,不会激发触发器

    ~ 创建或替换视图
    create or replace view view_name as select ...;

    ~ 删除视图
    drop view if exists view_name;

15. 函数 - function - 封装功能上相对独立且会被重复使用的代码
    ~ 获取帮助
        - help 'functions'; / ? functions;
        - help 'window functions'; / ? window functions;
        - help 'first_value'; / ? first_value;
    ~ MySQL内置函数
        - 聚合函数
            ~ 描述性统计信息 - sum() / avg() / count() / max() / min() / var_pop() / var_samp() / stddev_pop() / stddev_samp()
            ~ 其他 - group_concat() / json_arrayagg() / json_objectagg()
        - 数值函数
            ~ 绝对值和符号函数 - abs() / sign()
            ~ 取整和四舍五入 - ceiling() / floor() / round() / truncate()
            ~ 三角和反三角函数 - sin() / cos() / tan() / cot() / asin() / acos() / atan()
            ~ 指数和对数 - pow() / exp() / log() / log10() / log2()
            ~ 随机数 - rand()
            ~ 弧度和角度 - degrees() / radians()
            ~ 平方根 - sqrt()
        - 字符串函数
            ~ 长度 - char_length() / length()
            ~ 拼接 - concat()
            ~ 大小写 - lower() / upper()
            ~ 取子串 - left() / right() / substring()
            ~ 替换 - replace()
            ~ 修剪 - trim() / ltrim() / rtrim()
            ~ 定位 - instr() / locate()
            ~ 填充 - lpad() / rpad()
            ~ BASE64编解码 - from_base64() / to_base64()
            ~ 反转 - reverse()
        - 日期时间函数
            ~ 获取日期和时间 - current_timestamp() / current_date() / current_time()
            ~ 获取部分信息 - date() / time() / year() / quarter() / month() / day() / weekday() / hour() / minute() / second()
            ~ 计算时间差 - datediff() / timestampdiff()
            ~ 添加间隔 - date_add() / date_sub()
            ~ 格式化日期时间 - date_format()
        - 流程控制函数
            ~ if() / ifnull() / coalesce() / nullif()
        - 窗口函数
            ~ 排名 - rank() / dense_rank() / row_number() / percent_rank()
            ~ 取数 - lag() / lead() / first_value() / last_value() / nth_value()
        - 其他函数
            ~ 类型转换 - cast() / convert()
            ~ 信息获取 - current_role() / current_user() / database() / last_insert_id() / version() / user()
            ~ 全局唯一标识符 - uuid() / uuid_to_bin() / bin_to_uuid()
    ~ UDF - 用户自定义函数
        - 关键词 - create function
        - 函数名(参数列表) 返回类型
        - 修饰符
            ~ deterministic- 指示函数具有确定性 - 输入相同输出相同,有利于优化查询和缓存
            ~ no sql - 函数不会访问或修改数据库中的数据 - 提高执行效率和安全性
            ~ reads sql data - 函数可能会读取但不会修改数据库中的数据
        - 函数执行体 - begin ... end

    ~ 创建函数
    delimiter $$

    create function func_name(param_name data_type, ...)
    returns data_type deterministic
    begin
        declare ...;
        ... ... ...;
        return ...;
    end $$

    delimiter ;

    ~ 删除函数
    drop function if exists func_name;
    
    ~ 调用函数
    select func_name(param1, param2);

16.(存储)过程 - stored procedure - 一组预定义的可以重复使用的SQL语句集合
    ~ 过程的作用
        - 封装和代码复用
        - 减少交互次数,提升性能
        - 事务控制和安全性
        - 减少网络开销
    ~ 创建过程
    delimiter $$

    create procedure procedure_name(param1 data_type, ...)
    begin
        declare ...;
        ... ... ...;
    end $$

    delimiter ;

    ~ 调用过程
    call procedure_name(x, y, z);

    ~ 删除过程
    drop procedure if exists procedure_name;

17. 索引 - 类似于书的目录 - 加速查询
    ~ 执行计划 - explain
        - select_type
        - table
        - type - 查询类型
            ~ const - 常量级查询 - 性能最好
            ~ eq_ref - 唯一索引扫描 - 性能很好
            ~ ref - 非唯一索引扫描 - 性能比较好
            ~ range - 索引范围扫描 - 性能还行
            ~ index - 索引全扫描 - 性能很差
            ~ ALL - 全表扫描 - 性能最差
        - possible_keys - 可能用到的索引
        - key - 实际用到的索引
        - key_len - 索引的长度
        - rows - 预估扫描的行数 - 行数越少查询效率越高
        - extra - 额外的信息
    ~ 索引相关概念 - InnoDB - B+树
        - B+树是一个多叉树,层级很少(3-4层),所有它的I/O性能特别的好
        - 聚集索引 - 索引组织表 - 数据就根据主键排序放在索引中 - 只有一个
        - 非聚集索引 - 二级索引 - 额外创建一棵树来加速数据检索 - 回表
        - 前缀索引/复合索引
        - 索引覆盖查询和回表
            ~ index covered query - 要投影的字段已经被索引覆盖到,此时不需要回表,性能非常好
            ~ 回表 - 投影的字段没有被索引完全覆盖到,需要重新通过主键定位到数据,性能会受到影响
        - 函数索引
        - 不可见索引
        - 索引设计要点
            ~ 注意索引的最左匹配原则,避免失效的情况
            ~ 在作为查询条件的字段上建索引(覆盖到where子句)
            ~ 避免额外排序(索引覆盖到order by子句的字段)
            ~ 避免回表(让索引覆盖到查询要投影的列 - 复合索引)
            ~ 索引不是越多越好 - 索引加速了查询但是让增删改变得更慢 - 索引更新问题
    
    ~ 创建索引
    create index index_name on table_name (field_name1, field_name2,  ...);

    ~ 删除索引
    drop index index_name on table_name;
    alter table table_name drop index index_name;

    ~ 设置索引可见性(MySQL8新特性)
    alter table table_name alter index index_name invisible;
    alter table table_name alter index index_name visible;

18. 其他相关知识
    ~ MySQL三种类型的变量
        - 系统变量 - transaction_isolation / max_connections
        - 用户变量
            ~ set @x = 10;
            ~ select @x := 10;
        - 局部变量 - 通过declare进行声明
    ~ 数据备份
        - 导出数据
            ~ 导出到文本文件 - select ... into outfile '...';
            ~ Python脚本代码 - CSV / Excel
            ~ 图形化客户端工具
        - 导入数据
            ~ load data infile ...;
            ~ Python脚本代码 - CSV / Excel
            ~ 图形化客户端工具
        - 导出SQL
            ~ mysqldump -u root -p school > school1.sql
            ~ mysqldump -u root -p --databases school > school2.sql
        - 导入SQL
            ~ mysql -u root -p school < school1.sql
            ~ mysql -u root -p < school2.sql
        - 停机冷备份 - 停机 - 复制数据文件
        - 联机热备份
            ~ Percona XtraBackup
            ~ MySQL Enterprise Backup
    ~ 临时表
        - create temporary table ...;
    ~ 虚拟列和计算列
        - alter table tb_emp add column ann_sal int as (sal * 14 + comm * 12);
    ~ 触发器(trigger) - 千万不要用
        - 可能存在行级锁升级为表锁的风险,严重影响性能(难道不担心锁表的风险吗)
        - 可能存在诸多隐式操作,在不知情的情况下修改数据或者提交回滚事务,维护成本高
    ~ 表分区 - 加速查询 - RANGE分区 / LIST分区 / HASH分区
    ~ 主从复制 - 读写分离
    ~ 分表分库 - 数据切片 - 数据库中间件 - Vitess / ShardingSphere / Cobar / Mycat / Gaea
    ~ JOIN连接算法
        - 嵌套循环连接 - nested loop join - OLTP业务 - (驱动表)数据量小,语句简单,存在索引
            ~ 驱动表 - 可以通过explain进行查看
                - 左外连接时,左表是驱动表;
                - 右外连接时,右表是驱动表;
                - 内连接时,哪个表的数据更少,哪个表就是驱动表
            ~ OLTP - online transaction processing - 业务查询(开发) - 效率高、延迟低
        - 哈希连接 - hash join - OLAP业务 - 数据量大,关联表多,语句复杂,连接条件无索引
            ~ OLAP - online analysis processing - 分析查询(数据分析师)- 允许高延迟
    ~ CTE - Common Table Expression - 公共表表达式
        - 使用场景 - 需要在同一查询中多次引用相同的子查询的结果
        - 具体语法
            with cte_name (column1, column2, ...) as (
                select ... from ...
            )
            select ...
            from cte_name
            where ...;
        - 递归查询
            with recursive Q as (
                select eno, ename, mgr 
                  from tb_emp where eno = 7800
                 union all
                select P.eno, P.ename, P.mgr
                  from tb_emp as P inner join Q on P.mgr = Q.eno 
            )
            select * from Q;
    ~ SQL注射攻击 - SQL Injection
    ~ 范式理论和反范式设计
        - 范式级别(规范程度)越高,数据冗余越低,数据操作异常越少
        - 1NF - 列不可分割(单值列)- JSON类型显然是违背了1NF的设计
        - 2NF - 满足1NF + 非主键列必须完全依赖于主键列
        - 3NF - 满足2NF + 消除传递依赖
        - 4NF - 满足3NF + 消除非平凡多值依赖
        - 反范式 - 违反范式理论 - 增加冗余数据或违反范式规则来达到以下目标
            ~ 提高查询性能
            ~ 简化数据操作
            ~ 空间换取时间
    ~ 建表必备的三个字段 - xxx_id / xxx_created / xxx_updated
    ~ 慢查询日志
        - show variables like '%slow_query%';
        - set global slow_query_log = on;
        - set global long_query_time = 3;
    ~ insert相关
        - 如果有多个连接向同一个表插入数据,使用insert delayed可以获得更好的性能
        - 将查询结果插入到表中 - insert into table_name ... select ...;
    ~ SQL查询提示
        - use index - 建议使用指定的索引
        - ignore index - 建议忽略掉指定的索引
        - force index - 强制使用指定的索引


网友评论

相关作品