2015-04-08 2 views
2

Мне просто интересно. Если у меня есть две таблицы, скажем, Клиенты и Заказы. Клиенты имеют уникальный и первичный ключ ID_Client. У ордеров также есть поле ID_Client и отношение для поддержания целостности таблицы клиента по полю ID_Client.Просто интересно узнать о SQL-соединениях

Так что, когда я хочу присоединиться обе таблицы я сделать:

SELECT 
    Orders.*, Clients.Name 
FROM 
    Orders 
INNER JOIN 
    Clients ON Clients.ID_Client = Orders.ID_Client 

Так что, если я взял работу, чтобы создать первичный ключ, а также связь между таблицами,

Есть ли причина, почему Мне нужно явно включить объединенные столбцы в оговорку on?

Почему я не могу сделать что-то вроде:

SELECT 
    Orders.*, Clients.Name 
FROM 
    Orders 
INNER JOIN 
    Clients 

Так SQL должны знать, какие столбцы связаны обе таблицы ...

+5

Почему я не могу написать «Получите записи, которые я хочу»? –

+1

Да потому, что если sql всегда просто предполагал, что столбцы внешнего ключа используют в качестве предикатов соединения, это не позволит гибкости, если вы по какой-то причине хотите присоединиться к другим столбцам. Определение отношений - это НЕ о том, чтобы сделать вашу жизнь проще, как разработчик, а именно для поддержания целостности данных. –

+1

@Tom: Было бы хорошо, когда вы впервые напишите этот sql. это было бы ** HELL **, когда кто-то еще должен прочитать это через 18 месяцев, а sql содержит 10 таблиц, и он должен проверить отношения всех из них, чтобы узнать, что случилось с sql. –

ответ

5

У меня был тот же вопрос раз и я нашел большое объяснение его на Database Administrator Stack Exchange, ответ ниже был тем, который я считаю лучшим, но вы также можете ссылаться на ссылку для дополнительных объяснений.

Внешний ключ предназначен для сдерживает данные. т.е. принудительное использование ссылочной целостности . Вот и все. Ничего больше.

  1. Вы можете иметь несколько внешних ключей в одной таблице. Рассмотрим следующее, где отгрузка имеет начальную точку и конечную точку.

    table: USA_States 
    StateID 
    StateName 
    
    table: Shipment 
    ShipmentID 
    PickupStateID Foreign key 
    DeliveryStateID Foreign key 
    

    Возможно, вы захотите присоединиться на основе состояния срабатывания. Возможно, вы хотите присоединиться к состоянию доставки. Возможно, вы хотите выполнить 2 соединения для обоих! Двигатель sql не знает, чего вы хотите.

  2. Вы часто переходите на скалярные значения. Хотя скаляры обычно являются результатом промежуточных вычислений, иногда у вас будет таблица специального назначения с ровно 1 записью. Если двигатель попытался установить , то обнаружите ключ foriegn для соединения .... это не имеет смысла, потому что перекрестные соединения никогда не совпадают с столбцом.

  3. В некоторых особых случаях вы присоединяетесь к колонкам, где ни один не является уникальным. Поэтому наличие PK/FK на этих столбцах невозможно.

  4. Вы можете думать, пункты 2 и 3 выше, не актуальны, так как вопросы о том, когда есть IS один PK/FK отношения между таблицами. Однако наличие одиночного PK/FK между таблицами не означает, что вы не можете подключить другие поля к , кроме PK/FK. Двигатель sql не знал бы, к каким полям вы присоединяетесь .

  5. Допустим, у вас есть таблица «USA_States» и 5 других таблиц с FK для состояний. В «пяти» таблицах также есть несколько внешних ключей к друг другу. Должен ли модуль sql автоматически присоединяться к «пяти» таблицам с «USA_States»? Или он должен присоединиться к «пятерке» друг к другу? И то и другое? Вы можете настроить отношения так, чтобы движок sql вводил бесконечный цикл , пытаясь объединить все вместе. В этой ситуации невозможно заставить SQL-сервер угадать, чего вы хотите.

В итоге: PK/FK не имеет ничего общего с объединения таблиц. Это отдельные несвязанные вещи.Это просто случайность природы, которую вы часто присоединяетесь к колонкам PK/FK.

Хотите, чтобы двигатель sql догадался, если это полное, левое, правое или внутреннее соединение? Я так не думаю. Хотя это, возможно, будет меньше греха, чем угадать столбцы для присоединения.

+0

Вы также можете добавить 6: Что делать, если после написания хранимой процедуры или просмотра кто-то добавит новый внешний ключ? –

+0

