sql中的键是不是仍会保留在视图中
Posted
技术标签:
【中文标题】sql中的键是不是仍会保留在视图中【英文标题】:Will a key in sql still stay a key in a viewsql中的键是否仍会保留在视图中 【发布时间】:2011-07-19 03:59:00 【问题描述】:假设我有一个名为 FISH 的 mysql 表,其中包含字段 A、B 和 C。
我运行SELECT * FROM FISH
。这让我对所有领域都有了解。那么,如果 A 是原始表中的键,那么它也是视图中的键吗?意思是,如果我有一个表 FISH2,然后我跑了
SELECT * FROM (SELECT * FROM FISH) D, (SELECT * FROM FISH2) E WHERE D.A = E.A
相关字段仍然是键吗?
现在,让我们更进一步。如果我运行
SELECT * FROM (SELECT CONCAT(A,B) AS DUCK, C FROM FISH) D, (SELECT CONCAT(A,B) AS DUCK2, C FROM FISH2) E WHERE D.DUCK = E.DUCK2
如果 A 和 B 是原始表中的键,那么它们的串联是否也是键?
谢谢:)
【问题讨论】:
【参考方案1】:如果“键”是指“唯一”,是的,笛卡尔积的唯一值元组将是唯一的。 (可以通过归约法来证明这一点。)
【讨论】:
我的意思是运行查询仍然需要很短的时间..我理解的独特部分:) 请注意,尽管字符串连接不保留此属性:考虑集合 1 中的 (A, AF, AFO, AFOO) 和集合 2 中的 (FOOL, OOL, OL, L)。它们的连接笛卡尔积将有几个 AFOOL。【参考方案2】:对于第 1 步,将视图视为子查询,其中包含执行 CREATE VIEW
时 AS
子句中的所有内容。
例如,如果视图v
被创建为SELECT a, b, c FROM t
,那么当你执行...
SELECT * FROM v WHERE a = some_value
...它在概念上被视为...
SELECT * FROM (SELECT a, b, c FROM t) WHERE a = some_value
任何具有良好优化器的数据库都会注意到a
列直接传递到结果中,并且它可以通过将t
中的索引(如果有的话)移动到子查询中来利用它:
SELECT * FROM (SELECT a, b, c FROM t WHERE a = some_value)
这一切都发生在幕后,并不是您需要自己进行的优化。显然,它不能对WHERE
子句中的每个条件都做到这一点,但了解你可以做到的地方是编写优秀优化器的艺术的一部分。
对于第 2 步,连接的键将成为中间结果的一部分,数据库是否决定它们需要索引是一个实现细节。另请注意 fche 关于重复的评论。
如果您的数据库有查询计划解释器,那么运行它并学习解释结果将使您深入了解是什么让您的查询运行得很快,又是什么让它们变慢。
【讨论】:
【参考方案3】:如果A
是fish
中的一个键,那么仅对鱼的任何投影都会产生一个A 仍然唯一的结果集。
表 fish 和任何具有 1:1 关系的表(例如 fish_type)之间的连接将产生一个结果集,其中 A 是唯一的。
与来自鱼的具有 1:M 或 M:M 关系的另一个表(例如 fish_beits)的连接不会产生 A 唯一的结果,除非您在“其他”端提供过滤谓词(例如bait='Dynamite'
)。
SELECT * FROM (SELECT * FROM FISH) D, (SELECT * FROM FISH2) E WHERE D.A = E.A
...在逻辑上等价于下面的语句,大部分数据库(包括MySQL)都会进行转换:
select *
from fish
join fish2 on(fish.a = fish2.a)
A 在结果集中是否仍然唯一取决于 fish2
的键及其关系(见上文)。
串联不会保留唯一性。考虑以下情况:
concat("10", "10") => "1010"
concat("101", "0") => "1010"
因此,您的最终查询...
SELECT *
FROM (SELECT CONCAT(A,B) AS DUCK, C FROM FISH) D
,(SELECT CONCAT(A,B) AS DUCK2, C FROM FISH2) E
WHERE D.DUCK = E.DUCK2
...不会(必然)产生与
相同的结果select *
from fish
join fish2 on(
fish.a = fish2.a
and fish.b = fish2.b
)
我写了必要,因为碰撞取决于实际值。大约前一段时间,我发现了一个错误,其根本原因正是这个。代码在错误出现之前已经运行了几年。
【讨论】:
关于串联 - 也许我的问题是错误的。我不是在寻找唯一性,而是在寻找快速查询,例如在使用索引时(而不是专门的键)。那么,串联之后,索引属性还会存在吗? 不,不会使用索引。如果您在 (a,b) 上创建索引并使用我在上一个示例中使用的形式,则该索引将以您想要的方式使用。以上是关于sql中的键是不是仍会保留在视图中的主要内容,如果未能解决你的问题,请参考以下文章
我是不是必须保留放入 UIKit 应用程序视图中的所有值的副本?
尽管视图初始化,有时仍会显示已删除的项目-Vue,Node.js [重复]