前一段时间,我一直在阅读CJ Date撰写的《
SQL和关系理论
》一书。作者因批评SQL的三值逻辑(3VL)而闻名。 1)
作者对为什么在SQL中应避免使用3VL提出了一些强点,但是他没有概述 如果不允许使用可空列,那么数据库模型的外观
。我已经对此进行了思考,并提出了以下解决方案。如果我错过了其他设计方案,我想听听他们的意见!
1) Date对SQL 3VL的评论也遭到批评:参见Claude
Rubinson的这篇论文(包括CJ Date的原始评论)。
表格示例:
以下表为例,其中有一个可为空的列(DateOfBirth
):
# +-------------------------------------------+
# | People |
# +------------+--------------+---------------+
# | PersonID | Name | DateOfBirth |
# +============+--------------+---------------+
# | 1 | Banana Man | NULL |
# +------------+--------------+---------------+
选项1:NULL
通过标志和默认值进行仿真:
而不是使该列为可空,而是指定了任何默认值(例如1900-01-01
)。另一BOOLEAN
列将指定是DateOfBirth
仅应忽略其中的值还是实际上包含数据。
# +------------------------------------------------------------------+
# | People' |
# +------------+--------------+----------------------+---------------+
# | PersonID | Name | IsDateOfBirthKnown | DateOfBirth |
# +============+--------------+----------------------+---------------+
# | 1 | Banana Man | FALSE | 1900-01-01 |
# +------------+--------------+----------------------+---------------+
选项2:将可为空的列转换为单独的表:
可为空的列由新表(DatesOfBirth
)代替。如果记录中没有该列的数据,则新表中将没有记录:
# +---------------------------+ 1 0..1 +----------------------------+
# | People' | <-------> | DatesOfBirth |
# +------------+--------------+ +------------+---------------+
# | PersonID | Name | | PersonID | DateOfBirth |
# +============+--------------+ +============+---------------+
# | 1 | Banana Man |
# +------------+--------------+
尽管这似乎是更好的解决方案,但可能会导致许多表需要为单个查询连接。由于OUTER JOIN
将不允许s(因为它们会引入NULL
到结果集中),因此像以前一样,仅通过单个查询就可能不再获取所有必需的数据。
问题: 是否还有其他消除方法NULL
(如果是的话,它们是什么)?
我看到Date的同事Hugh Darwen在出色的演讲“如何在不使用NULL的情况下处理丢失的信息”中讨论了此问题,该演讲可在Third
Manifesto网站上找到
。
他的解决方案是您第二种方法的变体。这是第六种普通形式,其中的表用于保存出生日期和未知的标识符:
# +-----------------------------+ 1 0..1 +----------------------------+
# | People' | <-------> | DatesOfBirth |
# +------------+----------------+ +------------+---------------+
# | PersonID | Name | | PersonID | DateOfBirth |
# +============+----------------+ +============+---------------+
# | 1 | Banana Man | ! 2 | 20-MAY-1991 |
# | 2 | Satsuma Girl | +------------+---------------+
# +------------+----------------+
# 1 0..1 +------------+
# <-------> | DobUnknown |
# +------------+
# | PersonID |
# +============+
# | 1 |
# +------------+
然后,从“人员”中进行选择需要将所有三个表(包括样板)结合起来以指示未知的出生日期。
当然,这是理论上的。如今,SQL的状态仍不足以处理所有这些问题。休的演讲涵盖了这些缺点。他提到的一件事并不完全正确:某些SQL版本确实支持多重赋值-
例如Oracle的INSERT
ALL语法。
我认为这是一个常见的问题,但我还没有找到任何解决方案,也许我没有在谷歌上正确地搜索这个问题。总之,我有一个在表中插入多行的过程(在同一个事务中的许多其他事情中),但是这个过程是在多个线程和多个服务器中执行的。 描述是唯一的,但不作为数据库(旧版)中的约束,我想避免插入重复的描述。我已经隔离了搜索并插入到一个独立的事务中,我想在选择之前锁定表,如果它不存在,则在“保存”之后释放它。 我想要这样的东西
问题内容: 是否可以检索中特定行的特定列? 假设我要使用以下查询文本从名为的表中选择名称为:a,b的行: 如何修改此查询文本以仅选择第2、12、22、32、42列,而不是选择其所有1000列? 问题答案: 将通配符替换为要检索的列名。 但是请阅读有关SQL标准的文档。您在表中需要1.000列的可能性很小。
我有下一个示例代码: 你可以看到id是JSON格式中的一个重复字段,我知道PostgreSQL有一些功能可以避免这个问题,但我找不到。
我正试图从数据库中删除一行,但得到以下错误
我从一个用spark-kafka-cassandra(在kubernetes上)重写猛犸象spark-kafka-hbase应用程序的初步想法开始。 我有以下数据模型,一个支持全时插入,另一个支持upserts 办法1: 创建表test.inv_positions( location_id int, item bigint, time_id timestamp, sales_floor_qty i
问题内容: 我有此错误信息: 消息8134,级别16,状态1,第1行除以零错误。 编写SQL代码的最佳方法是什么,这样我就再也看不到此错误消息了? 我可以执行以下任一操作: 添加一个where子句,这样我的除数永远不会为零 或者 我可以添加一个case语句,以便对零进行特殊处理。 使用子句的最佳方法是吗? 有没有更好的方法,或者如何执行? 问题答案: 为了避免出现“被零除”错误,我们对此进行了如下