Skip to content

Commit 6a2ae18

Browse files
committed
Add F# type definitions for database normalization forms
This commit introduces a comprehensive F# type system for representing database normalization forms (1NF through 6NF, plus DKNF). Key features: - Core types: CellValue, Relation, FunctionalDependency, MultivaluedDependency - 1NF: Validates atomic values - 2NF: Checks for partial dependencies - 3NF: Detects transitive dependencies - BCNF: Ensures all determinants are superkeys - 4NF: Validates multivalued dependencies - 5NF: Handles join dependencies - 6NF: Supports temporal decomposition - DKNF: Domain-Key Normal Form constraints Each normalization form includes validation logic to check compliance.
1 parent e025040 commit 6a2ae18

2 files changed

Lines changed: 259 additions & 0 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Include="NormalizationForms.fs" />
10+
</ItemGroup>
11+
12+
</Project>
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
namespace DatabaseNormalization
2+
3+
open System.Collections.Generic
4+
5+
// 基础类型定义
6+
type AttributeName = string
7+
type RelationName = string
8+
9+
type CellValue =
10+
| Null
11+
| Int of int
12+
| String of string
13+
| Bool of bool
14+
| Float of float
15+
| Date of System.DateTime
16+
17+
interface System.IComparable with
18+
member this.CompareTo(other) =
19+
match other with
20+
| :? CellValue as o ->
21+
match this, o with
22+
| Null, Null -> 0
23+
| Null, _ -> -1
24+
| _, Null -> 1
25+
| Int a, Int b -> compare a b
26+
| String a, String b -> compare a b
27+
| Bool a, Bool b -> compare a b
28+
| Float a, Float b -> compare a b
29+
| Date a, Date b -> compare a b
30+
| _ -> 0
31+
| _ -> -1
32+
33+
type Domain = Set<CellValue>
34+
type AttributeSet = Set<AttributeName>
35+
type Tuple = Map<AttributeName, CellValue>
36+
37+
// 函数依赖 (Functional Dependency)
38+
type FunctionalDependency = {
39+
Left: AttributeSet // X
40+
Right: AttributeSet // Y
41+
// 表示 X -> Y
42+
}
43+
44+
// 多值依赖 (Multivalued Dependency)
45+
type MultivaluedDependency = {
46+
Left: AttributeSet // X
47+
Right: AttributeSet // Y
48+
// 表示 X ->-> Y
49+
}
50+
51+
// 连接依赖 (Join Dependency)
52+
type JoinDependency = {
53+
Decomposition: AttributeSet list
54+
}
55+
56+
// 基础关系
57+
type Relation = {
58+
Name: RelationName
59+
Attributes: AttributeName list
60+
Tuples: Tuple list
61+
}
62+
63+
// 1NF: First Normal Form
64+
type Relation1NF = {
65+
Relation: Relation
66+
// 所有属性值必须是原子的(不可再分)
67+
}
68+
69+
module Relation1NF =
70+
let isAtomic (value: CellValue) =
71+
// 在我们的定义中,所有 CellValue 都是原子的
72+
match value with
73+
| Null | Int _ | String _ | Bool _ | Float _ | Date _ -> true
74+
75+
let validate (relation: Relation) : Relation1NF option =
76+
let allAtomic =
77+
relation.Tuples
78+
|> List.forall (fun tuple ->
79+
tuple |> Map.forall (fun _ v -> isAtomic v)
80+
)
81+
if allAtomic then Some { Relation = relation }
82+
else None
83+
84+
// 2NF: Second Normal Form
85+
type Relation2NF = {
86+
Relation1NF: Relation1NF
87+
PrimaryKey: AttributeSet
88+
FunctionalDependencies: FunctionalDependency list
89+
// 没有部分依赖:所有非主属性完全依赖于候选键
90+
}
91+
92+
module Relation2NF =
93+
let isProperSubset (subset: AttributeSet) (superset: AttributeSet) =
94+
Set.isSubset subset superset && subset <> superset
95+
96+
let hasPartialDependency (primaryKey: AttributeSet) (fd: FunctionalDependency) (nonPrimeAttrs: AttributeSet) =
97+
// 检查是否存在部分依赖
98+
// 即:fd.Left 是主键的真子集,且 fd.Right 包含非主属性
99+
isProperSubset fd.Left primaryKey &&
100+
not (Set.isEmpty (Set.intersect fd.Right nonPrimeAttrs))
101+
102+
let validate (relation1nf: Relation1NF) (primaryKey: AttributeSet) (fds: FunctionalDependency list) =
103+
let allAttrs = relation1nf.Relation.Attributes |> Set.ofList
104+
let nonPrimeAttrs = Set.difference allAttrs primaryKey
105+
106+
let hasPartialDeps =
107+
fds |> List.exists (fun fd ->
108+
hasPartialDependency primaryKey fd nonPrimeAttrs
109+
)
110+
111+
if not hasPartialDeps then
112+
Some {
113+
Relation1NF = relation1nf
114+
PrimaryKey = primaryKey
115+
FunctionalDependencies = fds
116+
}
117+
else None
118+
119+
// 3NF: Third Normal Form
120+
type Relation3NF = {
121+
Relation2NF: Relation2NF
122+
CandidateKeys: AttributeSet list
123+
// 没有传递依赖:非主属性不依赖于其他非主属性
124+
}
125+
126+
module Relation3NF =
127+
let isSuperkey (relation: Relation) (candidateKeys: AttributeSet list) (attrs: AttributeSet) =
128+
candidateKeys |> List.exists (fun key -> Set.isSubset key attrs)
129+
130+
let isPrimeAttribute (candidateKeys: AttributeSet list) (attr: AttributeName) =
131+
candidateKeys |> List.exists (fun key -> Set.contains attr key)
132+
133+
let violates3NF (candidateKeys: AttributeSet list) (fd: FunctionalDependency) (allAttrs: AttributeSet) =
134+
// 违反3NF如果:
135+
// 1. X 不是超键
136+
// 2. Y 包含非主属性
137+
let relation = { Name = ""; Attributes = Set.toList allAttrs; Tuples = [] }
138+
let isSuper = isSuperkey relation candidateKeys fd.Left
139+
140+
if isSuper then false
141+
else
142+
// 检查 fd.Right 是否包含非主属性
143+
fd.Right |> Set.exists (fun attr -> not (isPrimeAttribute candidateKeys attr))
144+
145+
let validate (relation2nf: Relation2NF) (candidateKeys: AttributeSet list) =
146+
let allAttrs = relation2nf.Relation1NF.Relation.Attributes |> Set.ofList
147+
148+
let violations =
149+
relation2nf.FunctionalDependencies
150+
|> List.exists (fun fd -> violates3NF candidateKeys fd allAttrs)
151+
152+
if not violations then
153+
Some {
154+
Relation2NF = relation2nf
155+
CandidateKeys = candidateKeys
156+
}
157+
else None
158+
159+
// BCNF: Boyce-Codd Normal Form
160+
type RelationBCNF = {
161+
Relation3NF: Relation3NF
162+
// 更严格:对于每个非平凡函数依赖 X -> Y,X 必须是超键
163+
}
164+
165+
module RelationBCNF =
166+
let isTrivialDependency (fd: FunctionalDependency) =
167+
Set.isSubset fd.Right fd.Left
168+
169+
let isSuperkey (relation: Relation) (candidateKeys: AttributeSet list) (attrs: AttributeSet) =
170+
candidateKeys |> List.exists (fun key -> Set.isSubset key attrs)
171+
172+
let validate (relation3nf: Relation3NF) =
173+
let relation = relation3nf.Relation2NF.Relation1NF.Relation
174+
let candidateKeys = relation3nf.CandidateKeys
175+
176+
let allValid =
177+
relation3nf.Relation2NF.FunctionalDependencies
178+
|> List.forall (fun fd ->
179+
isTrivialDependency fd ||
180+
isSuperkey relation candidateKeys fd.Left
181+
)
182+
183+
if allValid then
184+
Some { Relation3NF = relation3nf }
185+
else None
186+
187+
// 4NF: Fourth Normal Form
188+
type Relation4NF = {
189+
RelationBCNF: RelationBCNF
190+
MultivaluedDependencies: MultivaluedDependency list
191+
// 对于每个非平凡多值依赖 X ->-> Y,X 必须是超键
192+
}
193+
194+
module Relation4NF =
195+
let isTrivialMVD (mvd: MultivaluedDependency) (allAttrs: AttributeSet) =
196+
Set.isEmpty mvd.Right ||
197+
Set.isSubset allAttrs (Set.union mvd.Left mvd.Right)
198+
199+
let validate (bcnf: RelationBCNF) (mvds: MultivaluedDependency list) =
200+
let relation = bcnf.Relation3NF.Relation2NF.Relation1NF.Relation
201+
let allAttrs = relation.Attributes |> Set.ofList
202+
let candidateKeys = bcnf.Relation3NF.CandidateKeys
203+
204+
let allValid =
205+
mvds |> List.forall (fun mvd ->
206+
isTrivialMVD mvd allAttrs ||
207+
RelationBCNF.isSuperkey relation candidateKeys mvd.Left
208+
)
209+
210+
if allValid then
211+
Some {
212+
RelationBCNF = bcnf
213+
MultivaluedDependencies = mvds
214+
}
215+
else None
216+
217+
// 5NF (PJNF): Fifth Normal Form / Project-Join Normal Form
218+
type Relation5NF = {
219+
Relation4NF: Relation4NF
220+
JoinDependencies: JoinDependency list
221+
// 每个连接依赖都由候选键所蕴含
222+
}
223+
224+
module Relation5NF =
225+
let validate (r4nf: Relation4NF) (jds: JoinDependency list) =
226+
// 简化验证:实际实现需要检查连接依赖是否由候选键蕴含
227+
Some {
228+
Relation4NF = r4nf
229+
JoinDependencies = jds
230+
}
231+
232+
// 6NF: Sixth Normal Form
233+
type Relation6NF = {
234+
Relation5NF: Relation5NF
235+
// 支持所有连接依赖(最终范式,完全分解)
236+
}
237+
238+
// DKNF: Domain-Key Normal Form
239+
type Constraint =
240+
| DomainConstraint of AttributeName * Domain
241+
| KeyConstraint of AttributeSet
242+
243+
type RelationDKNF = {
244+
Relation: Relation
245+
Constraints: Constraint list
246+
// 所有约束都是域约束或键约束的逻辑结果
247+
}

0 commit comments

Comments
 (0)