今天早些时候,我意识到我犯了一个非常愚蠢的错误。我没有编写视图,而是编写了无参数内联表值函数。这让我思考:除了界面之外,两者之间有什么区别吗?据我所知,它们在逻辑上是相同的并且执行相同。
那么,换句话来说,视图提供了哪些无参数内联表值函数所没有的功能呢?我想到的都是索引视图,但我从未见过有人真正使用它们。
今天早些时候,我意识到我犯了一个非常愚蠢的错误。我没有编写视图,而是编写了无参数内联表值函数。这让我思考:除了界面之外,两者之间有什么区别吗?据我所知,它们在逻辑上是相同的并且执行相同。
那么,换句话来说,视图提供了哪些无参数内联表值函数所没有的功能呢?我想到的都是索引视图,但我从未见过有人真正使用它们。
视图和内联 TVF 都是可更新的,并且几乎在任何地方都可以互换使用。
特别是对于 SQL Server,视图支持以下功能,但内联 TVF 不可用:
WITH CHECK OPTION
,一个很少使用的选项,用于防止更新可更新视图中的行,这将导致该行被排除在视图之外。TVF 仍然可以使用此类视图(甚至是隐式的),但您无法直接为 TVF 建立索引。
bcp.exe
如果没有实际查询,则无法从 TVF 进行查询SELECT
。SELECT
查询,并且修改可能不起作用。sp_describe_first_result_set
)可以更好地理解列定义。TVF 显然可以使用参数,而视图则不能。这通常可以使其比类似视图更加高效,例如将谓词推入窗口函数时。它们也可以
APPLY
逐行进行,而不是使用连接,这可以使它们更加灵活。您应该使用其中一种而不是另一种吗?我认为无参数 TVF 没有多大意义。您无法对其建立索引,因此如果您想这样做,则需要重复该代码。使用视图也更惯用,并且它们对用户来说更明显。某些 IDE 中的智能感知也不能很好地与函数配合使用。
不要使用多语句 TVF 或标量 UDF,除非绝对无法避免,因为两者通常都是主要的性能问题。
背景
主流SQL数据库引擎的概念经过几十年的逐步演变,以满足当时最突出的需求,并且也出现了许多定义基本功能的工业标准,这些标准一旦制定就很难修改。
结果是理解设计的基本原理并不总是那么容易。
据我所知,“视图”的概念从 SQL 历史的早期就存在,可能从一开始就存在 - 不管怎样,它肯定是最古老的概念之一。同时,表值函数(可以提供参数)是 SQL 中较晚才添加的,我不确定它的标准程度如何。
意见
视图执行许多功能。
其中主要的一个是为表提供一个间接层,以便可以更轻松地调整底层存储模式,而不会破坏现有代码。从语法上讲,SQL 不区分对视图的引用和对表的引用,并且视图(在某些约束下)可以作为插入、更新或删除的目标,就像表一样。
视图的另一个目的是充当与基础表不同的安全对象,以便可以提供过滤或汇总的数据,并独立于基表控制对数据的访问。
一些引擎还提供“索引”或“物化”视图,其中查询结果由引擎与调用结果的场合分开准备和存储,并且可以由分析的数据库引擎保持最新。结果的沿袭,并通过自动更新存储的结果来响应原始数据的变化。
我认为视图最初设计的目的并不是为了 SQL 代码模块化,纯粹是为了方便程序员。SQL 语言曾经在功能上比现在在大多数引擎中受到的限制要大得多,托管数据库引擎的机器的性能也是如此,并且 SQL 代码中通常不会有太多的内在复杂性。一个视图本身。然而如今,视图可能会像这样被压缩到服务中,封装一段对于许多查询来说很常见的 SQL 代码,并且复杂到使得复制变得不合理。
表值函数
表值函数的目的仅仅是取出数据,而这并不是视图的唯一目的,视图也可以容纳数据输入。
在我最熟悉的SQL Server中,也有“内联”函数和“多语句”函数的区别。
只有内联和无参数函数的情况才与视图非常相似。多语句函数比视图更类似于存储过程,但与过程不同的是,它可以以与表或视图类似的方式参与查询。
(编辑:根据 @Charlieface 的评论,并且作为关于“获取数据”这一点的限定,尽管这一点对于多语句函数来说是正确的,但似乎内联 TVF 实际上可以像视图一样“可更新”是。)
为什么重叠?
您已经可以看到,视图实现的主要目的与参数化函数的主要目的并不完全一致,即使在退化的无参数情况下也是如此。
我立即不确定是否存在内联和无参数函数不能与视图完全互换的情况。我怀疑这种重叠的情况纯粹是为了“功能”概念的完整性而被允许的,并且因为它自然出现而无需额外的复杂性或实现工作。
然而,多语句函数可以实现视图显然无法实现的功能(或者至少,如果没有相对较长、乱码和性能不佳的代码,可能无法实现,并且如果没有 SQL 语言的许多最新功能,也可能无法实现)
概括
综上所述,视图和函数在 SQL 的演变过程中出现于不同的时期,并且主要覆盖不同的目的。存在的少量重叠并不意味着其中一方完全包含另一方的所有目的。
本质区别在于,视图代表整个表,并具有许多类似表的品质(包括与表的语法等效、读/写功能以及分配触发器的能力),而函数代表可重用元素仅用于选择查询。
一般来说,我会出于许多不同的目的合理使用视图,但我很少使用函数(因为它们在 SQL 中是比其他编程语言中的“函数”或方法更重要的概念)。