数据库系统期末复习条记

打印 上一主题 下一主题

主题 999|帖子 999|积分 2997

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
保举几个有关范式的教学视频:


  • 范式判断
  • 将R分解为BCNF
  • 将R分解为3NF
关系代数

概述: 是数据库系统中的一种查询语言,用于对关系模型中的数据进行操作。它提供了一组操作,可以从关系(通常是表格)中派生出新的关系,关系代数是关系型数据库查询的基础之一,能够帮助DBMS(数据库管理系统)实行查询哀求
根本操作

选择(Selection, σ):
选择操作从关系中筛选出满足特定条件的元组(记载)


  • 符号:                                                         σ                                  条件                                          (                               R                               )                                      σ_{条件}(R)                        σ条件​(R)
  • 作用:从关系R中选择所有满足给定条件的元组
  • 例子:假设有一个学生表,包含学生的姓名、年龄、成绩等信息,若要选择年龄大于20岁的学生,可以写成:
                                                                    σ                                                   a                                        g                                        e                                                           >                                  20                                          σ_{age}>20                           σage​>20
投影(Projection, π):
投影操作用于选择关系中的特性属性(列)


  • 符号:                                                         π                                  属性列表                                          (                               R                               )                                      π_{属性列表}(R)                        π属性列表​(R)
  • 作用:从关系R中选择特定的属性列
  • 例子:假如我们只对学生表中的姓名和成绩感兴趣,可以写成:
                                                                    π                                                   n                                        a                                        m                                        e                                        ,                                        s                                        c                                        o                                        r                                        e                                                           (                                  学生                                  )                                          π_{name, score}(学生)                           πname,score​(学生)
    这将返回一个新的关系,包含学生表中的姓名和成绩列
联接(Join, ⨝):
联接操作用于将两个关系中的元组团结起来,形成一个新的关系。常见的联接类型包括:


  • 内联接(Inner Join):返回两个关系中所有匹配的元组
  • 外联接(Outer Join):返回所有匹配的元组以及那些没有匹配的元组(根据差别的外联接类型,如左外联接、右外联接、全外联接,结果会有所差别)
  • 符号:R ⨝ S
  • 例子:假设有两个学生表(包含学生的姓名和学号)和选课(包含学生的学号和课程名称),要找出所有学生及其所选课程的信息:
                                                       学生                                  ⋈                                  选课                                          学生⋈选课                           学生⋈选课
    这表示将学生表和选课表通过学号进行联接,返回包含学生姓名、学号、课程等信息的关系
并(Union, ∪):
并操作用于合并两个关系中的元组,要求两个关系具有相同的属性集合


  • 符号:R ∪ S
  • 作用:返回两个关系中所有差别的元组(对行数据去重)
  • 例子:假如有两个关系学生A和学生B,分别表示两个班级的学生信息,要求得到所有学生的集合:
                                                       学生                                  A                                  ∪                                  学生                                  B                                          学生A ∪ 学生B                           学生A∪学生B
    这表示将两个关系的元组合并,去除重复的学生信息
差(Difference, -):
差操作用于返回存在于第一个关系中但不在第二个关系中的元组


  • 符号:R - S
  • 作用:返回关系R中存在但不在关系S中存在的元组
  • 例子:假如学生A表示某班的学生,学生B表示已到场某测验的学生,那么:
                                                       学生                                  A                                  −                                  学生                                  B                                          学生A - 学生B                           学生A−学生B
    这表示所有未到场测验的学生
笛卡尔积(Cartesian Product, ×):
笛卡尔积操作将两个关系中的所有元组进行组合,天生一个新的关系,新的关系中的每个元组由两个关系中的元组拼接而成


  • 符号:R × S
  • 作用:返回两个关系中所有元组的组合
  • 例子:假设有学生表和课程表,实行笛卡尔积会返回每个学生与每个课程的组合:
                                                       学生                                  ×                                  课程                                          学生 × 课程                           学生×课程
    假如学生表有3个学生,课程表有2门课程,结果将有6个元组
重命名(Rename, ρ):
重命名操作用于给关系或其属性命名:


  • 符号:                                                         ρ                                  新名字                                          (                               R                               )                                      ρ_{新名字}(R)                        ρ新名字​(R)
  • 作用:给关系R重新命名
  • 例子:可以给一个关系重新命名,如:
                                                                    ρ                                     新学生                                              (                                  学生                                  )                                          ρ_{新学生}(学生)                           ρ新学生​(学生)
    这表示将学生表重命名为新学生
复合操作

选择和投影的组合:
假设要查询所有成绩大于80分的学生的姓名和成绩:
                                                    π                                           n                                  a                                  m                                  e                                  ,                                  s                                  c                                  o                                  r                                  e                                                 (                                       σ                                           s                                  c                                  o                                  r                                  e                                  >                                  80                                                 (                            学生                            )                            )                                  π_{name, score}(σ_{score>80}(学生))                     πname,score​(σscore>80​(学生))
联接与其他操作的团结:
假设要查询所有选了”数据库系统“课程的学生的姓名和成绩,可以利用联接与头因操作:
                                                    π                                           n                                  a                                  m                                  e                                  ,                                  s                                  c                                  o                                  r                                  e                                                 (                            学生⨝                                       σ                                           c                                  o                                  u                                  r                                  s                                  e                                  =                                  "                                  数据库系统                                  "                                                 (                            选课                            )                            )                                  π_{name, score}(学生 ⨝ σ_{course="数据库系统"}(选课))                     πname,score​(学生⨝σcourse="数据库系统"​(选课))
SQL

概述: SQL(结构化查询语言)是用于与关系型数据库管理系统(RDBMS)进行交互的标准语言。主要用于操作数据库中的表,每个表由列和行组成。
入门SQL

数据查询(SELECT)