Идея может быть «Если нет предложения On, а таблицы имеют только одно отношение к ключу, попробуйте присоединиться к ним. Если бы не SQL, попросите явно указать предложение ON». То же самое, если вы присоедините две таблицы (a и b) с общим именем поля и используйте SELECT a. *, B. *. Если A и B имеют одинаковые имена полей, SQL дает ошибку. Тот же принцип здесь – ericpap

+0

Хорошее объяснение. Спасибо – ericpap

0

Это так. :)

В стандарте sql говорится, что вы должны сказать, на каких столбцах присоединиться. Ограничения предназначены только для ссылочной целостности. С mysql поддержка соединения «join table using (column1, column2)», но тогда эти столбцы должны присутствовать в обеих таблицах.

+0

Надеюсь, что никто не использует нестандартную форму 'JOIN TABLE USING()', чтобы сохранить несколько символов. –

+0

Надеюсь, что так тоже :) –

1

Если вы не указали явно имена полей в запросе, SQL не знает, какие поля для использования. У вас не всегда будут поля, которые называются одинаковыми, и вы не всегда будете присоединяться к первичному ключу. Например, отношения могут быть между двумя полями внешнего ключа с именем «Client_Address» и «Delivery_Address». В этом случае вы можете легко увидеть, как вам нужно указать имя поля.

В качестве примера:

SELECT o.*, c.Name 
FROM Clients c 
INNER JOIN Orders o 
ON o.Delivery_Address = c.Client_Address  
+0

Хорошо. Пока я вижу, что имена полей не имеют значения, потому что я создаю связь между обеими таблицами независимо от имен полей. SQL Может предположить, что если я не указал предложение on, то он пытается присоединиться к соотношению между таблицами. – ericpap

+0

№ Нет никакого отношения. Это ограничение внешнего ключа *, а не отношение. Если вы настаиваете на теории, * table * - это отношение между данными, хранящимися в его полях. –

+0

Вы также можете создать представление в SQL Server для обработки отношений. Представления действуют аналогично таблицам, и они строятся вне запроса. – Jon

1

Есть ли причина, почему мне нужно явно включать то joinned полей на п?

Да, потому что вам все равно нужно сообщить серверу базы данных, что вы хотите. «Делать то, что я имею в виду», пока не входит в возможности какой-либо программной системы.

Внешние ключи - это инструменты для обеспечения целостности данных. Они не определяют, как вы можете присоединиться к таблицам. Вы можете присоединиться к при любых условиях, которые выражаются через выражение SQL.

Другими словами, предложение join связывает две таблицы друг с другом с помощью свободно определяемого условия, которое должно оцениваться как истинное, учитывая две строки слева и справа от соединения. Он не должен быть внешним ключом, это может быть любое условие.

Хотите найти людей, имеющих фамилии, равные продуктам, которые вы продаете?

SELECT 
    Products.Name, 
    Clients.LastName 
FROM 
    Products 
    INNER JOIN Clients ON Products.Name = Clients.LastName 

Существует нет даже внешнего ключа между Продуктами и Клиентами, но все это работает.

+0

Я согласен, но это не моя точка зрения. Я знаю, что могу присоединиться к любым полям. Все, что я говорю, это то, что SQL может быть умным, чтобы знать, что, если я не укажу предложение on, могу попробовать использовать ключ foreing. Я уверен, что вы согласны со мной, что может радикально уменьшить sql sintaxis при нескольких объединениях. – ericpap

+2

@ericpap нет, совсем нет. Это сделало бы вещи более запутанными, особенно в объединениях с несколькими столами. Вам нужно будет найти схему всех таблиц, чтобы узнать, почему была возвращена определенная строка. –

+1

@ericpap * «Все, что я говорю, это то, что компьютер может быть умным и просто делать то, что я считаю наиболее подходящим в то время». * ;-) – Tomalak

0

Причины, почему это поведение не по умолчанию

Поскольку одна таблица может иметь несколько столбцов, ссылающихся обратно в один столбец в другой таблице.

Во многих устаревших базах данных нет ограничений по внешнему ключу, но столбцы «Предполагается, что они» ссылаются на какой-либо столбец в другой таблице.

Условия соединения не всегда такие же простые, как A.Column = B.Column. И список продолжается…….

разработчики Microsoft были достаточно умны, чтобы позволить нам принять это решение, а не их гадать, что он всегда будет A.Column = B.Column

+0

Это не имеет ничего общего с Microsoft, это стандарт SQL. Кроме того, подумайте о взглядах, CTE и всех других конструкциях, отличных от таблицы –

+0

Я согласен, но это не моя точка зрения. Я знаю, что могу присоединиться к любым полям. Все, что я говорю, это то, что SQL может быть умным, чтобы знать, что, если я не укажу предложение on, могу попробовать использовать ключ foreing. Я уверен, что вы согласны со мной, что может резко снизить sql sintaxis при множественных объединениях. – ericpap