SQL: NATURAL JOIN 或 JOIN USING
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
NATURAL JOIN 或 JOIN .. USING 起初看起来是很有用的工具,当一个规范化的模式被设计得非常好,以至于 PRIMARY KEY
和 FOREIGN KEY
列名总是匹配时(在 NATURAL JOIN
的情况下,所有其他列名永远不会匹配)。 Sakila 数据库 就是后者的一个例子,其中包含如下表格
CREATE TABLE actor ( actor_id BIGINT PRIMARY KEY, first_name TEXT, last_name TEXT, last_update TIMESTAMP ); CREATE TABLE film ( film_id BIGINT PRIMARY KEY, title TEXT, last_update TIMESTAMP ); CREATE TABLE film_actor ( actor_id BIGINT REFERENCES film, film_id BIGINT REFERENCES film, last_update TIMESTAMP )
事实上,例如,ACTOR_ID
存在于 ACTOR
和 FILM_ACTOR
表中,并且在两个表中都表示相同的事物,这对于如下查询非常方便
SELECT * FROM actor JOIN film_actor USING (actor_id) JOIN film USING (film_id);
但即使是这个简单的模式也表明我们不能使用 NATURAL JOIN
,因为 LAST_UPDATE
列不应成为 JOIN
谓词的一部分。
SELECT * FROM actor NATURAL JOIN film_actor -- Wrong, because it joins on actor.last_update = film_actor.last_update NATURAL JOIN film -- Wrong, because it joins on film_actor.last_update = film.last_update
即使 USING
也可能遭受这种歧义,例如,当我们恰好向 FILM
表添加一个 ACTOR_ID
列时
-- Where actor_id means the "main" actor ID ALTER TABLE film ADD actor_id BIGINT REFERENCES actor;
这种添加是有争议的,因为
- 这个命名似乎没有充分描述它是“主要”演员的事实
- 从规范化的角度来看,在
FILM
表上重复此信息似乎是多余的,因为FILM_ACTOR
表可以有一个关于演员是电影中“主要”演员的附加标志。
可以看出,包含 NATURAL JOIN
或 JOIN .. USING
的查询很容易出错(通常是微妙的),并且当模式演变时更容易破坏。 因此,最好完全避免使用该语言功能,除非是偶尔的临时查询。
反馈
您对此页面有任何反馈吗? 我们很乐意听到!