Какая связь между этими таблицами?
У меня есть две таблицы, которые имеют внешние ключи к первичному ключу друг друга. Эта БД на французском языке. Я переведу две таблицы, которые я хочу, чтобы вы поняли.
- Ателье Кухня ==> Кухня
- Cuisinier == > Готовить шеф-повар
Итак, на этой картинке мы видим, что в Kitchen
Таблица у нас есть ПК, на который ссылается ФК из Cooking chef
Таблица; в Cooking chef
Таблица у нас есть ПК, на который ссылается ФК из Kitchen
Таблица. Так что я в замешательстве. Я не понимаю такого рода отношения между этими таблицами.
И я надеюсь проверить свой запрос, который я сделал, чтобы создать эти две таблицы, если это правильно
CREATE TABLE [ATELIER CUISINE] (
NumCuisine INT NOT NULL PRIMARY KEY,
TelCuisine VARCHAR(50) NOT NULL
)
CREATE TABLE CUISINIER (
NumCuisinier INT NOT NULL PRIMARY KEY,
NomCuis VARCHAR(50) NOT NULL,
DateEmb DATE NOT NULL,
NumCuisine INT NOT NULL CONSTRAINT FK_CUISINIER_NumCuisine FOREIGN KEY REFERENCES [ATELIER CUISINE](NumCuisine)
Смотрите изображение здесь:
Модель отношений базы данных ресторана
Смотрите изображение здесь:
Пример записи для некоторых таблиц
4 ответа
ИМХО, этот "обмен ключами" явно неправильный; Исходя из выборочных данных, мы можем предположить (но не точно!), что отношение между [ATELIER CUISINE] и [CUISINER] одно-ко-многим (таблица CUISINIER), в этом случае [ATELIER CUSINE] НЕ должно иметь NumCuisinier столбец, или иначе NumCuisine не является первичным ключом (который, согласно модели данных, является)! Таким образом, модель данных, вероятно, неверна.
Моя лучшая ставка на ваш запрос будет
SELECT B.*, A.TelCuisine
FROM [ATELIER CUISINE] A INNER JOIN CUISINIER B ON A.NumCuisine = B.NumCuisine
Если, конечно, NumCuisinier в таблице [ATELIER CUISINIER] НЕ является FK, как предполагает @marcothesane, и он имеет совершенно другое значение, и в этом случае он должен содержаться в наборе результатов (но с другим псевдонимом):
SELECT B.*, A.TelCuisine, A.NumCuisinier as [HeadChef]
FROM [ATELIER CUISINE] A INNER JOIN CUISINIER B ON A.NumCuisine = B.NumCuisine
Таблицы (база и результаты запроса) представляют отношения приложения.
Из (более ранней версии) этого ответа:
Для каждой базовой таблицы администратор базы данных предоставляет предикат - шаблон оператора заполнения на естественном языке (named-)blank, параметризованный именами столбцов.
-- chef with id NUMCUISINIER has name NOMCUIS and ...
CUISINIER(NumCuisinier, NomCuis, ...)
Базовая таблица содержит строки, которые, используя значения своих столбцов для заполнения (именованных) пробелов, делают истинное утверждение, известное как предложение.
CUISINIER
NumCuisinier | NomCuis | ...
----------------------------
1 | DURAND | ... -- chef with id 1 has name 'DURAND' and ...
...
-- AND for every absent row (NUMCUISINIER, NOMCUIS, ...),
NOT (chef with id NUMCUISINIER has name NOMCUIS and ...)
Каждое выражение / предложение SQL преобразует старое табличное значение в новое значение, содержащее строки, которые составляют истинное утверждение из некоторого нового предиката, который может быть выражен в терминах исходного предиката.
Предикат
R JOIN S
это предикатR
AND
с предикатомS
, ПредикатR ON/WHERE
condition
это предикатR
AND
редактировать сcondition
,
/* rows where
chef with id c.NUMCUISINIER has name c.NOMCUIS and ...
AND kitchen with id a.NUMCUISINE ...
AND c.NUMCUISINE = a.NUMCUISINE
*/
CUISINIER c join ATELIER_CUISINE a on c.NumCuisine = a.NumCuisine
Таким образом, мы запрашиваем, записывая выражение SQL, связанный предикат которого характеризует отношение приложения (или ассоциацию), строки которого мы хотим.
ФК (внешние ключи) не являются отношениями.
Ограничения FK некоторые люди называют отношениями, но это не так. Это факты.
FK таблицы - это набор столбцов. "FK" также используется для обозначения связанного ограничения, которое мы имеем, когда у нас есть FK. Что, как и любое ограничение, является верным утверждением в каждом состоянии базы данных. (Эквивалентно, каждая прикладная ситуация.) Ограничение FK говорит, что значения для определенных столбцов в определенной таблице также являются значениями для определенных столбцов в определенной другой таблице, где они образуют CK (ключ-кандидат). (Эквивалентно, это говорит о том, что если некоторые значения / объекты удовлетворяют определенной связи приложения, то некоторые из них плюс некоторые другие значения / объекты удовлетворяют определенной другой связи приложения, где значения / объекты формируют CK.) PK (первичные ключи) просто некоторые CK, которые вы решили назвать PK.)
У ограничения FK есть определенная связанная прикладная связь, но это не то, что подразумевается, когда "связь" используется для "FK (ограничение)". ("FK" также используется для обозначения значения subrow для столбцов FK или значения в строке для столбца FK с одним столбцом.)
Вы должны знать, что означает каждая таблица.
Предикаты должны предоставляться дизайнером вместе со схемой. Вы должны выяснить, что означают таблицы. Затем выразите свой предикат запроса в терминах их. Затем преобразовать в SQL.
Иногда мы догадываемся о предикатах более или менее успешно с помощью здравого смысла и именования. ФК и другие ограничения могут помочь с угадыванием.
Здравый смысл, имена, PK (подчеркнутые?) И FK ("#"?) Предлагают значения таблиц для вас, как:
-- chef with id NUMCUISINIER has name NOMCUIS and start date DATEEMB and works in kitchen with id NUMCUISINE
CUISINIER(NumCuisinier, NomCuis, NateEmb, NumCuisine)
-- kitchen with id NUMCUISINE has phone number TELCUISINE and chef with id NUMCUISINIER as head chef
ATELIER_CUISINE(NumCuisine, TelCuisine, NumCuisinier)
ФК не нужны для запроса
В запросе SQL над строками, которые превращают предикат в истинное предложение, всегда возвращаются строки. Неважно, сколько строк в NumCuisiner
или же NumCuisine
значение (т. е. являются ли они PK) или должно ли значение появляться в другой таблице (т. е. являются ли они FK). Или каково любое другое ограничение.
Нам нужно знать предикаты для запроса. Когда мы знаем их, нам не нужно знать никаких ограничений. Нам не нужно знать ФК.
FK, CK, PK, альтернативные ключи и наборы столбцов UNIQUE (суперключи) не имеют отношения к запросам, за исключением того, что если вы знаете, что что-то является суперключем из-за одного, то вы можете писать запросы, включающие извлечение значения из результата, состоящего из одной строки. Но вы могли бы выразить тот же результат без извлечений.
Итак, вы хотите знать, как запросить это.
Как многие говорили, это зависит от того, что нужно.
И - Philipxy - я не могу рассматривать внешний ключ как факт; Вы не можете рассчитать сумму, среднее или стандартное отклонение значений внешнего ключа. И для Кимбалла, как и я, факты - это факты, потому что вы можете делать эти вещи с ними.
И внешний ключ - это отображение на уровне языка определения данных отношений между сущностями, которые изображены в таблицах. Моя точка зрения, по крайней мере. Но, на самом деле, кого это волнует, пока это работает - и до тех пор, пока мы не создаем путаницу.
Было сказано, что:
Если вам нужны номера телефонов всех кухонь и имя их шеф-повара:
SELECT
telCuisine
, nomCuisinier
FROM atelier_cuisine
JOIN cuisinier USING(numCuisinier)
;
Если вам нужны все повара (неважно, шеф-повар или кто-либо еще), которых вы можете получить по одному номеру телефона на одной кухне, вы можете:
SELECT
nomCuisinier
FROM atelier_cuisine
JOIN cuisinier USING(numCuisine)
WHERE telCuisine = '+39 6 23 25 22 13';
Если вы хотите знать все телефонные номера кухонь, где работает Гастон, вы идете:
SELECT
telCuisine
FROM cuisinier
JOIN atelier_cuisine USING(numCuisine)
WHERE numCuisinier='Gaston'
;
Я знаю, что есть возможность использовать предложение ON для объединений, но я ленив и предпочитаю предложение USING()...
Кроме этого, я бы не знал, какой у тебя может быть вопрос, правда...
То, что вы видите здесь, скорее всего, является самым важным детским паттерном.
Я хотел бы предположить, что мы должны начать со стандартного отношения родитель-ребенок "один kitchen
использует один или несколько chef
s". Таким образом, у нас был бы внешний ключ в cuisinier
/ chef таблица, которая содержит идентификатор atelier_cuisine
/ кухня, где cuisinier
под вопросом работает.
Но по какой-то причине кухня должна указывать на самого важного повара, работающего там. Только это numCuisinier
или chefID / cookID - это неправильное наименование столбца внешнего ключа, поскольку он вводит в заблуждение, так же, как вводит нас в заблуждение в вашем примере. Если вы дали ему имя, как numCuisinierChef
или "идентификатор шеф-повара / повара", название столбца не требует пояснений.
Но то, как колонки были названы здесь, может быть и наоборот: шеф-повар работает на одной или нескольких кухнях, но одна кухня - его или ее самый важный работодатель.
Без документации или комментариев в модели данных, вы действительно зажарены...
Надеюсь, что это помогает, а не путает - как модель данных и именования...
Может быть, одна подсказка. МарселоБарбоза действительно вдохновил меня на это: если в atelier_cuisine
, numCuisinier
имеет нулевое значение, а в cuisinier
, numCuisine
НЕ НУЛЬ, то atelier_cuisine
является родителем, и cuisinier
это ребенок, и наоборот.
Марко вменяемый