Представление (T)Sql, содержащее слишком много бизнес-логики
У меня есть представление TSQL. Помимо нескольких столбцов, он довольно прост в том, что он просто делает несколько соединений, а затем склеивает все вместе, чтобы получить хороший вид, каким он должен быть. Однако несколько не столь простых столбцов делают код представления очень сложным, поскольку появились новые требования, которые лишают законной силы логики сложных столбцов.
Не вдаваясь в подробности, в моей базе данных есть таблица:
tblEmployment
Это состоит из рядов "занятий". Каждый раз, когда любой из столбцов подряд, для данной занятости меняется (скажем, employmentTitle
изменения), то текущая строка помещается в другую таблицу tblEmploymentHistory
и строка в tblEmployment
изменен, так что он содержит новейшие employmentTitle
,
По сути, то, что делает вид, это то, что он пытается присоединиться к tblEmployment
на tblEmploymentHistory
с уникальным EmploymentIdentifier
, что имеет смысл.
Более сложный столбец в представлении попытается вычислить число (elapsedTime
для каждой строки), выполняя различные вычисления из строк, которые она объединила (т.е. из tblEmployment and tblEmploymentHistory
). Чтобы получить истекшее время, он выполняет вычисления на основе продиктованной бизнес-логики, например, только конкретные столбцы даты и времени в таблице истории должны учитываться в общем elapsedTime, и это должно происходить только в том случае, если для других столбцов в этой строке заданы определенные значения и т. Д.
Теперь, когда появились новые требования, бизнес-логика стала намного сложнее, чем раньше. Мне трудно расширить представление, чтобы включить это, так как это становится очень грязным, и я чувствую, что это можно сделать гораздо более структурированным на уровне приложений, где также находится остальная часть бизнес-логики!
Правильно ли отменить просмотр и вместо этого переместить его на прикладной уровень моего приложения? Очевидно, что преимущество представления в том, что оно быстрое, и выполнение вычислений в коде для примерно 100000 строк займет некоторое время. Тем не менее, его можно оптимизировать, отфильтровывая строки, чтобы получить число около 10.000.
Каков "стандартный" и самый чистый способ решения этой проблемы?
2 ответа
Ответ зависит от нескольких вещей. Во-первых, убедитесь, что база данных выполняет основанную на множестве работу. Если вы начнете попадать в курсоры (вообще говоря) или в какой-то цикл, вам лучше поместить это в приложение. Реляционные базы данных неэффективно работают таким образом. Я бы также подумал о том, что является стандартным для среды, в которой вы работаете? Поддерживаются ли другие вещи в БД, как это, где вы находитесь? Если это так, вы можете оставаться последовательным.
В конце концов, то, что возвращает эти результаты наиболее эффективно и без влияния на другие запросы, должно быть ответом.
Как и было обещано, я приведу вам пример 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