SQL table 的列可能有 "multiple types of NULL" 个值

SQL table with a column which may have "multiple types of NULL" values

标题可能会令人困惑,所以我需要澄清一下。

我有以下需要传输到 PostgreSQL 数据库的调查数据集。

| id | title | income | age    | height | weight | Education   |
| 1  | foo   | 10000  | 45     | 170    | 50     | College     |
| 2  | bar   | 15000  | -20000 | -30000 | 45     | High School |
| 3  | hoge  | -10000 | -10000 | 150    | 60     | -20000      |
| 4  | fuga  | 20000  | 20     | -10000 | 70     | College     |
...

其中-10000、-20000、-30000都代表一个空值,只是由于不同的原因。
(例如,-10000 表示未向参与者显示有关该列的问题,-20000 表示参与者跳过了问题,-30000 表示他们的回答无效。)

问题是,如何设计一个table和约束来模拟这种情况?

显然,如果我对收入和其他列使用 INTEGER 而对教育使用 VARCHAR,则空值将不相同。此外,如果我将收入仅视为整数,"null" 值将只是一个负数,这将在以下数据操作中出现问题。

我认为这里最好的设计是只为每个数据列添加状态列,假设您想跟踪给定列的状态。像这样:

| id | title | income | age    | age_code | height | height_code | weight | Education   |
| 1  | foo   | 10000  | 45     | 1        | 170    | 1           | 50     | College     |
| 2  | bar   | 15000  | NULL   | 2        | NULL   | 4           | 45     | High School |
| 3  | hoge  | NULL   | NULL   | 3        | 150    | 1           | 60     | NULL        |
| 4  | fuga  | 20000  | 20     | 1        | NULL   | 5           | 70     | College     |

这里,我使用代码值2,3表示年龄中的某种错误代码,值4,5表示其他类型的高度错误。

通常,一列中的值应该只代表一件事。在这种情况下,年龄和身高列应该存储这些测量值的数据,而不是这些测量值的状态。我回填了 NULL 数据缺失或完全无效的值。