SELECT是SQL中最常用的语句,用于从一个或多个表中检索数据
查询所有列:
  1. SELECT * FROM table_name;
复制代码


  • *:表示所有列
  • table_name:要查询的表名称
查询特定列:
  1. SELECT column1, column2 FROM table_name;
复制代码


  • 只选择column1和column2这两列的数据
利用条件查询(WHERE):
  1. SELECT * FORM table_name WHERE condition;
复制代码


  • WHERE子句用来指定查询的条件
  • 例如,查询所有年龄大于20岁的学生:
    1. SELECT * FROM students WHERE age > 20;
    复制代码
排序查询结果(ORDER BY):
  1. SELECT * FROM table_name ORDER BY column_name [ASC | DESC];
复制代码


  • ORDER BY用来按照某一列对查询结果进行排序
  • 默认是升序ASC,可以利用DESC表示降序
  • 例如,按年龄升序排列学生:
    1. SELECT * FROM students ORDER BY age ASC;
    复制代码
限制查询结果(LIMIT):
  1. SELECT * FROM table_name LIMIT n;
复制代码


  • LIMIT用于限制返回的记载数
  • 例如,查询前5条记载:
    1. SELECT * FROM students LIMIT 5;
    复制代码
数据插入(INSERT)

插入单条记载:
  1. INSERT INTO table_name (column1, column2) VALUES (value1, value2);
复制代码


  • 例如向students表插入一条记载:
    1. INSERT INTO students (name, age, score) VALUES ('John', 22, 90);
    复制代码
插入多条记载:
  1. INSERT INTO table_name (column1, column2) VALUES (value1, value2), (value3, value4);
复制代码


  • 例如:
    1. INSERT INTO students (name, age, score)
    2. VALUES ('Alice', 20, 88), ('Bob', 21, 91);
    复制代码
数据更新(UPDATE)

用于更新表中已存在的记载
  1. UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;
复制代码


  • 例如:更新学生John的分数:
    1. UPDATE students SET score = 95 WHERE name = 'John';
    复制代码
  • 留意:WHERE子句非常紧张,缺少WHERE会更新表中的所有记载
数据删除(DELETE)

用于删除表中的记载:
  1. DELETE FROM table_name WHERE condition;
复制代码


  • 例如,删除年龄小于18岁的学生:
    1. DELETE FROM students WHERE age < 18;
    复制代码
  • 假如没有WHERE子句,所有记载都会被删除
创建数据库和表

创建数据库:
  1. CREATE DATABASE database_name;
复制代码


  • 例如,创建一个名为school的数据库:
    1. CREATE DATABASE school;
    复制代码
创建表:
  1. CREATE TABLE table_name {
  2.         column1 datatype,
  3.         column2 datatype,
  4.         ...
  5. };
复制代码


  • 例如,创建一个学生表students:
    1. CREATE TABLE students (
    2.         id INT PRIMARY KEY,
    3.     name VARCHAR(50),
    4.     age INT,
    5.     score FLOAT
    6. )
    复制代码
修改表结构

ALTER用于修改表结构,如添加、删除列等
添加列:
  1. ALTER TABLE table_name ADD column_name datatype;
复制代码


  • 例如,向student表添加 email列:
    1. ALTER TABLE students ADD email VARCHAR(100);
    复制代码
删除列:
  1. ALTER TABLE table_name DROP COLUMN column_name;
复制代码


  • 例如,删除students表中的email列:
    1. ALTER TABLE students DROP COLUMN email;
    复制代码
删除数据库和表

DROP用于删除数据库中的表或数据库
删除表:
  1. DROP TABLE table_name;
复制代码


  • 例如,删除students表:
    1. DROP TABLE students;
    复制代码
删除数据库:
  1. DROP DATABASE database_name;
复制代码


  • 例如,删除数据库school:
    1. DROP DATABASE school;
    复制代码
根本的SQL函数



  • 聚合函数:

    • COUNT():计算记载数
    • SUM():计算列的总和
    • AVG():计算列的平均值
    • MAX():获取列的最大值
    • MIN():获取列的最小值
    • 例如,查询所有学生的平均成绩:
      1. SELECT AVG(score) FROM students;
      复制代码

  • 字符串函数:

    • CONCAT():将多个字符串毗连起来
    • UPPER():将字符串转换为大写
    • LOWER():将字符串转换为小写
    • 例如,将学生姓名转换为小写
      1. SELECT LOWER(name) FROM students;
      复制代码

多表查询

概述: 也称联接查询,指的是在同一查询中, 涉及两个或多个表的数据操作。多表查询通常用于获取存储在差别表中的干系数据,通过某种条件将它们关联起来,通过多表查询,可以实现更加复杂和机动的数据提取需求。
内联接(INNER JOIN)

概述: 是最常见的多表查询类型,它返回的是两个表中满足联接条件的所有记载,假如某一表中没有匹配的记载,则该记载不会出现在查询结果中
示例:
假设有两个表students表和courses表,分别包含以下内容:


  • students:student_id、name
  • courses:course_id、student_id、course_name
要查询每个学生和他们所选的课程信息,可以利用INNER JOIN:
  1. SELECT students.name, courses.course_name
  2. FROM students
  3. INNER JOIN courses
  4. ON student.student_id = courses.student_id;
复制代码
解释:这条查询通过students.student_id和courses.student_id继续匹配,只返回那些在students 和courses表中有对应记载的学生及课程
外联接(OUTER JOIN)

概述: 与内联接的差别之处在于,外联接返回的是所有匹配记载和不匹配的记载)可以进一步细分为三种类型:左外联接(LEFT JOIN)、右外联接(RIGHT JOIN)、全外联接(FULL OUTER JOIN)
左外联接(LEFT JOIN):
左外联接返回左表(查询中的第一个表)中的所有记载,以及右表(查询中的第二个表)中与左表记载匹配的记载。假如右表没有匹配的记载,结果中的对应部分将显示为NULL
示例:假设想要查询所有学生的信息,以及他们是否选修了某些课程。假如没有选课的学生也需要显示,可以利用左外联接:
  1. SELECT students.name, courses.course_name
  2. FROM students
  3. LEFT JOIN courses
  4. ON students.student_id = courses.student_id;
