关系代数表达式为"is null"

Xtr*_*eik 5 null relational-algebra

下面的查询的关系代数表达式是什么?我找不到"Is Null"的表达式.

SELECT reader.name
FROM reader LEFT JOIN book_borrow ON reader.cardid = book_borrow.cardid
WHERE book_borrow.cardid Is Null;
Run Code Online (Sandbox Code Playgroud)

SáT*_*SáT 13

这项任务需要一点创造力,而不是逐字翻译.

这个查询中发生了什么?首先,我们将book_borrow加入到读者手中.记住定义:即使ON子句不匹配最右边的表中的行,连接仍将返回单行,使其在右表的字段中包含NULL.我们的表看起来像这样:

reader.name | reader.cardid | book_borrow.cardid | book_borrow.book_id
Alice       | 1             | 1                  | 1
Alice       | 1             | 1                  | 5
Bob         | 2             | 2                  | 5
Charlie     | 3             | NULL               | NULL
Run Code Online (Sandbox Code Playgroud)

我们可以看到Alice已经借了两本书(ids 1和5),Bob借了一本(id 5),Charlie在他的book_borrow字段中得到了NULL,因为他没有借用.然后查询继续只获取book_borrow.cardid为NULL的行,因此查询只是说:"让所有未借用任何书籍的人".

像这样描述任务,编写关系代数表达式很容易:

  • 让我们自然地加入读者和book_borrow,这将产生不必要的行,借用任何书籍的人的名字.
  • 然后从所有人的集合中减去这些人,结果就是那些没有借书的人.

在这里,释放我的乳胶:

π(name){π(name,carddid){Reader}  - π(name,cardid){Reader join Book_borrow}}

故事的道德:尽管正如欧文所指出的那样,在最纯粹的关系代数形式中没有空(因为关系代数建立在一阶逻辑上),我们并不总是需要它来表达缺乏某种东西; 左连接可以由基本运算符表示; 左连接是为了提高计算效率而发明的:你可以很容易地看到采用左连接和选择空值是多么实用.

  • 左连接不可能是(最纯粹的)关系代数的一部分,因为左连接按定义在它们的结果中引入(可能的)空值.RA可以表达(标识属性)某些其他属性在数据库中未知的事物,但是这需要两个不同的RA关系,并且根据SQL不能很好地映射到单个表-with-nulls. (2认同)
  • 此外,如果您在SQL表中指出了重复列名'cardid'的问题,那将更加令人满意.这是RA中无法实现的另一个"功能".否则,+1为"稍微"更有帮助的答案. (2认同)