问题
我感到困惑的一件事是可能是数据库最基本组件的技术定义:单个值。
一些例子
我理解并遵循(至少)数据库规范化的前三种正常形式——或者我认为是这样。也就是说,随着RANGE
PostgreSQL 9.2 的引入,我开始思考什么是单一值。
从文档:
范围类型很有用,因为它们表示单个范围值中的许多元素值
那么,你是什么?几个值,或一个值......虚无...... 42?
为什么这很重要?
因为 is 直接与第二范式对话:
- 为适用于多条记录的值集创建单独的表。
- 将这些表与外键相关联。
#1 范围
例如,在Postgres 9.1中,我有一些表结构如下:
"SomeSchema"."StatusType"
"StatusTypeID" | "StatusType"
--------------------|----------------
1 | Start
2 | Stop
“SomeSchema”。“状态”
"StatusID" | "Identifier" | "StatusType" | "Value" | "Timestamp"
---------------|----------------|----------------|---------|---------------------
1 | 1 | 1 | 0 | 2000-01-01 00:00:00
2 | 1 | 2 | 5 | 2000-01-02 12:00:00
3 | 2 | 1 | 1 | 2000-01-01 00:00:00
4 | 3 | 1 | 2 | 2000-01-01 00:00:00
5 | 2 | 2 | 7 | 2000-01-01 18:30:00
6 | 1 | 2 | 3 | 2000-01-02 12:00:00
这使我能够保留在任何给定时间点如何配置事物的历史记录。该结构的位置是“值”列中的数据都是单独的值。
现在,在Postgres 9.2中,如果我用一个RANGE
值做同样的事情,它看起来像这样:
“SomeSchema”。“状态”
"StatusID" | "Identifier" | "Value" | "Timestamp"
---------------|----------------|-------------|---------------------
1 | 1 | (0, NULL) | 2000-01-01 00:00:00
2 | 1 | (0, 5) | 2000-01-02 12:00:00
3 | 2 | (1, NULL) | 2000-01-01 00:00:00
4 | 3 | (2, NULL) | 2000-01-01 00:00:00
5 | 2 | (1, 7) | 2000-01-01 18:30:00
6 | 1 | (0, 3) | 2000-01-02 12:00:00
同样,这种结构使我能够保留事物配置方式的历史记录,但我会在不同的地方多次存储相同的值。它使更新(技术上插入新记录)更加棘手,因为我必须确保数据从原始记录翻转过来。
#2 数组
数组已经存在了很长时间,虽然它们可能会被滥用,但我倾向于将它们用于颜色代码之类的东西。例如,我的项目存储信息,有时需要知道如何显示它。我可以创建三列来存储red
、green
和blue
值;但这似乎很愚蠢。我什么时候会根据给定的颜色代码之一创建外键(甚至只是过滤器)。
当我创建该字段时,我需要以中性格式存储颜色,以便我可以提供任何接受颜色值的内容。我将该列设为一个数组,并用适当的代码填充它以制作我想要的颜色。
#3 PostGIS:几何与地理
在 PostGIS 中存储多边形时,它将构成边界的所有点存储在单个字段中。如果一个点发生变化并且我想保留历史记录,我将不得不存储所有未更改两次的点,以便将新多边形与旧多边形一起存储。
那么,什么是价值?和...如果RANGE
,ARRAY
和GEOGRAPHY
是值,它们真的打破了第二范式吗?