复制代码
解释:假如某个学生没有选课,那么该学生的course_name将会显示为NULL,但仍会显示学生的name
右外联接(RIGHT JOIN):
右外联接返回右表(查询中的第二个表)中的所有记载,以及左表(查询的第一个表)中与右表匹配的记载。假如左表没有匹配的记载,结果中对应部分将显示为NULL
  1. SELECT students.name, courses.course_name
  2. FROM students
  3. RIGHT JOIN courses
  4. ON students.student_id = courses.student_id;
复制代码


  • 解释:此查询返回所有课程及选修这些课程的学生,假如某个课程没有学生选修,则name列显示为NULL
全外联接(FULL OUTER JOIN):
全外联接返回左表和右表中的所有记载。假如某一边没有匹配的记载,另一边的列会显示为NULL
  1. SELECT students.name, courses.course_name
  2. FROM students
  3. FULL OUTER JOIN courses
  4. ON students.studetn_id = courses.student_id;
复制代码


  • 解释:这条查询返回所有学生和所有课程,假如学生没有选课或课程没有学生选修,则结果中相应部分会显示为NULL
笛卡尔积(CARTESIAN PRODUCT)

概述: 笛卡尔积返回两个表中每个记载的组合,笛卡尔积并不基于任何联接条件,因此结果集可能非常巨大
示例:
假设有两个表:students表(包含3个学生)和courses表(包含2门课程),笛卡尔积的查询语句如下:
  1. SELECT students.name, courses.course_name
  2. FROM students, courses;
复制代码
解释:这条查询会返回所有学生和所有课程的组合,结果为 3 * 2 = 6 条记载,即每个学生都将与每门课程组合成一条记载。
自联接(SELF JOIN)

概述: 自联接是一种特殊的联接,它用于将同一张表与自身进行联接,通常用于查询表中相互关联的数据。
示例:
假设employees表存储了员工信息,包括employee_id和manager_id,通过自联接查询员工及其司理的信息:
  1. SELECT e1.name AS employee_name, e2.name AS manager_name
  2. FROM employees e1
  3. LEFT JOIN employees e2
  4. ON e1.manager_id = e2.employee_id;
复制代码
解释:这套查询将employees表与自身进行联接,e1代表员工,e2代表司理,通过manager_id和employee_id进行匹配,返回每个员工及其对应司理的姓名
团结(UNION)

概述: 团结是将两个或多个SELECT语句的结果合并成一个结果集。UNION会主动去重,假如需要保留重复数据,可以利用UNION ALL
示例:
假设有两个表students_2023和students_2024,分别存储2023年和2024年入学的学生信息,要查询所有学生的姓名,可以利用UNION:
  1. SELECT name FROM students_2023
  2. UNION
  3. SELECT name FROM students_2024;
复制代码
解释:这条查询会返回两个表中的所有学生姓名,而且去除重复的姓名。
中级SQL

子查询(Subquery)

概述: 子查询是嵌套在其他查询语句中的查询。它可以出现在SELECT、FROM、WHERE等子句中,通常用于过滤数据、计算聚合值或作为毗连条件
标量子查询:
返回单一值,可以用在SELECT、WHERE或HAVING子句中
例如,查询每个学生的姓名及其选修课程的数量:
  1. SELECT name,
  2.         (SELECT COUNT(*) FROM courses WHERE courses.student_id = students.student_id) AS course_count
  3. FROM students;
复制代码
解释:这里的子查询返回每个学生选修课程的数量,并将其作为列course_count展示
多行子查询:
返回多行数据,常用于IN或EXISTS中
  1. SELECT name
  2. FROM students
  3. WHERE student_id IN (SELECT student_id FROM courses WHERE course_name = 'Math');
复制代码
解释:该查询返回所有选修Math课程的学生姓名。子查询返回所有选修该课程的学生ID,然后在主查询中通过IN进行匹配
多列子查询:
返回多列数据,常用于WHERE子句中
  1. SELECT name
  2. FROM students
  3. WHERE (student_id, age) IN (SELECT student_id, age FROM students WHERE score > 90);
复制代码
解释:该查询返回所有年龄和分数大于90分的学生姓名
联接进阶引用

天然联接(NATURAL JOIN):
根据两个表中具有相同列名的列主动进行联接,他会主动选择相同列名并按这些列进行联接
  1. SELECT *
  2. FROM employees
  3. NATURAL JOIN departments;
复制代码
解释:NATURAL JOIN会主动辨认两个表中相同的列名进行联接。这个操作等效于实行INNER JOIN和选择相同列的条件。
复合联接条件(Using Clause):
利用USING关键字来指定多个列作为联接条件:
  1. SELECT e.name, d.department_name
  2. FROM employees e
  3. JOIN departments d USING (department_id);
复制代码
解释:USING用于指定两个表中需要联接的列,而且这些列必须具有相同的名字。在这种情况下,联接的条件是deparment_id
聚合函数与分组(GROUP BY)

GROUP BY用于将查询结果分组,并对每个组实行聚合函数(如COUNT、SUM、AVG、MIN、MAX)
GROUP BY 和 HAVING:
HAVING用于过滤分组后的结果,类似于WHERE,但是作用于聚合后的数据
  1. SELECT department_id, AVG(salary)
  2. FROM employees
  3. GROUP BY department_id
  4. HAVING AVG(saraly) > 50000;
