关系型数据管理系统

124 阅读6分钟

关系型数据模型

表的组成:

  • 列(Column):一个属性,有明确的数据类型(原子类型,不可再分)

  • 行(Row):一个记录(tuple, record)

  • 数学定义K列的表:{<t1, …, tk> | t1 属于 D1, … , tk 属于 Dk }

    • Di:第i列可能取值的集合

Schema vs. Instance

  • Schema: 类型,一个表的类型是由每个列的类型决定的

    • 只需要定义一次
  • Instance: 具体取值,具体存储哪些记录,每个列的具体值由具体应用决定的

    • 对应多个instance

Key (键)

  • Primary key (主键):唯一确定本表中的一个记录

  • Foreign key (外键):是另一个表的Primary key,唯一确定另一个表的一个记录

SQL语言

-- 表创建
create table TakeCourse ( 
    CourseID integer NOT NULL,  
    StudentID integer NOT NULL,  
    Year year, 
    Semester enum(Spring, Summer, Fall), 
    Grade float, 
    primary key (CourseID, StudentID), 
    foreign key (CourseID) references Course(ID), 
    foreign key (StudentID) references Student(ID) 
);

-- 插入
insert into Student(ID, Name) values (131234, ‘张飞’);
insert into Student values (131234, ‘张飞’, 1995/1/1, M, ‘计算机’, 2013, 85);

-- 删除
delete from Student where ID = 131234;

-- 更新
update Student set GPA = 86 where ID = 131234; 

-- 查找
select 列名,…,列名 
from 表,…, 表 
where 条件 
group by 列名,…,列名 
having 条件 
order by 列名,…,列名

-- 选择与投影
select Name, GPA from Student where Major = ‘计算机’;
-- 等值连接
select Student.Name, Course.Name 
from Student, Course, TakeCourse 
where TakeCourse.CourseID = Course.ID and TakeCourse.StudentID = Student.ID;
-- group by + having + order
select Major, count(*) as Cnt 
from Student 
where Year >= 2013 and Year <= 2014 
group by Major 
having Cnt >= 2;
order by Cnt desc;

已知 Student.GPA 为截止上学期的平均成绩,需要重新计算每位学生的GPA

select Student.Name, avg(Grade) as NewGPA
from TakeCourse, Student
where TakeCourse.StudentID = Student.ID
group by Student.ID, Student.Name;

数据库系统架构

RDBMS的系统架构(单机)

  1. 语法分析器:SQL 语句的程序 -> 解析好的内部表达

    1. 语法解析,语法检查,表名、列名、类型检查
  2. 查询优化器:SQL内部表达 -> Query Plan (执行方案)

    1. 产生可行的query plan,估计运行时间和空间代价,选择最佳的query plan
  3. 执行引擎:query plan -> SQL语句的结果

    1. 根据query plan,完成相应的运算和操作:数据访问、关系型运算的实现
  • Transaction management:事务管理

    • 实现ACID、logging写日志,locking加锁、保证并行transactions事务的正确性
  • Buffer pool: 在内存中缓存硬盘的数据

    • 局部性原理,提高性能,减少I/O
  • Data storage and indexing

    • 如何在硬盘上存储数据,如何高效地访问硬盘上的数据

数据存储与访问

索引

  • Tree based:有序,支持点查询和范围查询
  • Hash based:无序,只支持点查询
  • Clustered(主索引):记录就存在index中,记录顺序就是index顺序
  • Secondary(二级索引): 记录顺序不是index顺序,index中存储page ID和in‐page tuple slot ID.

