postgresql - 建模和规范化时如何处理空值?

标签 postgresql null relational-database database-normalization

我必须为 field 创建一个数据库。

客户为事件预订了房间。问题是客户并不总是提供他们的姓名、电子邮件和电话号码。大多数时候,要么是姓名和电子邮件,要么是姓名和电话。这 3 种情况很少,但它确实发生了。

我需要将这些分别存储在各自的属性(姓名、电子邮件、电话)中。但是他们给我他们的信息的方式,我有很多空值。 我可以用这些空值做什么?有人告诉我最好不要有空值。之后我还需要规范化我的表格。

最佳答案

SQL 根据其 3VL(三值逻辑)版本特殊对待 NULL。规范化和其他关系理论没有。但是,我们可以将 SQL 设计转换为关系设计并返回。 (假设这里没有重复行。)

规范化发生在关系 中,并且根据不特殊处理 NULL 的运算符定义。术语“normalization”有两个最常见的不同含义:将表放入“1NF”和放入“更高的 NF(范式)”。 NULL 不影响“标准化为 1NF”。 “标准化为更高的 NF”用自然连接回它的较小表替换表。出于规范化的目的,除了其 SQL 类型的值之外,您还可以将 NULL 视为可空列域中允许的值。如果我们的 SQL 表没有 NULL,那么我们可以将它们解释为关系,将 SQL 连接等解释为连接等。但是,如果你分解码件之间共享的可为空列的位置,然后意识到要在 SQL 中重建原始数据,你必须在 SQL 上连接同名列等于或均为 NULL。而且您不会希望 SQL 数据库中有这样的 CK(候选键)。例如,您不能将其声明为 SQL PK(主键),因为这意味着 UNIQUE NOT NULL。例如,涉及可空列的 UNIQUE 约束允许多行在该列中具有 NULL,即使这些行在每一列中具有相同的值。例如,SQL FK 中的 NULL 使它们得到满足(每个 MATCH 模式以各种方式),而不是因为没有出现在引用的表中而失败。 (但 DBMS 与标准 SQL 有着特殊的不同。)

不幸的是,分解可能会导致一个表的 所有 CK 都包含 NULL,因此我们没有任何东西可以声明为 SQL PK 或 UNIQUE NOT NULL。唯一确定的解决方案是转换为无 NULL 设计。规范化之后,我们可能希望在组件中重新引入一些可空性。

在实践中,我们设法设计表,以便始终有一组可以通过 SQL PK 或 UNIQUE NOT NULL 声明为 CK 的无 NULL 列。然后我们可以通过将可空列从表中删除并添加一个包含该列的表和一些无空 CK 的列来摆脱可空列:如果旧设计中的一行的列是非空的,那么一行它的 CK 子行和列值进入添加的表;否则它在旧设计中为 NULL,并且在添加的表中没有相应的行。 (原表是新表的自然左连接。)当然,我们还需要将查询从旧设计修改为新设计。

我们总是可以通过为每个旧的可空列添加一个 bool 列并使旧列为 NOT NULL 的设计来避免 NULL。新列表示旧列在旧设计中是否为 NULL,以及当 true 时旧列是我们为此目的在整个数据库中为该类型选择的某个值。当然,我们还必须将查询从旧设计修改为新设计。

是否要避免 NULL 是一个单独的问题。无论采用哪种设计,您的数据库在某种程度上都可能对您的应用程序“更好”或“更差”。避免 NULL 背后的想法是 it complicates the meanings of queries ,因此与来自更多无 NULL 表的更多连接的复杂性相比,以一种反常的方式使查询复杂化。 (通常通过在尽可能靠近它们出现的位置删除查询表达式中的 NULL 来管理这种反常行为。)

PS 许多 SQL 术语(包括 PK 和 FK)与关系术语不同。 SQL PK 的意思更像是 super 键; SQL FK 的意思更像是外国 super 键; but it doesn't even make sense to talk about a "superkey" in SQL :

Because of the resemblance of SQL tables to relations, terms that involve relations get sloppily applied to tables. But although you can borrow terms and give them SQL meanings--value, table, FD (functional dependency), superkey, CK (candidate key), PK (primary key), FK (foreign key), join, and, predicate, NF (normal form), normalize, 1NF, etc--you can't just substitute those SQL meanings for those words in RM definitions, theorems or algorithms and get something sensible or true. Moreover SQL presentations of RM notions almost never actually tell you how to soundly apply RM notions to an SQL database. They just parrot RM presentations, oblivious to whether their use of SQL meanings for terms makes things nonsensical or invalid.

关于postgresql - 建模和规范化时如何处理空值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40733477/

相关文章:

php - INNER JOIN 唯一列 mysql

postgresql - bool 值被插入到 PostgreSQL 中的字符变化字段中

postgresql - clojure/java.jdbc 和 postgres : Prepared statments 100x slower than string concatenated queries?

PostgreSQL : How can I determine how many characters in a text

sql - 查询时间过长

c - C-此指针为空吗?

c - 为之前初始化为 NULL 的指针赋值

java - Builder类中的director如何将一个null int设置为0?

sql - 在 RDB 模式中,什么时候将列组合成单个分隔列会更好?

java - 我可以用lucene索引RDB吗?