---
title: 函数依赖
tags:
  - 架构知识
  - 数据库设计
  - 函数依赖
  - 数据依赖
categories:
  - - 架构知识
    - 数据库设计
mathjax: true
date: 2021-04-19 09:01:42
---

函数依赖是一个从数学派生过来的术语，是最重要最基本的一种数据依赖关系体现。所有关系型数据库的设计理论核心就坐落于其上。<!-- more -->函数依赖内容在软考中出现的几率非常大，几乎接近必考的内容，但也是几乎所有人都为之头疼的问题。其实函数依赖不是难于理解，而是函数依赖是来自数学概念的，这就导致函数依赖的概念变得有一些晦涩。

## 定义

教科书上的定义一般是比较准确的，函数依赖在教科书上的定义是这样的。

!!! note ""
    设$R(U)$是属性$U$上的一个关系模式，$X$和$Y$是$U$的子集，$r$是$R$的任意一个关系，如果对于$r$中的任意两个元组$u$和$v$，只要存在$u[X]=v[X]$，就有$u[Y]=v[Y]$，则称$X$函数决定$Y$，或称$Y$函数依赖于$X$，记为$X \rightarrow Y$。

看到这个教科书形式的定义，想必数学不好的人已经完全懵圈了。其实要想理解这个函数依赖的定义，只需要明白这个定义中所使用的几个概念。

- **属性**，在这个定义中，**属性**的概念和我们平时常说的属性并不是同一个概念。这里的属性实际上指代的是**集合**。
- **关系模式**，实际上就是几个数据间关系的描述。通常记为$R(U, D, dom, F)$，其中$R$是关系名，$U$是组成这个关系的属性名称集合，$D$是属性集合$U$中属性所来自的域，$dom$是属性向域的映像集合，$F$是属性间数据依赖关系的集合。关系模式$R$通常会被简记为$R(U)$或者$R(A_1, A_2, \ldots, A_n)$，在这里面$A_n$表示一个具体的属性名称。在一个数据库中，一个关系模式是由一张或者多张数据表构成，$F$中每一个关系实际上对应一个数据表。
- **元组**，一个属性中记录值的集合。为了便于理解可以认为是一条数据库记录。

> 常见的关系模式记录方式是这样的：$R\langle U=\lbrace A, B, C, D \rbrace, F=\lbrace A \rightarrow B, B \rightarrow C \rbrace \rangle$。

函数依赖的概念在数学中是用来表示两个函数间的关系的，主要用于表达两个函数间的依赖关系。假设有$A$、$B$两个函数，如果$A \rightarrow B$（从函数$A$能推出函数$B$），那么就可以称函数$B$函数依赖于函数$A$。这个概念在引申到数据间关系上以后，可以这样来表述。

!!! note ""
    在关系$R$中，如果属性集$A$中两个元组的值相等，而如果这两个元组中对应的属性集$B$中的值也相同，就可以记作$A \rightarrow B$。也就是说属性集$A$函数决定属性集$B$，属性集$B$函数依赖于属性集$A$。

如果用现实生活中可以接触到的数据库结构来解释，那么可以视属性集$A$为数据表的主键，属性集$B$是数据表中的非主键字段。那么可以看出通过作为主键的属性集$A$是可以找到其对应的属性集$B$的，或者用比较数学的语言说，通过属性集$A$可以推出属性集$B$。

## 函数依赖的类型

根据函数依赖的不同形式，函数依赖可以被细分成更多的几个类型。以下均假定$X$和$Y$、$Z$都是关系$R$上的属性集合。

### 平凡函数依赖

当属性集$Y$是属性集$X$的子集时（$Y \subset X$），必然存在函数依赖$X \rightarrow Y$，那么这种函数依赖就被称为平凡函数依赖。

### 非平凡函数依赖

当属性集$Y$不是属性集$X$的子集时（$Y \not\subset X$），但存在函数依赖$X \rightarrow Y$，那么这种函数依赖就被称为非平凡函数依赖。

### 部分函数依赖

如果有属性集$X$的真子集$X^\prime$，如果存在$X^\prime \rightarrow Y$，那么就称$Y$对$X$部分函数依赖。

!!! info "真子集"
    如果集合$A$是集合$B$的子集（$A \subset B$），但是集合$B$不是集合$A$的子集（$B \not\subset A$），那么集合$A$就是集合$B$的真子集（$A \subseteq B$），即集合$A$完全包含于集合$B$。

### 完全函数依赖

如果属性集$X$的任何一个真子集$X^\prime$，都不存在$X^\prime \rightarrow Y$，那么就可以称$Y$对$X$完全函数依赖。

!!! info ""
    完全函数依赖的意义在于属性集$Y$只能被属性集$X$的整体确定，而不是可被$X$的一部分确定。如果$X$是数据表中的主键，那么$X$和$Y$组成的数据表就已经是不可再被精简的组合了。

### 传递函数依赖

如果$X \rightarrow Y$，$Y \rightarrow Z$，但是没有$Y \rightarrow X$，且$Y \not\in X$，$Z \not\in Y$，那么可以称$Z$对$X$存在传递函数依赖。

传递函数依赖常常用来推导多个属性间的关系或者是多个属性集之间的关系，用在数据库设计上，可以对数据结构做进一步的拆分，提升数据库的范式级别。此外，传递函数依赖还是软考中出题概率最大的内容。

## 系列文章

1. {% post_link functional-dependency %}
1. {% post_link schema-decomposition %}