我有一个TSQL视图。除了一些列之外,它非常基本,因为它只是进行一些连接,然后将所有内容粘合在一起,以呈现应有的漂亮视图。然而,少数不那么简单的列使得视图代码很难扩展,现在出现了新的需求,使复杂列的业务逻辑无效。
在我的数据库中有一个表:tblEmployment
由"employments"行组成。每次一行中的任何列,对于给定的就业变化(假设employmentTitle
变化),则当前行被推入另一个表tblEmploymentHistory
,并且tblEmployment
中的行被更改,因此它包含最新的employmentTitle
。
实际上,视图所做的是,它试图将tblEmploymentHistory
上的tblEmployment
与唯一的EmploymentIdentifier
连接起来,这是有意义的。
视图中更复杂的列将尝试通过从它连接在一起的行(即从tblEmployment and tblEmploymentHistory
)进行各种计算来计算一个数字(每行elapsedTime
)。为了获得经过的时间,它根据指定的业务逻辑执行计算,例如,只有历史表中的特定datetime列应该计入总elapsedTime,并且只有当该行中的其他列被设置为特定值时,它才应该这样做。
既然有了新的需求,业务逻辑就比以前复杂得多。我发现很难扩展视图来包含这个,因为它变得非常混乱,我觉得这可以在应用程序层中更结构化地完成,其余的业务逻辑也驻留在应用程序层中!
废弃视图并将其移动到应用程序的应用层是"正确的"吗?显然,使用该视图的好处是速度快,并且在代码中对大约100,000行进行计算将花费一些时间。然而,它可以通过过滤掉行来优化,使数字在10,000左右。
解决这个问题的"标准"和最干净的方法是什么?
答案取决于几件事。首先,确保数据库正在执行基于集合的工作。如果开始使用游标(一般来说)或某种循环,最好将其放在应用程序中。关系数据库以这种方式工作效率不高。我要考虑的另一件事是,你工作的环境的标准是什么?你所在的数据库中还有像这样维护的东西吗?如果是这样,你可能想要保持一致。
最后,在不影响其他查询的情况下,最有效地返回这些结果的应该是答案。
按照约定,我将给出udf方法的一个示例:在我的一个项目中,我将它与40多个不同的分层结构udf一起使用,以获得包含近1000列的结果集。
CREATE TABLE dbo.TestTable(Col1 INT,Col2 INT,Col3 INT);
INSERT INTO dbo.TestTable VALUES(1,2,3),(4,5,6),(7,8,9);
GO
CREATE FUNCTION dbo.TestFunc(@Prm1 INT,@Prm2 INT)
RETURNS TABLE
AS
RETURN
SELECT @Prm1 AS Func_Prm1 --use names, which will be unique in any usage, this makes things much easier!
,@Prm2 AS Func_Prm2
,@Prm1 * @Prm2 AS Func_Calculated;
GO
--This would be your simple VIEW, consisting of any columns you can easily get
SELECT *
FROM dbo.TestTable
--This is how you join the "buiness logic" to your view
CROSS APPLY dbo.TestFunc(TestTable.Col1,TestTable.Col2) AS func
DROP TABLE dbo.TestTable;
GO
DROP FUNCTION dbo.TestFunc;
GO