Diferença entre junção natural e junção interna

197

Qual é a diferença entre uma junção natural e uma junção interna?

ferreiro
fonte
3
Esta pergunta não é uma duplicata da outra, pois trata-se de junções INNER vs NATURAL, que não são abordadas na outra.
1
Ao mesmo tempo, isso foi fechado como uma duplicata de Qual é a diferença entre junções esquerda, direita, externa e interna , mas essa pergunta não aborda a diferença entre junções internas e junções naturais.
Jonathan Leffler

Respostas:

250

Uma diferença significativa entre INNER JOIN e NATURAL JOIN é o número de colunas retornadas.

Considerar:

TableA                           TableB
+------------+----------+        +--------------------+    
|Column1     | Column2  |        |Column1  |  Column3 |
+-----------------------+        +--------------------+
| 1          |  2       |        | 1       |   3      |
+------------+----------+        +---------+----------+

As INNER JOINtabelas TableA e TableB na coluna1 retornarão

SELECT * FROM TableA AS a INNER JOIN TableB AS b USING (Column1);
SELECT * FROM TableA AS a INNER JOIN TableB AS b ON a.Column1 = b.Column1;
+------------+-----------+---------------------+    
| a.Column1  | a.Column2 | b.Column1| b.Column3|
+------------------------+---------------------+
| 1          |  2        | 1        |   3      |
+------------+-----------+----------+----------+

O NATURAL JOINTableA e TableB na coluna1 retornará:

SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+    
|Column1     | Column2  | Column3  |
+-----------------------+----------+
| 1          |  2       |   3      |
+------------+----------+----------+

A coluna repetida é evitada.

(AFAICT da gramática padrão, você não pode especificar as colunas de junção em uma junção natural; a junção é estritamente baseada em nome. Consulte também Wikipedia .)

( Há uma trapaça na saída da junção interna; o a.eb. partes não estariam em nomes de coluna; você só tem column1, column2, column1, column3como os títulos. )

Jonathan Leffler
fonte
2
Eu tenho duas tabelas TableA (Column1, Column2) e TableB (Column2, Column3).
2
16
Colapsar colunas na saída é o aspecto menos importante de uma junção natural. As coisas que você precisa saber são: (A) ele se une automaticamente aos campos com o mesmo nome e (B) faz com que você fique com a merda quando você menos espera. No meu mundo, o uso de uma junção natural é motivo para demissão.
8
@JonofAllTrades Você pode explicar mais sobre o que exatamente NATURAL JOINvai arruinar, por que é inesperado e em que mundo você está?
Bryson
35
Isso é abordado de alguma forma na resposta do usuário166390. Digamos que você tenha uma união natural entre Customerse Employeesparticipando EmployeeID. Employeestambém tem um ManagerIDcampo Está tudo bem. Então, algum dia, alguém adiciona um ManagerIDcampo à Customersmesa. Sua associação não será interrompida (isso seria uma piedade), mas agora incluirá um segundo campo e funcionará incorretamente . Assim, uma mudança aparentemente inofensiva pode quebrar algo apenas distante. MUITO MAL. A única vantagem de uma junção natural é economizar um pouco de digitação, e a desvantagem é substancial.
2
@ Jonathan, em relação à sua resposta, você declarou que SELECT * FROM TableA INNER JOIN TableB USING (Column1)fornece 4 colunas. Isso não está correto porque, SELECT * FROM TableA INNER JOIN TableB USING (Column1)e SELECT * FROM TableA NATURAL JOIN TableBsão iguais, ambos fornecem 3 colunas.
Pacerier
81
  • Um interior junção é aquela em que a linha correspondente na tabela unida é necessária para que uma linha da primeira tabela seja retornada
  • Uma junção externa é aquela em que a linha correspondente na tabela unida não é necessária para que uma linha da primeira tabela seja retornada
  • Uma junção natural é uma junção (você pode ter natural leftou natural right) que pressupõe que os critérios de junção estejam onde as colunas com o mesmo nome nas duas tabelas coincidem

Eu evitaria o uso de junções naturais como a praga, porque as junções naturais são:

  • não é sql padrão [SQL 92] e, portanto, não é portátil, não é particularmente legível (pela maioria dos codificadores SQL) e possivelmente não é suportado por várias ferramentas / bibliotecas
  • não informativo; você não pode dizer em quais colunas estão sendo unidas sem se referir ao esquema
  • suas condições de junção são invisivelmente vulneráveis ​​a alterações de esquema - se houver várias colunas de junção natural e uma dessas colunas for removida de uma tabela, a consulta ainda será executada, mas provavelmente não corretamente, e essa alteração no comportamento será silenciosa
  • dificilmente vale o esforço; você está economizando apenas 10 segundos de digitação