复制代码
解释:这条查询会计算每个部分的平均工资,并仅返回平均工资大于50000的部分
GROUP BY多列:
你可以按多个列进行分组,如允许以得到更过细的统计结果
  1. SELECT department_id, job_title, COUNT(*)
  2. FROM employees
  3. GROUP BY department_id, job_title;
复制代码
解释:该查询返回每个部分、职位的员工数量
窗口函数(Window Functions)

概述: 是一类特殊的聚合函数,它可以在查询结果会合为每一行计算一个值,而不需要像GROUP BY那样分组。常用的窗口函数包括ROW_NUMBER、RANK、DENSE_RANK、NTILE等。
ROW_NUMBER():
为查询结果会合的每一行分配一个唯一的序号,通常用于分页查询或排名
  1. SELECT name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rank
  2. FROM employees;
复制代码
解释:该查询返回员工的姓名、工资,并根据工资降序排列,每一行都有一个唯一的排名(rank)
RANK()和DENSE_RANK():
RANK()和DENSE_RANK()用于天生排名,区别在于RANK()会跳过排名(例如,如有两个并列第一名,则第三名跳过),而DENSE_RANK()则不会跳过排名
  1. SELECT name, salary, RANK() OVER (ORDER BY salary DESC) AS rank
  2. FROM employees;
复制代码
解释:这条查询为每个员工计算排名,工资高的员工排名靠前。假如有员工的工资相同,他们的排名也会相同。
事务控制

概述: 事务是指一组作为单一工作单元实行的SQL语句。在事务中,所有的操作要么都成功(COMMIT),要么都失败并回滚(ROLLBACK)
事务的根本操作:


  • BEGIN TRANSACTION:开始一个事务
  • COMMIT:提交事务,生存所有的修改
  • ROLLBACK:回滚事务,打消事务中所有的修改
  1. BEGIN TRANSACTION;
  2. UPDATE employees SET salary = saraly * 1.1 WHERE department_id = 1;
  3. -- 如果没有问题,可以提交事务
  4. COMMIT;
  5. -- 如果出错了,回滚事务
  6. ROLLBACK;
复制代码
视图(VIEW)

概述: 视图是一个虚拟的表,它是一个包含SQL查询的命令查询。视图可以简化复杂查询的利用,进步查询的可读性和复用性
创建视图:
  1. CREATE VIEW top_earning_employees AS
  2. SELECT name, salary
  3. FROM employees
  4. WHERE salary > 100000;
复制代码
这条语句创建了一个视图,该视图返回所有年薪超过10w的员工信息
查询视图:
  1. SELECT * FROM top_earning_employees;
复制代码
查询视图和查询普通表类似
删除视图:
  1. DROP VIEW top_earning_employees;
复制代码
索引(Index)

概述: 是进步查询性能的关键工具,它允许数据库更快速地查找数据,对于经常用作查询条件的列,可以创建索引
创建索引:
  1. CREATE INDEX idx_employee_name ON employees (name);
复制代码
该索引加速了基于name列的查询
删除索引:
  1. DROP INDEX idx_employee_name;
复制代码
高级SQL

复杂查询与高级子查询

干系子查询(Correlated Subquery):
查询条件依赖于外部查询的数据,在实行时,每一行外部查询的记载都将触发一次子查询。
  1. SELECT name
  2. FROM employees e
  3. WHERE salary > (SELECT AVG(salary) FROM employees WHERE department_id = e.department_id);
复制代码
解释:查询薪水高于所在部分平均薪水的员工。子查询是依赖于外部查询的每一行员工的 department_id 来计算该部分的平均薪水。
多层子查询(Nested Subquery):
是嵌套的子查询,通常用于实行更复杂的计算或过滤
  1. SELECT name
  2. FROM employees
  3. WHERE department_id = (SELECT department_id
  4.                        FROM departments
  5.                        WHERE department_name = 'Sales'
  6. );
