包含太多业务逻辑的(T)Sql视图

时间:2015-09-09 12:56:00

标签: sql-server tsql sql-view data-layer application-layer

我有一个TSQL视图。除了一些列之外,它非常基本,因为它只需要进行一些连接,然后将所有内容粘合在一起,以呈现应有的美观。但是,由于新的需求已经使复杂列的业务逻辑无效,因此少数几个不那么简单的列使得视图代码很难扩展。

没有太多细节,我的数据库中有一个表:

tblEmployment

这包括“就业”行。每次任何列中的某列,对于给定的职业变化(假设employmentTitle更改),那么当前行将被推送到另一个表中tblEmploymentHistorytblEmployment中的行已更改,因此它包含最新的employmentTitle

基本上,视图的作用是,它尝试将tblEmploymenttblEmploymentHistory加入唯一的EmploymentIdentifier,这是有道理的。

视图中更复杂的列将尝试通过从已连接在一起的行(即来自elapsedTime)进行各种计算来计算数字(每行tblEmployment and tblEmploymentHistory)。为了获得经过的时间,它根据指示的业务逻辑执行计算,例如只有历史记录表中的特定日期时间列应计入总的elapsedTime,并且只有在该行中的其他列设置为特定值等时才应该这样做。

现在新的需求已经出现,业务逻辑比以前复杂得多。我发现很难扩展视图以包含它,因为它变得非常混乱,我觉得这可以在其他业务逻辑所在的应用层中更加结构化!

废弃视图并将其移至应用程序的应用程序层是否“正确”?显然,拥有视图的好处在于它很快,并且在代码中进行大约100.000行的计算将花费一些时间。但是,可以通过过滤行来优化它,使数字大约为10.000。

解决这个问题的“标准”和最简洁的方法是什么?

2 个答案:

答案 0 :(得分:3)

答案取决于一些事情。首先,确保数据库正在进行基于集合的工作。如果你开始进入游标(一般来说)或某种循环,你最好把它放在应用程序中。关系数据库以这种方式工作并不高效。我要考虑的另一件事是你所处理的环境的标准是什么?在这样的数据库中是否保留了其他内容?如果是这样,您可能希望保持一致。

最终无论如何最有效地返回这些结果,而不影响其他查询,应该是答案。

答案 1 :(得分:1)

正如所承诺的那样,我将举例说明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