Boêmio
fonte
2
Eu acho que a esquerda / direita para o exterior deve ser mencionada (já que o exterior é mencionado). Mas, caso contrário, agradável e conciso: faltam apenas os exemplos de diagramas de registros SQL.
2
ESQUERDA NATURAL e DIREITO NATURAL também existem. Mas sim, ainda os evite.
MatBailie
1
@ Bohemian, No que diz respeito a "evitá-los como uma praga", existem casos de uso reais para junções naturais nas quais eles são úteis. mariadb.com/kb/en/sql-99/natural-join "... Os aparência casual 'Livros NATURAL JOIN Checkouts' só é possível quando banco de dados convenções de nomenclatura são formais e executadas ...."
Pacerier
2
@sqlvovel há muito errado com o seu comentário, especificamente está incorreto. As colunas de junção não podem ser "especificadas em uma lista de seleção". A definição de uma junção natural é a junção em * todas as colunas com o mesmo nome *. No documento do MySQL: O NATURAL [LEFT] JOIN de duas tabelas é definido como semanticamente equivalente a um INNER JOIN ou LEFT JOIN com uma cláusula USING que nomeia todas as colunas que existem nas duas tabelas. . E outra coisa - na prática, é inútil, porque idé onipresente e inútil participar; nomes de chaves estrangeiras comuns são tablename_id. Associações naturais são uma má, má, má ideia.
Bohemian
2
Não há colunas retornadas duplas na minha consulta. Uma das vantagens da semântica de NJ é que as colunas duplicadas nunca são retornadas. Sua consulta anterior também era "menos segura" que a minha porque falharia se uma coluna chamada "a" fosse adicionada a t2 (porque a condição de junção sem alias é ambígua). Suspeito que seus preconceitos contra NJ se baseiem no fato de você não ter tentado em um produto em que o SQL padrão é suportado adequadamente. A questão aqui é sobre SQL, não MySQL - coisas bem diferentes. Você ainda não corrigiu sua resposta por não ser um padrão.
Nvogel
27

Uma junção natural é apenas um atalho para evitar a digitação, com a presunção de que a junção é simples e corresponde a campos com o mesmo nome.

SELECT
  *
FROM
  table1
NATURAL JOIN
  table2
    -- implicitly uses `room_number` to join

É o mesmo que...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON table1.room_number = table2.room_number

O que você não pode fazer com o formato de atalho, no entanto, é junções mais complexas ...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON (table1.room_number = table2.room_number)
    OR (table1.room_number IS NULL AND table2.room_number IS NULL)
MatBailie
fonte
2
@ JonathanLeffler - No MySQL, certamente.
MatBailie
3
OK - interessante. Eu perguntei porque o padrão SQL não parece permitir isso (mas extensões são sempre possíveis).
Jonathan Leffler
Qual DBMS permite essa sintaxe não padrão NATURAL JOIN ... USING ():? O padrão é a NATURAL JOIN bora JOIN b USING (c)
ypercubeᵀᴹ
1
"apenas um atalho para evitar digitar" é uma declaração incorreta. Seu recurso mais significativo é que não resulta em colunas duplicadas.
Onedaywhen
... por exemplo, o resultado da sua consulta que usa junção natural terá apenas uma coluna denominada room_number, enquanto suas junções internas terão duas colunas denominadas room_number.
onedaywhen
13

O SQL não é fiel ao modelo relacional de várias maneiras. O resultado de uma consulta SQL não é uma relação, pois pode ter colunas com nomes duplicados, colunas 'anônimas' (sem nome), linhas duplicadas, nulos etc. O SQL não trata tabelas como relações, porque depende da ordem das colunas, etc.

A idéia por trás NATURAL JOINdo SQL é facilitar a fidelidade ao modelo relacional. O resultado de NATURAL JOINduas tabelas terá colunas desduplicadas por nome, portanto, nenhuma coluna anônima. Da mesma forma, UNION CORRESPONDINGe EXCEPT CORRESPONDINGsão fornecidos para abordar a dependência do SQL na ordenação de colunas na UNIONsintaxe herdada .

