2

问题

我感到困惑的一件事是可能是数据库最基本组件的技术定义:单个值。

一些例子

我理解并遵循(至少)数据库规范化的前三种正常形式——或者我认为是这样。也就是说,随着RANGEPostgreSQL 9.2 的引入,我开始思考什么是单一值。

文档

范围类型很有用,因为它们表示单个范围值中的许多元素值

那么,你是什么?几个值,或一个值......虚无...... 42?

为什么这很重要?

因为 is 直接与第二范式对话:

  1. 为适用于多条记录的值集创建单独的表。
  2. 将这些表与外键相关联。

#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 数组

数组已经存在了很长时间,虽然它们可能会被滥用,但我倾向于将它们用于颜色代码之类的东西。例如,我的项目存储信息,有时需要知道如何显示它。我可以创建三列来存储redgreenblue值;但这似乎很愚蠢。我什么时候会根据给定的颜色代码之一创建外键(甚至只是过滤器)。

当我创建该字段时,我需要以中性格式存储颜色,以便我可以提供任何接受颜色值的内容。我将该列设为一个数组,并用适当的代码填充它以制作我想要的颜色。

#3 PostGIS:几何与地理

在 PostGIS 中存储多边形时,它将构成边界的所有点存储在单个字段中。如果一个点发生变化并且我想保留历史记录,我将不得不存储所有未更改两次的点,以便将新多边形与旧多边形一起存储。


那么,什么是价值?和...如果RANGE,ARRAYGEOGRAPHY是值,它们真的打破了第二范式吗?

4

1 回答 1

1

某些操作可以从 X 派生新值,这些新值似乎是 X 的值的组成部分,这并不意味着 X 本身不是“单值”。因此,就 DBMS 类型系统而言,“范围”值和“地理”值应该是单个值。我对 Postgresql 的实现知之甚少,无法知道“数组”本身是否可以被视为单个值。像 Postgresql 这样的 SQL DBMS 并不是真正的关系DBMS,并且 SQL 支持各种结构,这些结构肯定不是正确的关系变量、值或类型(指针、空值和其他外来变量)。

然而,这是一个困难且有时会引起争议的话题。如果你还没有读过,那么我推荐这本书Databases, Types, and the Relational Model - The Third Manifesto by Date and Darwen。它准确地解决了您所问的问题。

我不喜欢你对 2NF 的描述,但它在这里不是很相关。

于 2013-11-15T15:33:36.817 回答