复制代码
解释:这条查询首先利用内层子查询查找名为 “Sales” 的部分的 department_id,然后在外层查询中利用这个 department_id`来查找所有属于该部分的员工。
存储过程和触发器

概述: 它们可以封装复杂的逻辑,主动化任务或响应特定的变乱。
存储过程(Stored Procedure):
存储过程是一组预编译的SQL语句,可以在数据库中生存并反复调用
  1. CREATE PROCEDURE raise_salary(IN dept_id INT, IN percentage DECIMAL)
  2. BEGIN
  3.         UPDATE employees
  4.         SET salary = salary * (1 + percentage)
  5.         WHERE department_id = dept_id;
  6. END;
复制代码
解释:这个存储过程根据部分ID和百分比增加该部分员工的薪水
触发器(Trigger):
触发器是由特定变乱(如插入、更新、删除)主动触发的SQL代码
  1. CREATE TRIGGER salary_update
  2. AFTER UPDATE ON employees
  3. FOR EACH ROW
  4. BEGIN
  5.         IF NEW.salary > 200000 THEN
  6.                 INSERT INTO salary_updates (employee_id, old_salary, new_salary)
  7.                 VALUES (NEW.employee_id, OLD.salary, NEW.salary);
  8.     END IF;
  9. END;
复制代码
解释:这个触发器会在员工的薪水更新后实行,若薪水超过200000,则将更改记载到salary_updates表中
实体-关系模型

概述: ER模型是一种用于描述和设计数据库结构的概念模型。主要由实体、属性、关系三种根本元素组成, 通过这些元素,我们能够直观地表示现实世界中数据的结构和它们之间的相互关系。
实体(Entity)

概述: 是现实世界可以独立存在并能够被明白描述的对象,通常表示一个表格(关系)的实例。
实体集(Entity Set): 由相同类型的实体组成的集合,例如所有的学生或员工可以构成一个实体集
示例:


  • 学生:一个学生实体可能包括学生的姓名、学号、年龄等信息
  • 图书:一本书的实体可能包括书名、作者、ISBN编号等信息
属性(Attribute)

概述: 是描述实体特征的数据项,它表示实体所拥有的某个详细特征或性子。属性通常用于详细描述实体,而且与实体的实例一一对应
属性的分类:


  • 简单属性(Simple Attribute):不能再进一步分解的属性。例如,”学生姓名“是简单属性
  • 复合属性(Composite Attribute):由多个简单属性组成的属性。例如,地址可能由”街道“、“城市”、“邮政编码”等组成
  • 多值属性(Multivalued Attribute):一个实体可以有多个值的属性。例如,学生的“电话号码”可能有多个
  • 派生属性(Derived Attribute):可以从其他属性中计算得出的属性。例如,学生的“年龄”可以从出生日期计算得出
示例:


  • 学生实体的属性:学号、姓名、出生日期、性别、地址
  • 图书实体的属性:书名、作者、出版日期、ISBN
关系(Relationship)

概述: 表示两个或多个实体之间的联系。关系通过实体之间的联系和约束表示为一个抽象的“关系”,来阐明这些实体如何交互
分类:


  • 一对一关系(One-to-One, 1:1):一个实体会合的每个实体只与另一个实体会合的一个实体干系联。例如一个学生只能有一个身份证,反之一个身份证只能对应一个学生
  • 一对多关系(One-to-Many, 1:N):一个实体会合的每个实体可以与另一个实体会合的多个实体干系联,但后者的每个实体只能与前者的一个实体干系联。例如,一个部分可以有多个员工,但每个员工只属于一个部分
  • 多对多关系(Many-to-Many, M:N):一个实体会合的每个实体可以与另一个实体会合的多个实体干系联。例如,学生和课程之间是多对多关系,一个学生可以选多门课程,一门课程可以有多个学生
ER图

概述: 是ER模型的图形化表示,通过图形化的方式描述实体、属性和关系,帮助设计职员更直观地明白和设计数据库。
ER图的根本符号:


  • 实体:用矩形表示
  • 属性:用椭圆表示,并通过线毗连到相应的实体
  • 关系:用菱形表示,毗连到场关系的实体
  • 主键属性:用双椭圆表示
  • 多值属性:用双椭圆表示
约束: 用来限制数据的合法性和有效性。常见的约束有:


  • 基数约束(Cardinality Constraint):描述实体之间的关系数量限制。例如,学生与课程的关系是多对多的,这意味着每个学生可以选多门课程,反之,每门课程也可以被多个学生选修
  • 到场约束(Participation Constraint):描述一个实体是否必须到场某个关系。它分为全到场和部分到场:

    • 全到场:表示实体必须到场某个关系
    • 部分到场:表示实体可以到场,也可以不到场某个关系

扩展:


  • 弱实体(Weak Entity):表示没有充足属性来唯一标识的实体。通常,弱实体依赖于一个或多个强实体来标识。例如,订单项(OrderItem)依赖于订单(Order)来唯一标识
  • 继续(Inheritance):表示实体集之间的继续关系,通常是在面向对象的数据库设计中利用。例如,一个员工实体可以是全职员工和兼职员工的父类,后者继续了前者的属性
数据库设计

目标:


  • 提供高效的数据存取
  • 包管数据的完整性和一致性
  • 低落数据冗余
  • 使数据库易于扩展和维护
设计过程

需求分析: 明白数据库需要存储什么样的数据,这些数据之间的关系是什么,如何利用这些数据
概念设计(Conceptual Design): 从业务需求出发,抽象出一个全面的数据类型,并利用ER模型来描述数据和它们之间的关系


  • 实体集:定义要存储的主要数据对象
  • 属性:定义每个实体的特性
  • 关系:定义实体之间的联系
逻辑设计(Logical Design): 将概念设计转换为详细的数据库模型,通常是关系模型。逻辑设计的目标是确定如何将实体-关系模型(ER模型)转换为数据库的表结构。
步调:


  • 实体转换为表格:每个实体集通常转换为一个数据库表(关系)。表的每一行代表一个实体实例,表的每一列代表实体的属性
  • 关系转换为外键:实体之间的关系(如一对多、一对一、多对多)需要用外键(Foreign Key)来表示。例如,一个学生选修课程的关系可以用学生表的外键来表示学生与课程之间的关系。
  • 规范化(Normalization):规范化是关系模型中一种用于减少冗余数据和防止数据差别的过程。通过分解大表,确保表结构的高效性和一致性
规范化:目的是减少数据冗余和数据异常,规范化有多个级别,常见的有:


  • 第一范式(1NF):要求每个字段的值都是原子性的,即不可再分的
  • 第二范式(2NF):在1NF的基础上,要求表中的每个非主属性都完全依赖于主键
  • 第三范式(3NF):在2NF的基础上,要求表中的非主属性不依赖于其他非主属性
  • BCNF:是3NF的进一步强化,要求每个决定因素都是候选键
在实际的设计中,有时为了优化查询性能,可以适当进行反规范化,即引入冗余数据来提升查询服从
物理设计(Physical Design): 是将逻辑模型转换为实际的数据库实现。它关注如何优化数据存储和访问性能


  • 数据存储结构:确定命据在硬盘上的存储方式。选择适当的数据存储结构(例如B树、哈希表)和索引结构,以进步查询和更新的服从
  • 索引(Index):索引是加速查询操作的一种数据结构,它通过为表中的一列或多列创建索引,来进步查询速率。常见的索引类型有:

    • 单列索引:针对表中的单一列创建索引
    • 复合索引:针对表中的多个列创建索引
    • 唯一索引:确保某列的数据值是唯一的
    • 全文索引:用于文本数据的全文搜刮

  • 存储优化:选择合适的存储介质和存储方式(例如,表空间、分区、压缩等)来优化数据库性能
  • 数据分区(Partitioning):将大型表分割成较小的部分,以进步查询性能和数据库维护的服从,常见的分区方法有:

    • 范围分区(Range Partitioning):根据数据范围将数据分区
    • 哈希分区(Hash Partitioning):根据数据值的哈希值进行分区
    • 列表分区(List Partitioning):根据预定义的值将数据分区

数据库实施: 涉及将设计好的数据库模型实现到实际的数据库管理系统中


  • 利用SQL语句创建数据库结构
  • 输入数据并进行出测试
  • 根据需求调整数据库结构和索引
数据库测试与优化:


  • 查询优化:通过分析查询实行计划、索引涉及、表结构调整等来优化查询性能
  • 数据完整性和一致性检查:确保数据遵循业务规则,而且在各种操作下保持一致性
  • 事务管理和并发控制:确保多个事务在并发操作时不会引发数据冲突或不一致
关键概念

超键、候选键、主键与外键:


  • 超键(Superkey):是一个属性集,能够唯一标识关系模式中的每一元组,可以包含冗余属性
  • 候选键(Candidate Key):是最小的超键,不能删除任何属性,否则无法我i一标识元组
  • 主键:从候选键选出一个作为主键,表中的唯一标识符,用于唯一标识每一行数据,每个表只能有一个主键
  • 外键:表中的字段,它引用另一个表的主键,表示两个表之间的关联。外键用于维护表之间的关系完整性
数据完整性约束(Data Integrity Constraints): 用来确保数据库中数据的准确性和可靠性的规则:


  • 实体完整性(Entity Integrity):确保每个表都有唯一主键
  • 参照完整性(Referential Integrity):确保外键字段的值在干系表中存在
  • 域完整性(Domain Integrity):确保字段的数据值符合预定义的域
  • 用户定义完整性(User-Defined Integrity):由用户自定义的规则或约束,通常用于表示业务逻辑
事务(Transaction): 是数据库操作的一个根本单位,由一组SQL语句组成,实行这些语句要包管原子性、一致性、隔离性和持久性(ACID属性)。在设计时,需要考虑事务的并发控制和数据一致性
检索

存储

数据库存储结构

行(Tuple):
数据库中的一行数据称为行(在RDBMS中也叫元组或记载)。一行数据是按列存储的,每一列对应一个属性(字段)。行存储在页中,每个页可以存储多行
页(Page):
数据库的根本存储单元是页(也叫块block),一个页通常由一块固定大小的内存或磁盘空间组成(常见大小为4KB、8KB、16KB等)。数据表、索引、以及其他数据库对象中的数据都是在页中存储的


  • 页头:包含一些元数据,例如页的标识符、页的类型(数据页、索引页等)、页的状态(已利用、空闲等)
  • 数据区:实际存储数据的地区。每个页可以存储多行数据记载
文件(File):
多个页可以组成一个文件。数据库表、索引等对象通常由对应的文件,这些文件会存储数据记载、索引信息或其他数据库对象
文件组织方式

概述: 指在物理存储介质上如何组织数据库文件以及如何高效地存储、访问这些文件。文件组织的差别方式影响到数据检索的速率和服从。
堆组织(Heap Organization):
是最简单的文件组织方式,其中数据行是无序地插入到文件中的。每当有新纪录插入时,数据将直接追加到文件的末尾。
特点:


  • 简单、插入操作开销小
  • 查询服从低
  • 适用于数据量小或不常查询的场景
顺序组织(Sequential Organization):
是将数据行按照某个列的值进行排序,而且数据在文件中按照顺序存储。
特点:


  • 查询服从较高,特别是范围查询和按顺序检索
  • 插入操作较慢,由于要包管数据顺序
  • 删除操作可能导致空间碎片,需要定期整理
  • 适用于查询中有大量范围检索或顺序扫描的场景
哈希组织(Hash Organization):
通过哈希函数将数据映射到一个预定大小的桶中。对于某些特定字段(如主键或其他唯一标识符),可以通过哈希算法来定位数据的位置
特点:


  • 查询服从高,特别是对于准确查找
  • 不支持范围查询,由于哈希是无序的
  • 插入和删除操作通常较为高效
  • 碰到哈希冲突时,系统需要采取一定的冲突办理策略(如链式法、开放地址法)
B+树组织(B+ Tree Organization):
是一种多路均衡树,广泛应用于数据库索引的文件组织中。所有数据都存储在叶子节点中,而内部节点仅存储索引信息。B+树的叶子节点通过链表毗连,支持高效的范围查询
特点:


  • 支持高效的查询、插入、删除操作,尤其适合于范围查询
  • 适合处置惩罚大量数据,具有较好的均衡性,查询性能优良
  • 支持动态更新,数据量增大时也能保持均衡
B树组织(B Tree Organization):
是一种多路均衡树,类似于B+树,差别之处在于,B树的内部节点也存储实际的数据记载
特点:


  • 支持高效的查找、插入和删除操作
  • 不适合范围查询,由于数据存储在内部节点中
  • 在某些情况下,由于数据存储在内部节点,B树的内存服从较差
索引

概述: 是进步数据库查询性能的关键技术,可以快速定位数据的位置
聚焦索引(Clustered Index):
将数据表的物理存储顺序与索引顺序一致,表中的数据行按照索引的顺序存储。在一个表中,只能有一个聚焦索引
特点:


  • 查询性能高,尤其是范围查询
  • 插入和删除操作可能导致索引的重排
非聚焦索引(Non-Clustered Index):
是指索引结构与数据表的存储顺序无关。索引记载中生存了数据表中记载的物理地址或主键值
特点:


  • 支持多个索引
  • 查询速率较快,但比聚焦索引稍慢
  • 插入和删除较快,由于数据的物理顺序不受影响
唯一索引(Unique Index):
确保某一列(或多列)中的值唯一,它在包管数据完整性的同时,也进步了查询速率
特点:


  • 适用于需要确保唯一性的字段,如主键、唯一约束等
  • 进步查询服从,同时制止重复数据
全文索引(Full-text Index):
用于全文检索,特别适用于大规模文本数据的检索,它可以创建一个词汇表,映射每个单词的位置
特点:


  • 对于文本数据,尤其是内容查询非常高效
  • 不适合结构化数据,通常用于文章、评论等文本内容的搜刮
存储优化

数据压缩: 通过减少存储空间来进步存储服从


  • 无损压缩:包管压缩后的数据可以完全恢复
  • 有损压缩:通过丢弃一些冗余数据来减少存储空间
分区和分片:
分区是将表的数据按某些标准(如日期、地理位置等)分割到多个物理文件中
分片是将数据库的差别部分(如差别的数据表或数据库)分散存储在差别服务器上
缓存:
DBMS会利用缓存(内存中的缓存或磁盘缓存)来加速对频仍访问数据的读取。通过利用高速缓存,可以明显减少磁盘IO操作,进步查询性能
查询处置惩罚

概述: 负责将用户的查询哀求转换为数据库能够实行的详细操作,并在尽可能高效的方式下实行查询。
查询解析

概述: 将用户输入的查询转换为数据库能够明白的内部表示形式的过程。该过程由查询解析器(Parser)来实行。
词法分析和语法分析:


  • 词法分析(Lexical Analysis):将输入的SQL查询字符串分解成一系列的tokens,例如关键字、表名、列名、操作符等
  • 语法解析(Syntax Analysis):根据SQL的语法规则,将tokens组织成一个语法树或解析树。这一阶段会检查SQL查询的语法是否准确,并天生一个树形结构,表示SQL查询的结构化信息
天生查询树:
是一个抽象语法树(AST),表示查询的逻辑结构。
查询优化

概述: 为查询天生一个高效的实行计划
查询实行计划:
Query Execution Plan 是数据库系统实行查询时所采用的详细步调序列。实行计划包含了如何访问数据、如何毗连差别表、如何实行操作(如排序、过滤等)等信息
常见的实行计划:


  • 选择(Selection):从表中筛选出符合条件的行
  • 投影(Projection):选择需要显示的列
  • 毗连(Join):将多个表的数据根据毗连条件组合起来
  • 排序(Sort):对数据进行排序操作
  • 聚合(Aggregation):进行数据的汇总、分组等操作
查询优化的目标:
最优实行计划通常具有以下特点:


  • 最小的IO成本:尽可能少地访问磁盘
  • 最小的计算成本:尽可能少地进行计算,制止不必要的操作
  • 最小的内存利用:尽量减少内存的利用量,制止内存溢出
查询优化策略:


  • 选择谓词推送(Predicate Pushdown):将查询中的过滤条件(WHERE 子句)尽早地应用于数据,减少不必要的行的读取
  • 投影谓词推动(Projection Pushdown):将查询中的投影条件(SELECT 子句)尽早地应用于数据,减少传递不必要的列
  • 毗连顺序优化(Join Order Optimization):确定毗连多个表的最优顺序,差别的毗连顺序可能会大幅度影响查询服从
  • 索引利用:查询优化器可能会选择合适的索引来加速数据检索过程。通过利用索引,可以制止全表扫描,直接定位到需要的行。
  • 视图合并(View Merging):对于复杂查询,优化器可以考虑合并视图或子查询,制止不必要的中心结果。
代价估算:
查询优化器会根据数据统计信息(如表的大小、列的基数、索引的选择性等)来估算实行差别计划的代价。通常,代价会以某种形式的成本度量(如 CPU 时间、磁盘 I/O、内存利用量等)来表示。优化器会选择代价最小的实行计划。
启发式优化与成本基优化:


  • 启发式优化:利用经验规则和启发式方法来天生和优化实行计划。启发式优化不考虑所有可能的实行计划,但通过一些简单规则来尽量提升性能。
  • 成本基优化:通过详细计算差别实行计划的代价,并选择最优的实行计划。成本基优化通常需要对每个操作的代价进行估算,并选择代价最小的方案。
联接实现

嵌套循环联接(Nested Loop Join, NLJ)

概述: 是一种常用的数据库联接算法,特别适用于没有索引大概联接的列没有排序的情况
主要步调:

  • 外层循环:选择一个表作为外层表,通常是较小的表,在外层循环中,逐行扫描外层表的每一行记载
  • 内层循环:对于外层表中的每一行记载,扫描另一个表(内层表)的每一行记载
  • 比较:对于外层表和内层表的每一对记载,实行毗连条件的比较。
伪代码:
  1. for each row r1 in Table1:
  2.         for each row r2 in Table2:
  3.                 if r1 and r2 satisfy the join condition:
  4.                         ADD (r1, r2) to the result set
复制代码
块嵌套循环联接(Block Nested Loop Join, BNLJ)

概述: 是NLJ的改进算法,旨在减少内存的消耗并进步服从
主要步调:

  • 分块:首先将关系R和S按照块大小B进行分块,确保每次扫描一个数据库可以完全加载到内存中
  • 外层循环:从外部关系R中取出一个数据块
  • 内存循环:

    • 对于每一个外部快,扫描内部关系S中的每个数据块
    • 对表里两个块中的每对元组进行毗连操作,找出符合联接条件的元组

性能优化:


  • 内存利用:BNLJ利用内存缓存多个块,减少了磁盘IO的频仍访问
  • 减少IO操作:BNLJ通过加载数据块而不是单独的元组,明显减少了磁盘访问的次数
事务恢复

概述: 确保数据库出现故障时能够恢复到一致状态
事务

事务恢复的目标 :


  • 持久性(Durability):即使发生故障,已提交的事务结果也不会丢失
  • 原子性(Atomicity):事务要么全部成功,要么完全不做更改。假如事务在实行过程中出现故障,数据库需要回滚(undo)事务操作,恢复到事务实行前的状态
  • 一致性(Consistency):事务应将数据库从一个一致的状态转换到另一个一致的状态。即使发生故障,事务实行后的状态应满足数据库的约束条件
  • 隔离性(Isolation):事务的实行不应受到其他事务的影响。恢复过程中,要包管正在实行的事务互不干扰
故障类型:


  • 系统崩溃:如操作系统崩溃、硬件故障、突然断电等
  • 媒体故障:如磁盘损坏,数据文件丢失
  • 事务故障:事务在实行过程中由于逻辑错误、死锁等问题被中止或回滚
  • 存储故障:如数据库日志损坏,导致恢复时缺少关键数据
事务日志(WAL):
日志的作用:记载了数据库操作的详细信息,包括每个事务的开始、提交和混滚操作,数据修改前后的值等。
日志格式:


  • 写操作日志:记载每个修改操作的详细信息,包括修改前的数据和修改后的数据
  • 事务开始日志:记载了事务的启动,包括事务ID
  • 事务提交日志:记载事务的提交,表示该事务的修改已持久化
  • 事务回滚日志:记载事务的回滚,打消该事务的所有修改
恢复的根本过程:

  • 分析阶段:恢复系统会扫描日志文件,找出所有已经提交的事务,未提交的事务以及在故障发生前已实行的操作。
  • 重做阶段(Redo):系统会重新实行日志中已经提交的事务,确保所有已提交的事务操作已经持久化
  • 回滚阶段(Undo):系统会打消所有未完成的事务(包括崩溃前已开始但未提交的事务),恢复它们开始前的状态。
并发控制

概述: 是指在多个事务并行实行时,确保它们能够互补干扰且不会破坏数据库的一致性和完整性的机制。
问题

丢失更新(Lost Update):
假如两个事务都读取同一数据并进行更新,且更新操作没有同步,就可能导致其中一个事务的更新被另一个事务的更新覆盖,造成数据丢失
脏读(Dirty Read):
是指事务A读取了事务B修改但未提交的数据。假如事务B回滚,事务A就会读到无效数据。
不可重复读(Non-repeatable Read):
发生在同一事务内多次读取相同数据时,由于其他事务修改了数据,导致读取到差别的值
举例:


  • 事务T1读取帐户余额为100
  • 事务T2修改帐户余额为120并提交
  • 事务T1再次读取帐户余额是,得到120,而第一次读取时是100
幻读(Phantom Read):
指的是同一事务内多次查询数据时,由于其他事务插入、删除或修改了数据,导致查询结果发生变革
举例:


  • 事务T1查询符合条件的帐户列表,结果是10个帐户
  • 事务T2插入了一个新帐户并提交
  • 事务T1再次查询时,发现结果是11个帐户
目标

主要目标时保障DBMS中的事务隔离性
事务的隔离性通常有4个级别:


  • 读未提交(Read Uncommited):事务可以读取未提交事务的数据,容易出现脏读问题
  • 读已提交(Read Commited):事务只能读取已提交事务的数据,但可能会出现不可重复读
  • 可重复读(Repeatable Read):事务在实行期间多次读取同一数据时,包管读取结果稳定,防止不可重复读,但可能出现幻读
  • 串行化(Serializable):事务按照顺序串行实行,完全制止幻读、不可重复读和脏读,但性能最差
技术

锁机制:
锁的种类:


  • 共享锁(Shared Lock, S-Lock):允许多个事务同时读取数据,但不允许修改。多个事务可以持有共享锁,但不能对数据进行修改
  • 排他锁(Exclusive Lock, X-Lock):事务在修改数据时需要得到排他锁,排他锁会阻止其他事务读取或修改相同的数据
  • 意向锁(Intent Lock):指示事务计划在某个粒度的数据上得到锁
  • 悲观锁与乐观锁:悲观锁假设会发生冲突,因此通过加锁来制止;乐观锁假设冲突概率较低,通过版本控制或数据验证等方式来制止冲突
锁的管理:


  • 两阶段锁协议(Twp-Phase Locking, 2PL):为了制止死锁,数据库系统通常要求事务在实行期间按一定顺序获取锁,并在事务竣事前不开释任何锁,但是还是不能完全制止死锁
  • 死锁:当两个或多个事务在持有锁的情况劣等待对方开释锁时,便发生了死锁,办理死锁的方法包括:

    • 死锁检测:系统监控锁的状态,并通过算法发现死锁
    • 死锁制止:通过资源分配策略(如银行家算法)制止死锁的发生
    • 死锁恢复:当检测到死锁时,回滚某个事务以开释锁

时间戳排序:
通过为每个事务分配一个唯一的时间戳来控制事务的顺序,每个事务在实行时必须遵循一个全局的时间戳顺序,数据库根据事务的时间戳来判断对其他事务的影响


  • 时间戳排序的核心:假如事务T1时间戳早于事务T2,则事务T1必须先实行,T2必须等待
  • 时间戳排序方法通过比较事务的读/写时间戳来确保不发生冲突。
多版本并发控制(MVCC):
MVCC通过为数据创建多个版本来制止锁的竞争。每当一个事务对数据进行修改时,数据库会为该数据创建一个新版本,而不会直接覆盖旧版本。其他事务仍然可以访问旧版本的数据,如许制止了对数据的壅闭。


  • 事务视图:MVCC通过维护每个事务可见的数据版本来实现并发控制
  • 快照隔离(Snapshot Isolation):在MVCC中,事务看到的是一个数据快照,包管事务在实行期间的数据一致性
乐观并发控制(Optimistic Concurrency Control, OCC):
假设事务之间不会发生冲突,因此事务实行时无需锁定命据,事务在实行竣事后,通过检查数据是否被其他事务修改来决定是否提交。假如发生冲突,事务会回滚并重新实行

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

不到断气不罢休

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表