No entanto, como em todas as técnicas de programação, requer disciplina para ser útil. Um requisito para um êxito NATURAL JOINé consistentemente nomeado de colunas, porque as junções são implícitas em colunas com os mesmos nomes (é uma pena que a sintaxe para renomear colunas no SQL seja detalhada, mas o efeito colateral é incentivar a disciplina ao nomear colunas nas tabelas base e VIEWs :)

Observe que um SQL NATURAL JOINé uma junção equi **, no entanto, isso não impede a utilidade. Considere que, se NATURAL JOINfosse o único tipo de junção suportado no SQL, ele ainda estaria completo em termos relacionais .

Embora seja verdade que qualquer um NATURAL JOINpossa ser escrito usando INNER JOINe projection ( SELECT), também é verdade que qualquer um INNER JOINpode ser escrito usando product ( CROSS JOIN) e restrição ( WHERE); Observe também que uma NATURAL JOINtabela entre sem nomes de colunas em comum dará o mesmo resultado que CROSS JOIN. Portanto, se você está interessado apenas em resultados que são relações (e por que nunca ?!), esse NATURAL JOINé o único tipo de associação que você precisa. Claro, é verdade que, de uma perspectiva de design de linguagem, abreviações como INNER JOINe CROSS JOINtêm seu valor, mas também consideramos que quase qualquer consulta SQL pode ser escrita de 10 maneiras sintaticamente diferentes, mas semanticamente equivalentes, e é isso que torna os otimizadores de SQL tão difíceis desenvolver.

Aqui estão alguns exemplos de consultas (usando o banco de dados usual de peças e fornecedores ) que são semanticamente equivalentes:

SELECT *
  FROM S NATURAL JOIN SP;

-- Must disambiguate and 'project away' duplicate SNO attribute
SELECT S.SNO, SNAME, STATUS, CITY, PNO, QTY
  FROM S INNER JOIN SP 
          USING (SNO);                        

-- Alternative projection
SELECT S.*, PNO, QTY
  FROM S INNER JOIN SP 
          ON S.SNO = SP.SNO;

-- Same columns, different order == equivalent?!
SELECT SP.*, S.SNAME, S.STATUS, S.CITY
  FROM S INNER JOIN SP 
      ON S.SNO = SP.SNO;

-- 'Old school'
SELECT S.*, PNO, QTY
  FROM S, SP 
 WHERE S.SNO = SP.SNO;

** A junção natural relacional não é um equijoin, é uma projeção de um. - philipxy

um dia quando
fonte
A junção natural relacional não é um equijoin, é uma projeção de um. A junção natural do SQL é um equijoin do SQL (é possível duplicar) - é definida em termos de junção interna usando.
philipxy
@ philipxy: Obrigado, eu fiz alterações. Sinta-se à vontade para editar - esta ou qualquer uma das minhas respostas - por distorções e mal-entendidos. Eu ainda estou aprendendo com você :)
onedaywhen
9

Uma NATURALjunção é apenas uma sintaxe curta para uma junção específica INNER - ou "junção equi" - e, uma vez que a sintaxe é desembrulhada, ambos representam a mesma operação de Álgebra Relacional. Não é um "tipo diferente" de junção, como no caso de OUTER( LEFT/ RIGHT) ou CROSSjunções.

Veja a seção equi-join na Wikipedia:

Uma junção natural oferece uma especialização adicional de junções equi. O predicado de junção surge implicitamente comparando todas as colunas nas duas tabelas que possuem os mesmos nomes de coluna nas tabelas unidas. A tabela unida resultante contém apenas uma coluna para cada par de colunas com o mesmo nome.

A maioria dos especialistas concorda que JUNTAS NATURAIS são perigosas e, portanto, desencorajam fortemente seu uso. O perigo advém da adição inadvertida de uma nova coluna, com o mesmo nome de outra coluna ...

Ou seja, todas as NATURALjunções podem ser escritas como INNERjunções (mas o inverso não é verdadeiro). Para fazer isso, basta criar o predicado explicitamente - por exemplo, USINGouON - e, como Jonathan Leffler apontou, selecione as colunas desejadas do conjunto de resultados para evitar "duplicatas", se desejado.

Feliz codificação.


(A NATURALpalavra-chave também pode ser aplicada LEFTe RIGHTassocia - se, e o mesmo se aplica. Uma NATURAL LEFT/RIGHTassociação é apenas uma sintaxe curta para uma associação específica LEFT/RIGHT .)

