- •Аннотация
- •Содержание
- •Введение
- •Безопасность.
- •Индексы.
- •Руководство пользователя (администратора).
- •1. Описание предметной области
- •2. Проектирование базы данных
- •2.1. Схема базы данных
- •2.2. Концептуальное проектирование
- •2.3. Обоснование нормализации (3нф)
- •3. Создание базы данных
- •4. Создание таблиц и ограничений целостности
- •5. Заполнение таблиц данными
- •6. Объекты промежуточного слоя
- •6.1. Пользовательские функции (udf)
- •6.2. Представления (Views)
- •6.3. Хранимые процедуры и подсистема xml
- •7. Стратегия резервного копирования
- •Часть 4: стратегия резервного копирования
- •8. Безопасность
- •8.1. Уровни аутентификации и авторизации
- •8.2. Ролевая модель разграничения доступа
- •8.3. Тестирование системы безопасности
- •9. Индексы
- •9.1. Кластеризованные индексы
- •9.2. Некластеризованные индексы
- •10. Руководство пользователя (администратора)
- •10.1. Установка и развертывание системы
- •10.2. Сценарии работы с данными
- •Заключение
- •Список используемых источников
- •Приложение а
- •Часть 1: оптимизация (индексы)
- •Часть 2: безопасность (без dbo)
- •Часть 3: ролевая модель (schema permissions)
- •Часть 4: стратегия резервного копирования
6. Объекты промежуточного слоя
Для изоляции физической структуры данных от клиентского приложения и реализации сложной бизнес-логики на стороне сервера был разработан промежуточный программный слой. Он включает в себя пользовательские функции, представления и хранимые процедуры.
6.1. Пользовательские функции (udf)
В соответствии с техническим заданием, в системе реализованы три типа пользовательских функций, различающихся по сложности и назначению:
Скалярная функция (Scalar Function) — [Stock].[udf_FormatValue]
Предназначена для форматирования единиц измерения. Функция принимает числовое значение и строковый код единицы измерения, возвращая единую отформатированную строку. Это позволяет избежать дублирования кода конкатенации в запросах.
Листинг реализации функции приведен ниже:
IF OBJECT_ID('[Stock].[udf_FormatValue]', 'FN') IS NOT NULL DROP FUNCTION [Stock].[udf_FormatValue];
GO
CREATE FUNCTION [Stock].[udf_FormatValue]
(
@Value NVARCHAR(100),
@Unit NVARCHAR(20)
)
RETURNS NVARCHAR(150)
AS
BEGIN
DECLARE @Result NVARCHAR(150);
-- Логика: Если единицы измерения нет, возвращаем просто число
IF @Unit IS NULL OR @Unit = ''
SET @Result = @Value;
ELSE
SET @Result = @Value + ' ' + @Unit;
RETURN @Result;
END
GO
Встроенная табличная функция (Inline Table-Valued Function) — [Stock].[udf_GetComponentParams]
Возвращает набор технических параметров для конкретного компонента. В отличие от представлений, данная функция параметризована (принимает ID компонента), что позволяет получать данные точечно, снижая нагрузку на сервер.
Листинг реализации функции приведен ниже:
IF OBJECT_ID('[Stock].[udf_GetComponentParams]', 'IF') IS NOT NULL DROP FUNCTION [Stock].[udf_GetComponentParams];
GO
CREATE FUNCTION [Stock].[udf_GetComponentParams]
(
@CompID INT
)
RETURNS TABLE
AS
RETURN
(
SELECT
ParamName AS [Parameter],
-- Вызов скалярной функции внутри табличной
[Stock].[udf_FormatValue](ParamValue, Unit) AS [ValueFormatted]
FROM [Stock].[ComponentParams]
WHERE ComponentID = @CompID
);
GO
Многооператорная табличная функция (Multi-Statement Table-Valued Function) — [Stock].[udf_GetComponentQualityReport]
Реализует сложную аналитическую логику. Функция создает в памяти переменную-таблицу, наполняет её первичными данными, а затем выполняет серию операций обновления (UPDATE) для расчета рейтинга качества заполнения данных (Quality Score) по каждому компоненту. Результатом работы функции является готовая таблица с вердиктом о полноте информации.
Листинг реализации функции приведен ниже:
IF OBJECT_ID('[Stock].[udf_GetComponentQualityReport]', 'TF') IS NOT NULL DROP FUNCTION [Stock].[udf_GetComponentQualityReport];
GO
CREATE FUNCTION [Stock].[udf_GetComponentQualityReport]
(
@CategoryID INT -- Фильтр по категории
)
RETURNS @ReportTable TABLE
(
PartNumber NVARCHAR(100),
Manufacturer NVARCHAR(100),
HasDescription BIT,
HasModel BIT,
QualityScore INT, -- Вычисляемый балл (0-100)
Verdict NVARCHAR(50)
)
AS
BEGIN
-- 1. Первичная вставка данных
INSERT INTO @ReportTable (PartNumber, Manufacturer, HasDescription, HasModel, QualityScore, Verdict)
SELECT
c.PartNumber,
m.Name,
CASE WHEN c.Description IS NOT NULL THEN 1 ELSE 0 END,
CASE WHEN EXISTS(SELECT 1 FROM [Stock].[ComponentModels] cm WHERE cm.ComponentID = c.ComponentID) THEN 1 ELSE 0 END,
0, -- Начальный балл
'Unknown'
FROM [Stock].[Components] c
JOIN [Ref].[Manufacturers] m ON c.ManufacturerID = m.ManufacturerID
WHERE c.CategoryID = @CategoryID;
-- 2. Логика расчета баллов (Multi-step logic)
-- +40 баллов, если есть описание
UPDATE @ReportTable SET QualityScore = QualityScore + 40 WHERE HasDescription = 1;
-- +60 баллов, если есть мат. модель
UPDATE @ReportTable SET QualityScore = QualityScore + 60 WHERE HasModel = 1;
-- 3. Вынесение вердикта
UPDATE @ReportTable
SET Verdict = CASE
WHEN QualityScore = 100 THEN 'Excellent'
WHEN QualityScore >= 40 THEN 'Good'
ELSE 'Poor Data'
END;
RETURN;
END
