以下摘自一本关于数据库设计的书(Beginning Database Design ISBN:0-7645-7490-6):
使用视图的危险在于根据视图过滤查询,期望读取非常大的表的非常小的部分。任何过滤都应该在视图中完成,因为在视图中的查询完成执行之后,才会应用针对视图本身的任何过滤。视图通常对加快开发过程很有用,但从长远来看,它会完全扼杀数据库性能。
以下是 PostgreSQL 9.5 文档的摘录:
充分利用视图是良好 SQL 数据库设计的一个关键方面。视图允许您封装表结构的细节,这些细节可能会随着应用程序的发展而改变,并隐藏在一致的接口后面。
这两个来源似乎相互矛盾(“不要用视图设计”与“用视图设计”)。
但是,在 PG 中,视图是使用规则系统实现的。因此,可能(这是我的问题)针对视图的任何过滤都被重写为视图中的过滤器,从而导致对基础表执行单个查询。
我的解释是否正确并且 PG 将 WHERE 子句组合进和出视图?还是单独运行它们,一个接一个?任何简短的、自包含的、正确的(可编译的)示例?
从多个连接创建表以用于分析时,何时首选使用视图而不是创建新表?
我更喜欢使用视图的一个原因是我们的管理员在 Ruby 中开发了数据库模式,而我对 Ruby 并不熟悉。我可以请求创建表,但需要一个额外的步骤,我希望在开发/测试新连接时有更大的灵活性。
我开始使用关于 SO 相关问题的答案的视图(何时使用 R,何时使用 SQL)。得票最多的答案开始于“在 SQL 中进行数据操作,直到数据位于单个表中,然后在 R 中进行其余的操作”。
我已经开始使用视图,但我遇到了一些视图问题:
视图是否适合这种用途?如果是这样,我应该期待性能损失吗?有没有办法加快对视图的查询?
我是 Oracle 数据库的新手。如果我理解正确的话,物化视图是将结果集保存为数据库中的物理表的视图,并且该视图/表根据某个参数进行刷新。如果视图保存为物理表,为什么不首先将数据存储到表中?那么使用物化视图代替表有什么好处呢?
如何在 PostgreSQL 中使用 SQL 命令列出数据库的所有视图?
我想要类似于 psql\dv命令的输出的东西,但最好只是一个视图名称列表。例如,
SELECT ...;
my_view_1
my_view_2
my_view_3
Run Code Online (Sandbox Code Playgroud)
我在 Ubuntu Linux 上运行 PostgreSQL v9.1.4。
我很久以前在某个地方读过。这本书指出我们不应该允许在 SQL Server 中使用嵌套视图。我不确定我们不能这样做的原因,或者我可能记得不正确的陈述。
学生们
SELECT studentID, first_name, last_name, SchoolID, ... FROM students
CREATE VIEW vw_eligible_student
AS
SELECT * FROM students
WHERE enroll_this_year = 1
Run Code Online (Sandbox Code Playgroud)
老师
SELECT TeacherID, first_name, last_name, SchoolID, ... FROM teachers
CREATE VIEW vw_eligible_teacher
AS
SELECT * FROM teachers
WHERE HasCert = 1 AND enroll_this_year = 1
Run Code Online (Sandbox Code Playgroud)
学校
CREATE VIEW vw_eligible_school
AS
SELECT TOP 100 PERCENT SchoolID, school_name
FROM schools sh
JOIN
vw_eligible_student s
ON s.SchoolID = sh.SchoolID
JOIN
vw_eligible_teacher t
ON s.SchoolID = t.SchoolID
Run Code Online (Sandbox Code Playgroud)
在我的工作场所,我调查了我们的一个内部数据库应用程序。我检查了对象,发现有两到三层的视图相互堆叠。所以这让我想起了我过去读过的东西。有人可以帮忙解释一下吗?
如果这样做不行,我想知道它仅限于 …
如果您在视图内部或外部过滤视图会有所不同吗?
例如,这两个查询之间有什么区别吗?
SELECT Id
FROM MyTable
WHERE SomeColumn = 1
Run Code Online (Sandbox Code Playgroud)
或者
SELECT Id
FROM MyView
WHERE SomeColumn = 1
Run Code Online (Sandbox Code Playgroud)
并且MyView定义为
SELECT Id, SomeColumn
FROM MyTable
Run Code Online (Sandbox Code Playgroud)
如果源表位于链接服务器上,答案有什么不同吗?
我问是因为我必须从链接服务器两次查询一个大表(4400 万行),并获得结果的汇总。我想知道是否应该创建两个视图来访问数据,每个查询一个视图,或者我是否可以使用单个视图和一个WHERE子句。
performance sql-server-2005 sql-server view query-performance
以下面的例子为例:
SELECT <CalculationA> As ColA,
<CalculationB> As ColB,
<CalculationA> + <CalculationB> As ColC
FROM TableA
Run Code Online (Sandbox Code Playgroud)
CalculationA 和CalculationB 会分别计算两次吗?
或者优化器是否足够聪明来计算一次并使用结果两次?
我想进行测试以查看自己的结果,但是,我不确定如何检查这样的事情。
我的假设是它会执行两次计算。
在哪种情况下,根据所涉及的计算,使用派生表或嵌套视图会更好吗?考虑以下:
SELECT TableB.ColA,
TableB.ColB,
TableB.ColA + TableB.ColB AS ColC,
FROM(
SELECT <CalculationA> As ColA,
<CalculationB> As ColB
FROM TableA
) As TableB
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我希望计算只执行一次?
请问有人可以证实或反驳我的假设吗?或者指导我如何为自己测试这样的东西?
谢谢。
我在更新后备份我的数据库时遇到问题。我一直在我的系统上四处寻找,试图找出原因。我运行的一个查询返回了这个结果。
Got error: 1449: The user specified as a definer ('cittool'@'%') does not exist when using LOCK TABLES
Run Code Online (Sandbox Code Playgroud)
经过一些调查,这些视图的定义者似乎是一个已从系统中清除的旧开发者帐户。有这个问题的数据库和视图很少使用,并且大多数被保留用于存档目的。
大约有 40 个视图带有不再存在的定义器。有没有一种简单的方法可以一次性将定义者更改为不同的帐户?有没有办法让 mysqldump 简单地将所有视图转储到一个文件中,以便我可以编辑该文件并重新创建视图?
我有一个物化视图Postgres 9.3,我想用新列进行更新。但是,其他物化视图也依赖于该视图,并且错误消息表明当其他对象依赖于该视图时,无法删除该视图。
错误:无法删除物化视图 latest_charges 因为其他对象依赖它
从文档中还可以看出 REPLACE 关键字对物化视图无效。除了删除所有依赖对象并重建每个对象之外,还有其他捷径吗?
我正在使用 MySQL 5.6。我无法像在 Oracle 中那样创建物化视图。我见过一两个像 Flexview 这样的解决方案。
谁能告诉我在 MySQL 中创建物化视图的最佳方法(如 Oracle 中的自动刷新),并且复杂性最低?
view ×10
mysql ×3
performance ×3
postgresql ×3
sql-server ×3
optimization ×2
mysql-5.6 ×1
oracle ×1