运算的实现

  • Operator tree:Query plan 最终将表现为一棵Operator Tree

    • 每个节点代表一个运算,运算的输入来自孩子节点,运算的输出送往父亲节点

  • Selection & Projection

    • Selection: 行的过滤,支持多种数据类型:数值类型,字符串类型等,实现比较操作、数学运算、逻辑运算

    • Projection: 列的提取,Query plan生成时,同时产生中间结果记录的schema

      • 主要功能:从一个记录中提取属性,生成一个结果记录
  • Join

    • Nested loop Join

      • foreach tuple r in R { 
            foreach tuple s in S { 
                if (r.a = s.b) output(r,s); 
            } 
        }
        R 有 Mr 个Page 
        S 有 Ms 个Page 
        每个Page有 B 个记录
        总共读的page数: Mr(1+ BMs),I/O成本太大了!
        
    • Block Nested Loop Join:内存大小为M,外循环每次读入M页的R,而不是一条R的记录,内循环读一遍S

      • Mr(1+ Ms/M)
    • Index Nested Loop Join:相当于加了一个hash,匹配才读取,很少有匹配时,效率很高

    • foreach tuple r  R {
          lookup index to look for match s in S
          if (found) output(r,s);
      }
      
  • Hashing

    • Simple hash join:读R建立hash table;读S访问hash table找到所有的匹配

      • R比内存大怎么办?分片:PartitionID = hash(join key) % PartitionNumber
    • GRACE Hash Join:对R和S进行I/O partitioning

      • for (j=0; j< ParitionNumber; j++) { 
            simple hash join计算Rj ⋈ Sj ; 
        }
        读2Mr + 2Ms个Page,写Mr + Ms个Page,I/O成本是线性的!
        
  • Sorting:把R和S分段排序,可以Merge(归并)找出所有的匹配

    • 通常代价比Hash Join稍差,当一个表已经有序的情况下,会被使用

事务处理

ACID

  • Atomicity(原子性):要么完全执行,要么完全没有执行
  • Consistency(一致性):从一个正确状态转换到另一个正确状态(正确指:constraints, triggers等)
  • Isolation(隔离性):每个事务与其它并发事务互不影响
  • Durability(持久性):Transaction commit后,结果持久有效,crash也不消失
begin transaction; 
…… 
commit transaction;
…… 
rollback transaction;

可串行化:存在一个顺序,按照这个顺序依次串行执行这些Transactions,得到的结果与并行执行相同

隔离性问题:

  • 脏读:读取别人未提交的数据(写读)
  • 不可重复读:同一事务内,读取同一个数据,值不同(读写)
  • 更新丢失:事务提交前,被其他事务修改了本事务的数据(写写)

解决方法:

  • 悲观锁:

    • 两段锁协议:对每个访问的数据都要加锁后才能访问

    • 互斥锁

    • 读写锁

    • 意向锁:

      • 对行加读、写锁之前,需要获得上级锁粒度的意向锁
      • 目的:低成本实现多粒度的锁
    • 避免死锁:规定lock对象的顺序

  • 乐观锁:

    • 不采用加锁的实现:

      • 读取:读取数据到私有工作区,完成修改
      • 验证:检查事务与其他事务是否有冲突
      • 提交:验证通过,没有发现冲突,那么把私有工作区的修改复制到数据库公共数据中
    • Snapshot Isolation实现: 一个时点的数据库数据状态

      • 在起始时点的snapshot

      • 读:这个snapshot的数据

      • 写:先临时保存起来

      • 在commit时检查有无写冲突,有冲突就abort

Concurrency Control (并发控制)

  • Transactional Logging(事务日志):记录写、commit、Abort操作的全部信息
  • Write‐Ahead Logging:写记录日志,再进行操作
  • 检查点:为了使崩溃恢复的时间可控,不用重新执行所有日志操作

数据仓库

OLTP:Online transaction processing(联机事务处理)

  • 数据库,主要是对数据库中的数据进行增删改查

OLAP:Online Analytical Processing(联机分析处理)

  • 数据仓库,数据量大,星型或雪花模型、记录当前和历史的数据、不支持更新和删除

  • Data Cube(数据立方)

    • rollup、drill down、slice等操作
  • 列式存储:OLAP场景只读取部分列,更容易压缩

分布式数据库

系统架构

  • Shared memory

    • 多芯片、多核或Distributed shared memory
  • Shared disk

    • 多机连接相同的数据存储设备
  • Shared nothing

    • 普通意义上的机群系统,由以太网连接多台服务器

分布式查询处理

  • 分片、副本
  • hash jon

分布式事务处理

  • 2PC:两阶段提交