在任何数据库查询中总是有 "base table" 吗?
Is there ALWAYS a "base table" in any database query?
好的,这只是略微 的理论,所以如果有公正的数据库爱好者给出意见就太好了。
为了争论起见,让我们同意存在 "base table" w.r.t 这样的概念。到查询,其中 table 驱动结果集的大部分信息。想象一个查询,其中包含三个关系 - 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就是上面的基关系。它是最大的 table,它通过连接 "from" 来驱动结果集,并且在视觉上列在结果集的 "left side" 上是均匀的。 (左边的东西实际上是我同事的标准)。
现在,我们再次假设 TableA 有 100 万行,TableB 是 "junction" 或 "bridge" table,大约有 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
好的,鉴于最后一个查询,谁能告诉我 "base relation" 是什么?我认为没有,但希望得到另一个数据库人员的意见。
让我提出一个观点,其中 base table 是 FROM
子句中的第一个(即不是 JOIN
ed table)。如果一个语句可以用一个 table 或另一个作为基数 table 来写,我们会说有 两个(或更多)基数 table s。
在您的第一个查询中,基数 table 是 TableA
。如果在查询中反转 TableA
和 TableC
,则不能保证得到相同的结果,因为 LEFT JOIN
.
在第二个查询中,当您使用 FULL JOIN
s 时,所有 3 个 tables 都可以在不改变结果的情况下被反转,所以这确实是一个查询的用例,其中 所有 tables 都是基础 tables。
基础 table 是给定的命名 table 值变量——一个 数据库 table。而已。在查询表达式中,其名称是表示其值的叶表达式。 "Given table variable" 会更具描述性。查询可以对 table 使用文字表示法。将给定的命名 table 值常量也称为 "base" 是合理的。这与某种 "main" table.
无关
关系模型建立在 table 的基础上,其中包含从其(特征) predicate(由列名参数化的语句模板)。我们给出基础 table 行并获取查询表达式行。
作为基本 table 名称的查询表达式带有设计者指定的谓词。
/* (person, liked) rows where [liker] likes [liked] */
/* (person, liked) rows where Likes(liker, liked) */
SELECT * FROM Likes
作为 table 文字的查询表达式在列等于值方面具有特定谓词。
/* (person) rows where
person = 'Bob'
*/
SELECT * FROM (VALUES ('Bob')) dummy (person)
否则,查询表达式有一个谓词根据其关系运算符从其组成 table 表达式谓词构建。
- Every algebra operator corresponds to a certain logic operator.
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?
"base table"这个词有定义,和你描述的没有任何关系。 "base table" 几乎就是 "table"。也就是说,它不是一个视图,它不是一个 table 值函数,它不是一个查询的结果。它是作为显式 table.
存储在数据库中的内容
你所掌握的似乎与优化策略有关。我在优化上下文中使用了类似的术语来描述优化器访问的 "driving table"。这样做的目的是为了区分不同的执行计划。
考虑查询:
from t1 join t2 using (col)
有多个不同的执行计划。以下是一些方法以及它们可能被认为是 "driving table"(如果有的话)的方法:
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"
换句话说,"driving"table与查询结构关系不大。它基于用于查询的优化策略。也就是说,left join
s 和 right join
s 限制了优化路径。因此,在嵌套循环或索引查找情况下,"first"(或"last")table 将是驱动 table.
"driving" table 的概念实际上是关于 DBMS 预期如何在内部执行查询的假设。 基于规则的 查询优化器,在没有任何与索引相关的首选项的情况下,在选择时可能会将 tables 和查询中的连接的顺序视为重要的执行计划。在 cost-based 优化器下,tables 和连接的顺序没有任何意义,因此查询本身的结构不会告诉您哪个 table 首先读取或以什么顺序读取连接条件。
在概念化查询时,在脑海中形成一个 table 作为查询起点的形象可能会有所帮助,但我认为这里问题的答案一定是否定的。照理说开车是没有的table.
好的,这只是略微 的理论,所以如果有公正的数据库爱好者给出意见就太好了。
为了争论起见,让我们同意存在 "base table" w.r.t 这样的概念。到查询,其中 table 驱动结果集的大部分信息。想象一个查询,其中包含三个关系 - 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就是上面的基关系。它是最大的 table,它通过连接 "from" 来驱动结果集,并且在视觉上列在结果集的 "left side" 上是均匀的。 (左边的东西实际上是我同事的标准)。
现在,我们再次假设 TableA 有 100 万行,TableB 是 "junction" 或 "bridge" table,大约有 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
好的,鉴于最后一个查询,谁能告诉我 "base relation" 是什么?我认为没有,但希望得到另一个数据库人员的意见。
让我提出一个观点,其中 base table 是 FROM
子句中的第一个(即不是 JOIN
ed table)。如果一个语句可以用一个 table 或另一个作为基数 table 来写,我们会说有 两个(或更多)基数 table s。
在您的第一个查询中,基数 table 是 TableA
。如果在查询中反转 TableA
和 TableC
,则不能保证得到相同的结果,因为 LEFT JOIN
.
在第二个查询中,当您使用 FULL JOIN
s 时,所有 3 个 tables 都可以在不改变结果的情况下被反转,所以这确实是一个查询的用例,其中 所有 tables 都是基础 tables。
基础 table 是给定的命名 table 值变量——一个 数据库 table。而已。在查询表达式中,其名称是表示其值的叶表达式。 "Given table variable" 会更具描述性。查询可以对 table 使用文字表示法。将给定的命名 table 值常量也称为 "base" 是合理的。这与某种 "main" table.
无关关系模型建立在 table 的基础上,其中包含从其(特征) predicate(由列名参数化的语句模板)。我们给出基础 table 行并获取查询表达式行。
作为基本 table 名称的查询表达式带有设计者指定的谓词。
/* (person, liked) rows where [liker] likes [liked] */ /* (person, liked) rows where Likes(liker, liked) */ SELECT * FROM Likes
作为 table 文字的查询表达式在列等于值方面具有特定谓词。
/* (person) rows where
person = 'Bob'
*/
SELECT * FROM (VALUES ('Bob')) dummy (person)
否则,查询表达式有一个谓词根据其关系运算符从其组成 table 表达式谓词构建。
- Every algebra operator corresponds to a certain logic operator.
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?
"base table"这个词有定义,和你描述的没有任何关系。 "base table" 几乎就是 "table"。也就是说,它不是一个视图,它不是一个 table 值函数,它不是一个查询的结果。它是作为显式 table.
存储在数据库中的内容你所掌握的似乎与优化策略有关。我在优化上下文中使用了类似的术语来描述优化器访问的 "driving table"。这样做的目的是为了区分不同的执行计划。
考虑查询:
from t1 join t2 using (col)
有多个不同的执行计划。以下是一些方法以及它们可能被认为是 "driving table"(如果有的话)的方法:
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"
换句话说,"driving"table与查询结构关系不大。它基于用于查询的优化策略。也就是说,left join
s 和 right join
s 限制了优化路径。因此,在嵌套循环或索引查找情况下,"first"(或"last")table 将是驱动 table.
"driving" table 的概念实际上是关于 DBMS 预期如何在内部执行查询的假设。 基于规则的 查询优化器,在没有任何与索引相关的首选项的情况下,在选择时可能会将 tables 和查询中的连接的顺序视为重要的执行计划。在 cost-based 优化器下,tables 和连接的顺序没有任何意义,因此查询本身的结构不会告诉您哪个 table 首先读取或以什么顺序读取连接条件。
在概念化查询时,在脑海中形成一个 table 作为查询起点的形象可能会有所帮助,但我认为这里问题的答案一定是否定的。照理说开车是没有的table.