这些表之间有什么样的关系?

时间:2017-02-12 14:11:24

标签: sql-server foreign-keys relational-database relationship composite-primary-key

我有两个表,彼此的主键都有外键。这个DB是法语。我将翻译我想要你理解的两个表格。

  • Atelier Cuisine ==>厨房
  • Cuisinier ==>烹饪厨师

所以在这张图片中我们看到在Kitchen表中我们有一个来自Cooking chef表的FK引用的PK;在Cooking chef表中,我们有一个来自Kitchen表的FK引用的PK。所以我很困惑。我不明白这些表之间的这种关系。

我希望查看我的查询,如果正确的话,我会创建这两个表

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)

见图像:
Relationship model of the restaurant database

见图像:
Example records for some tables

4 个答案:

答案 0 :(得分:0)

你在这里看到的很可能是最重要的孩子模式。

我认为我们需要从“一个kitchen使用一个或多个chef s”的标准父子关系开始。因此,我们将在cuisinier / chef表中包含一个外键,其中包含atelier_cuisine / kitchen的ID,其中cuisinier有问题。

但出于某种原因,厨房必须能够指出在那里工作的最重要的厨师/厨师。只有numCuisinier或chefID / cookID才是该外键列的错误命名,因为它误导了它,就像它在你的例子中误导我们一样。如果您给它命名为numCuisinierChef或“chef / cook in Chief ID”,则列名称将不言自明。

但是,在这里命名列的方式,它也可能恰恰相反:厨师/厨师在一个或多个厨房工作,但一个厨房是他或她最重要的雇主。

如果没有数据模型中的文档或评论,你就会被炒,真的......

希望这有助于而不是混淆 - 正如数据模型和命名所做的那样......

也许有一个线索。 MarceloBarbosa实际上激励了我: 如果在atelier_cuisine中,numCuisinier无法使用,并且在cuisinier中,numCuisine为非空,则atelier_cuisine是父项,cuisinier 1}}是孩子,反之亦然。

Marco the Sane

答案 1 :(得分:0)

(基本和查询结果)代表应用程序关系。

来自(早期版本)this answer

  

对于每个基表,DBA都提供谓词 - 一个由列名参数化的自然语言填充(命名)空白语句模板。

-- 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表达式/子句将旧表值转换为一个新值,该值保存从某个新谓词生成true语句的行,这些谓词可以用原始谓词表示。

  

R JOIN S的谓词是R AND的谓词S的谓词。 R ON/WHERE condition 的谓词是使用 R 编辑的AND condition的谓词。< / p>

/* 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是一组列。 &#34; FK&#34;也用于表示我们拥有FK时的相关约束。其中每个约束都是每个数据库状态中的真实语句。 (等效地说,每个应用程序情况。)FK约束表示某个表中某些列的值也是某个其他表中某些列的值,它们形成一个CK(候选键)。 (等效地,它表示如果某些值/实体满足某个应用程序关系,那么它们中的一些加上一些其他值/实体满足某些其他应用程序关系,其中值/实体形成CK。)PK(主键)只是你决定叫PK的一些CK。)

FK约束具有某种相关的应用关系,但这并不意味着&#34;关系&#34;用于&#34; FK(约束)&#34;。 (&#34; FK&#34;也用于表示FK列的子行值,或单列FK列的行值)。

您需要知道每个表的含义

必须由设计人员提供谓词以及架构。你需要找出表格的含义。然后根据它们表达您的查询谓词。然后转换为SQL。

有时我们通过常识和命名或多或少成功地在谓词猜测。 FK和其他约束可以帮助猜测

常识,名字,PK(带下划线的?)和FK(&#34;#&#34;?)为您提供表格含义:

-- 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)

查询

不需要FK

在上面的SQL查询中,使谓词成为真命题的行总是返回的行。每个NumCuisinerNumCuisine值有多少行(即它们是否为PK)或者某个值是否必须出现在另一个表中(即它们是否为FK)并不重要。或者其他任何约束。

我们需要知道要查询的谓词。当我们了解它们时,我们不需要知道任何约束。我们不需要了解FK。

FK,CK,PK,备用密钥和UNIQUE列集(超级密钥)与查询无关,除非你知道某个东西是超级密钥,那么你可以编写涉及从一行结果中提取值的查询。但你可以在没有提取的情况下表达相同的结果。

答案 2 :(得分:0)

恕我直言,这种“钥匙交换”显然是错误的;从样本数据中我们可以推测(但不是肯定的!)[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

除非[ATELIER CUISINIER]表中的NumCuisinier当然不是FK,因为@marcothesane建议并且它具有完全不同的含义,在这种情况下它应该包含在结果集中(但具有不同的别名):< / p>

SELECT B.*, A.TelCuisine, A.NumCuisinier as [HeadChef]
FROM [ATELIER CUISINE] A INNER JOIN CUISINIER B ON A.NumCuisine = B.NumCuisine

答案 3 :(得分:0)

所以你想知道如何查询。

正如许多人所说,这取决于需要什么。

而且 - philipxy - 我不能把外键视为事实;您无法计算外键值的总和或平均值或标准差。而且,对于像我这样的Kimball-ian,事实就是事实,因为你可以和他们一起做这些事情。

外键是数据定义语言级别对表格所描述的实体之间关系的描述。我的观点,至少。但是,实际上,只要它起作用,谁就会关心 - 只要我们不会造成混乱。

说完了:

如果您需要所有厨房&#39;电话号码和他们的主厨姓名:

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';

如果您想知道Gaston工作的厨房的所有电话号码,请访问:

    SELECT
      telCuisine
    FROM cuisinier
    JOIN atelier_cuisine USING(numCuisine)
    WHERE numCuisinier='Gaston'
;

我知道有可能对连接使用ON子句,但我很懒,更喜欢USING()子句......

除此之外,我不知道你的问题是什么,真的......