复习数据库的时候整理的笔记。
阅读时你将看到:中英双语,是因为有些名词的中文翻译我不确定,所以保留英文了。
SQL 为 postgresql
关系运算的参与对象是关系,运算后结果也是关系。在数据库中,关系就是一张张的表。在离散数学中,关系是做为一个个的集合来进行运算的。
五种基本操作经过有限次复合的式子称为关系代数表达式。
Select Operation
\(\sigma_p(r)\) 表示从关系 \(r\) 中选出满足 \(p\) 的元组。
We can combine several predicates into a larger predicate by using the connectives:
\(\and,\or,\neg\)
sql:select * from r where p
Project Operation
表示从关系 \(r\) 中选择属性(Attribute) \(A_i\)。
sql: select A1, A2, ..., Ak from r
我们可以将关系运算结合起来,例如:
select A1, A2, ..., Ak from r where p
Cartesian-Product Operation
笛卡尔积用来组合来自任意两种关系的信息。
sql: select * from r1, r2
Join Operation
看作是笛卡尔积和选择的复合:
\(r \Join_\theta s = \sigma_{\theta}(r \times s)\)
Union Operation
若 \(r\cup s\) 合法,则:
• \(r, s\) must have the same arity (same number of attributes)
• The attribute domains must be compatible(例如对应列的数据类型须相同)
sql:
select c from t1 union select c from t2;
如果不需要去重则写
union all
Set-Intersection Operation 类似于 \(r\cup s\),只不过是求交(\(\cap\)),即找到在两个关系中同时存在的元组。
Set Difference Operation
找到在一个关系中但不在另一个关系中的元组。
合法的要求同 \(r\cup s\)。
sql:
select c from t1 except select c from t2;
The Assignment Operation
通过赋值操作,一个查询可以被写成一个顺序程序,由一系列的赋值和一个表达式组成,其值将显示为查询的结果。
The Rename Operation
\(\rho _ x (E)\) 返回名称为 \(x\) 下的表达式 \(E\) 的结果。
\(\rho_{x(A_1,A2,\dots,An)}(E)\) 将关系 \(E\) 重命名为关系 \(x\),属性名依次修改为 \(A_i\)(\(i \in [1, n]\))。
select c as C from t1
在关系代数中编写查询的方法不止一种。
两个查询尽管不相同但却是等价的——它们在任何数据库上都给出相同的结果。
Models an enterprise as a collection of entities and relationships
由属性(用于描述实体的性质)构成的集合表示。
example: \(\texttt{instructor = (ID, name, salary)}\)
Represented diagrammatically by an entity-relationship diagram (E-R diagram)
实体集(entity set)是具有相同属性的相同类型的实体的集合。
Example: set of all persons, companies, trees, holidays
实体的属性的子集构成实体集的主键(primary key),用以唯一地(uniquely)标识实体集的成员。
在 ER 图中用矩形表示。
关系集(Relationship Sets)
实体之间的关系构成的集合。
关系集是由多个实体集抽象出来的一种特殊的实体集。
Most relationship sets are binary.(大多数关系集为二元关系集)
关系集是 \(n\geq 2\) 个实体集合的数学关系,每个实体取自一个实体集,关系集为:
\[\{(e_1, e_2, e_3,\dots,e_n) | e_i\in E_i \} \]其中 \(E_i\) 为一个实体集。
在 ER 图中用菱形表示。
Complex Attributes
属性可分为:
多值属性例子:电话号码——一个人可以同时拥有一个或多个电话号码。
域 Domain: The set of permitted values for each attribute.(可以理解为属性的值域)
派生属性 Derived attributes:可以通过其它属性计算得来,例如:给出属性生日可以计算出属性年龄,那么年龄为派生属性。
复合属性 Composite Attributes:将属性划分为子部分,例如属性名字可以划分为姓 + 名。
Mapping Cardinality Constraints
Mapping Cardinality(映射基数) :实体可以参与的最大关系实例数。
二元关系集的映射基数种类一定是下面四种之一:
• One to one
• One to many
• Many to one
• Many to many
Primary Key
实体的键(Key)是足以区分实体之间的属性的集合。
超键(Super Key):在关系中能唯一标识元组的属性集称为关系模式的超键。
作为:表的行的唯一标识的候选关键字。
主键可以由一个字段,也可以由多个字段组成,分别称为:单字段主键、多字段主键。
弱实体集 (weak entity set)
没有足够的属性以形成主键的实体集。
例如对于餐厅的食物有属性:制作时间、美味度、名字。但时间可能重合,美味度和名字也同理,那么食物对应的实体集就是弱实体集。
相对地,有主键的实体集称为 强实体集 strong entity set。
这个强实体集被称为标识 identifying 或属主实体集 owner entity set。
将弱实体集与标识实体集相联的联系称为标识性联系 identifying relationship,在 E-R 图中用双菱形表示
我们称弱实体集存在依赖于标识实体集,标识实体集拥有弱实体集。
分辨符 discriminator(部分码):
弱实体集没有可以充当主码的属性,它用分辨符来区分属性集合。
在实体集中用 虚下划线 标识。
1.第一范式(确保每列保持原子性)
第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
2.第二范式(确保表中的每列都和主键相关)
第二范式在第一范式的基础之上更进一层。
第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
事务( Transaction)由一次或者多次基本操作构成,或者说,事务由一条或者多条 SQL 语句构成。
一般来说,事务具有四个标准属性,分别是原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability),简称 ACID。
一个事务中的所有 SQL 语句,要么全部执行成功,要么全部执行失败,不会结束在中间的某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的数据必须完全符合所有的预设规则,其中包含数据的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
在事务的并发操作中可能会出现脏读,不可重复读,幻读。
脏读:指当一个事务正在访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。
不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事物内两次连续读到的数据是不一样的。
幻读:一个事务先后读取一个范围的记录,但两次读取的记录数不同。事务 A 按照一定条件进行数据读取, 期间事务 B 插入了相同搜索条件的新数据,事务 A 再次按照原先条件进行读取时,发现了事务 B 新插入的数据。
数据库事务的隔离级别有4种,由低到高分别为 Read uncommitted 、Read committed 、Repeatable read 、Serializable 。
读未提交 (Read uncommitted)
一个事务可以读取另一个未提交事务的数据。在这种隔离级别下,查询是不会加锁的,也由于查询的不加锁,所以这种隔离级别的一致性是最差的,可能会产生“脏读”、“不可重复读”、“幻读”。如无特殊情况,基本是不会使用这种隔离级别的。
读提交(Read Committed)
只能读到已经提交了的内容,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。
但这可能出现一个事务中两次查询返回不同数据的情况(不可重复读)。
进一步说,“读提交”只能避免“脏读”,并不能避免“不可重复读”和“幻读”。
这是各种系统中最常用的一种隔离级别,也是 SQL Server 和 Oracle 的默认隔离级别。
可重复读 (Repeated Read)
它也是 MySql 的默认隔离级别。
不可重复读会令在事务开启的时,不允许其他事务的 UPDATE 操作。但是可能还会有幻读问题。因为幻读问题对应的是插入 INSERT/DELETE 操作,而不是 UPDATE 操作。
序列化 (Serializable)
这是数据库最高的隔离级别,这种级别下,事务“串行化顺序执行”,也就是一个一个排队执行。这种级别下,“脏读”、“不可重复读”、“幻读”都可以被避免,但是执行效率奇差,性能开销也最大,所以基本没人会用。