Comunidade
fonte
2
"Junção NATURAL é apenas uma sintaxe curta para junção equi" [cortada] - e, uma vez que a sintaxe é desembrulhada, ambas representam a mesma Álgebra Relacional "- você está correto: isso é verdade para a álgebra relacional, mas sua resposta é quebrada depois disso, por exemplo, "a maioria dos especialistas concorda que JUNTAS NATURAIS são perigosas e, portanto, desencorajam fortemente seu uso" - que especialistas em álgebra relacional dizem isso ?!
usar o seguinte código
2

Junção natural: é um resultado combinado ou combinado de todas as colunas nas duas tabelas. Ele retornará todas as linhas da primeira tabela em relação à segunda tabela.

Junção interna: essa junção funcionará, a menos que algum nome da coluna seja sxame em duas tabelas

Victor Bhatti
fonte
3
Não acho que sua resposta seja clara o suficiente e seria necessária uma grande reescrita para corrigi-la.
onedaywhen
0

Uma Junção Natural é onde duas tabelas são unidas com base em todas as colunas comuns.

coluna comum: é uma coluna com o mesmo nome nas duas tabelas + com tipos de dados compatíveis nas duas tabelas. Você pode usar apenas = operador

Uma Junção Interna é onde duas tabelas são unidas com base em colunas comuns mencionadas na cláusula ON.

coluna comum: é uma coluna que possui tipos de dados compatíveis nas duas tabelas, mas não precisa ter o mesmo nome. Você só pode usar qualquer operador de comparação, como =, <=, >=, <, >,<>

Suchitra Phadke
fonte
-2

A diferença é que int a junção interna (equi / padrão) e a junção natural que na coluna comum da junção natuarl serão exibidas em um único tempo, mas a junção interna / equi / padrão / simples a coluna comum será exibida duas vezes.

Rajat Gupta
fonte
-2

A junção interna e a junção natural são quase iguais, mas há uma pequena diferença entre elas. A diferença está na junção natural, não é necessário especificar a condição, mas na condição de junção interna é obrigatória. Se especificarmos a condição na junção interna, as tabelas resultantes serão como um produto cartesiano.

rashedcs
fonte
Por que não há necessidade de especificar condições de junção? Sob quais circunstâncias a especificação de condições em uma junção interna resultaria em algo como um produto cartesiano?
Onedaywhen
Chamar a junção externa e interna de "quase o mesmo" é um pequeno eufemismo. Talvez você possa elaborar sua avaliação?
TMOTTM
-3
mysql> SELECT  * FROM tb1 ;
+----+------+
| id | num  |
+----+------+
|  6 |   60 |
|  7 |   70 |
|  8 |   80 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

mysql> SELECT  * FROM tb2 ;
+----+------+
| id | num  |
+----+------+
|  4 |   40 |
|  5 |   50 |
|  9 |   90 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

JUNÇÃO INTERNA :

mysql> SELECT  * FROM tb1 JOIN tb2 ; 
+----+------+----+------+
| id | num  | id | num  |
+----+------+----+------+
|  6 |   60 |  4 |   40 |
|  7 |   70 |  4 |   40 |
|  8 |   80 |  4 |   40 |
|  1 |    1 |  4 |   40 |
|  2 |    2 |  4 |   40 |
|  3 |    3 |  4 |   40 |
|  6 |   60 |  5 |   50 |
|  7 |   70 |  5 |   50 |
|  8 |   80 |  5 |   50 |
.......more......
return 36 rows in set (0.01 sec) 
AND NATURAL JOIN :

    mysql> SELECT  * FROM tb1 NATURAL JOIN tb2 ;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |    1 |
    |  2 |    2 |
    |  3 |    3 |
    +----+------+
    3 rows in set (0.01 sec)
zloctb
fonte
-4

Junção interna, junte duas tabelas em que o nome da coluna é o mesmo.

Junção natural, junte duas tabelas em que o nome da coluna e os tipos de dados são iguais.

Tejeshwar
fonte
Isso está completamente incorreto. A NATURAL JOIN(como várias pessoas apontaram anos atrás) é aquela em que os nomes das colunas são os mesmos. O tipo de dados não precisa ser o mesmo. Os campos usados ​​para uma INNER JOINnecessidade não precisam ter o mesmo nome.