好吧,这有点是理论上的,因此,如果一个公正的数据库爱好者提出意见,那将是很好的。
为争辩起见,我们同意存在诸如“基础表”这样的概念。查询,其中一个表驱动了结果集中的大多数信息。想象一下一个查询,其中存在三个关系-TableA,TableB和TableC
让我们说TableA的基数为100万条记录,TableC的基数为500条,TableC的基数为10,000。
假设查询是这样-
SELECT A.Col1
, A.Col2
, A.Col3
, A.Col4
, A.Col5
FROM TableA A
LEFT JOIN TableB B ON B.ID = A.TableBID
LEFT JOIN TableC C ON C.ID = A.TableCID
好,显然 TableA是上面的基本关系。它是最大的表,通过“从”连接来驱动结果集,并且在外观上,列甚至位于结果集的“左侧”。 (左边的东西实际上是我同事的标准。)
现在,让我们假设TableA再次具有100万行,TableB是“连接”或“桥”表,并且具有500,000行,而TableC具有1,000,000行。因此,假设查询只是一个外部联接,以获取TableA和TableC中存在如下所示关系的所有列...
SELECT A.*
, C.*
FROM TableC C
FULL OUTER JOIN TableB B ON C.ID = B.TableAID
FULL OUTER JOIN TableA A ON A.ID = B.TableCID
好吧,给定最后一个查询,谁能告诉我“基本关系”是什么?我认为没有,但是希望其他数据库人发表意见。
答案 0 :(得分:3)
基表是给定的命名表值变量-数据库表。而已。在查询表达式中,其名称是表示其值的叶表达式。 “给定表变量”将更具描述性。查询可以对表使用文字表示法。给定的命名表值常量也被称为“基本”是合理的。与某种“主”表无关。
关系模型基于一个表,该表包含根据其(特征)谓词(由列名参数化的语句模板)。我们提供基表行并获取查询表达式行。
设计器给定的谓词是基表名称的查询表达式。
/* (person, liked) rows where [liker] likes [liked] */ /* (person, liked) rows where Likes(liker, liked) */ SELECT * FROM Likes
作为表文字的查询表达式在列等于值方面具有一定的谓词。
/* (person) rows where
person = 'Bob'
*/
SELECT * FROM (VALUES ('Bob')) dummy (person)
否则,查询表达式具有根据其关系运算符从其组成表表达式谓词构建的谓词。
- 每个代数运算符都对应一个逻辑运算符。
NATURAL JOIN
和AND
RESTRICT
theta
和AND
theta
UNION
和OR
MINUS
和AND NOT
PROJECT
all but
C
和EXISTS C
etc
/* (person) rows where (FOR SOME liked, Likes(person, liked)) OR person = 'Bob' */ SELECT liker AS person FROM Likes UNION VALUES ('Bob')
/* (person, liked) rows where FOR SOME [values for] l1.*, l2.*, person = l1.liker AND liked = l2.liked AND Likes(l1.liker, l1.liked) AND Likes(l2.liker, l2.liked) AND l1.liked = l2.liker AND person = 'Bob' AND NOT Likes(l1.liked, 'Ed') */ Likes l1 INNER JOIN Likes l2 ON l1.liked = l2.liker WHERE l1.liker = 'Bob' AND NOT (l1.liked, 'Ed') IN (SELECT * FROM Likes)
在确定包含查询表达式的谓词时,使用基本查询,文字查询或运算符调用查询表达式没有什么区别。
Is there any rule of thumb to construct SQL query from a human-readable description?
Relational algebra - recode column values
答案 1 :(得分:3)
术语“基础表”具有定义,与您的描述无关。 “基本表”几乎只是一个“表”。也就是说,它不是视图,不是表值函数,也不是查询结果。它是作为显式表存储在数据库中的。
您似乎要掌握的内容似乎与优化策略有关。在优化的上下文中,我使用了类似的术语来描述优化器正在访问的“驱动表”。这样做的目的是区分不同的执行计划。
考虑查询:
from t1 join t2 using (col)
有多个不同的执行计划。以下是一些方法,以及可能被视为“驾驶表”的方法:
for each row in t1
for each row in t2
compare col
--> t1 is the "driving table"
for each row in t2
for each row in t1
compare col
--> t2 is the "driving table"
for each row in t1
look up t2 value using index on t2(col)
--> t1 is the "driving table"
sort t1 by col
sort t2 by col
compare the rows in the two sorted sets
--> no "driving table"
hash t1 by col
hash t2 by col
compare the hash maps
--> no "driving table"
换句话说,“驱动”表与查询结构无关。它基于用于查询的优化策略。也就是说,left join
和right join
限制了优化路径。因此,在嵌套循环或索引查找情况下,“第一个”(或“最后一个”)表将成为驱动表。
答案 2 :(得分:3)
“驱动”表的概念实际上是关于期望DBMS如何在内部执行查询的假设。在没有任何与索引相关的首选项的情况下,基于
在概念化查询时,以一张表的心理形象作为查询的起点可能会有所帮助,但我认为此处问题的答案必须为否。从逻辑上讲,没有驾驶台这样的东西。
答案 3 :(得分:2)
让我提出一个观点,其中基表是FROM
子句中的第一个(即不是JOIN
ed表)。如果可以用一个表或另一个表作为基表来平等地写一条语句,我们可以说有两个(或更多)基表。
在您的第一个查询中,基表为TableA
。如果您在查询中反转TableA
和TableC
,由于LEFT JOIN
,就不能保证得到相同的结果。
在第二个查询中,当您使用FULL JOIN
时,所有3个表都可以反转而不改变结果,因此,这确实是查询的用例,其中所有表都是基表< / em>。