курсач / Наволоцкий_1302_v2
.pdf05_SecurityAndAdmin.sql
/*
============================================================
=====================
СКРИПТ 05: БЕЗОПАСНОСТЬ, ОПТИМИЗАЦИЯ И ОБСЛУЖИВАНИЕ Схемы: [Stock], [Ref]
============================================================
===================== */
USE CircuitDB;
GO
PRINT '=========================================================== ==';
PRINT 'Настройка безопасности и оптимизации...';
PRINT 'Время запуска: ' + CONVERT(VARCHAR(30), GETDATE(), 120);
PRINT '=========================================================== ==';
GO
/* =============================================
ЧАСТЬ 1: ОПТИМИЗАЦИЯ (ИНДЕКСЫ)
Анализ плана выполнения запросов показал необходимость следующих индексов для ускорения JOIN и WHERE.
============================================= */
101
PRINT 'Создание индексов... ' + CONVERT(VARCHAR(30),
GETDATE(), 120);
GO
--1. Уникальный индекс для Артикула
--Обоснование: Часто используется в WHERE PartNumber = ...
и для проверки дубликатов.
-- Тип: UNIQUE NONCLUSTERED
IF NOT EXISTS (SELECT name FROM sys.indexes WHERE name = 'IX_Components_PartNumber')
CREATE UNIQUE NONCLUSTERED INDEX [IX_Components_PartNumber]
ON [Stock].[Components](PartNumber);
GO
--2. Покрывающий индекс (Covering Index) для Производителя
--Обоснование: Часто используется JOIN по ManufacturerID.
--INCLUDE позволяет получить IsActive без обращения к основной таблице (Key Lookup).
IF NOT EXISTS (SELECT name FROM sys.indexes WHERE name = 'IX_Components_ManufacturerID_Includes')
CREATE NONCLUSTERED INDEX [IX_Components_ManufacturerID_Includes] ON [Stock].[Components](ManufacturerID) INCLUDE (IsActive, CategoryID);
GO
/* =============================================
ЧАСТЬ 2: БЕЗОПАСНОСТЬ (БЕЗ DBO)
102
Создание Логинов (Server Level) и Пользователей (DB
Level)
Пароль: 123
Логика: Удаляем старых (если есть) -> Создаем новых
============================================= */
PRINT 'Настройка пользователей... ' + CONVERT(VARCHAR(30), GETDATE(), 120);
GO
-- 1. Сначала удаляем Пользователей в БД, чтобы освободить Логины
USE CircuitDB;
GO
IF EXISTS (SELECT name FROM sys.database_principals WHERE name = 'Manager')
DROP USER Manager;
IF EXISTS (SELECT name FROM sys.database_principals WHERE name = 'Engineer')
DROP USER Engineer;
GO
-- 2. Переключаемся в master и пересоздаем Логины
USE master;
GO
-- Удаляем старые логины, если они есть
IF EXISTS (SELECT name FROM sys.server_principals WHERE name = 'User_Manager')
103
DROP LOGIN User_Manager;
IF EXISTS (SELECT name FROM sys.server_principals WHERE name = 'User_Engineer')
DROP LOGIN User_Engineer;
GO
--Создаем заново с простым паролем '123'
--CHECK_POLICY = OFF позволяет использовать короткие пароли
(отключает проверку Windows)
CREATE LOGIN User_Manager WITH PASSWORD = '123',
CHECK_POLICY = OFF;
CREATE LOGIN User_Engineer WITH PASSWORD = '123',
CHECK_POLICY = OFF;
GO
-- 3. Возвращаемся в базу и создаем Пользователей
USE CircuitDB;
GO
CREATE USER Manager FOR LOGIN User_Manager;
CREATE USER Engineer FOR LOGIN User_Engineer;
GO
/* =============================================
ЧАСТЬ 3: РОЛЕВАЯ МОДЕЛЬ (SCHEMA PERMISSIONS)
Используем права на уровне СХЕМ, а не таблиц.
============================================= */
104
PRINT 'Настройка прав доступа на СХЕМЫ... ' + CONVERT(VARCHAR(30), GETDATE(), 120);
GO
-- 3.1. Роль "Менеджер" (Только чтение отчетов)
IF NOT EXISTS (SELECT name FROM sys.database_principals WHERE name = 'Role_SeeReports')
CREATE ROLE Role_SeeReports;
--Даем права: Менеджер может читать ВСЁ в схеме Stock (там лежат Views)
GRANT SELECT ON SCHEMA::[Stock] TO Role_SeeReports;
--И читать справочники
GRANT SELECT ON SCHEMA::[Ref] TO Role_SeeReports;
-- Добавляем пользователя
ALTER ROLE Role_SeeReports ADD MEMBER Manager;
-- 3.2. Роль "Инженер" (Выполнение процедур)
IF NOT EXISTS (SELECT name FROM sys.database_principals WHERE name = 'Role_ComponentEditor')
CREATE ROLE Role_ComponentEditor;
--Даем права: Выполнение любых процедур в схеме Stock GRANT EXECUTE ON SCHEMA::[Stock] TO Role_ComponentEditor;
--Чтение справочников (нужно для работы процедур поиска)
GRANT SELECT ON SCHEMA::[Ref] TO Role_ComponentEditor;
105
-- Инженер также должен видеть отчеты
ALTER ROLE Role_SeeReports ADD MEMBER Engineer;
ALTER ROLE Role_ComponentEditor ADD MEMBER Engineer;
GO
/* =============================================
ЧАСТЬ 4: СТРАТЕГИЯ РЕЗЕРВНОГО КОПИРОВАНИЯ Скрипт создает бэкап с ДАТОЙ в имени файла.
============================================= */ PRINT 'Выполнение резервного копирования... ' + CONVERT(VARCHAR(30), GETDATE(), 120);
GO
DECLARE @BackupName NVARCHAR(255);
DECLARE @BackupFile NVARCHAR(255);
DECLARE @CurrentDate NVARCHAR(20);
--Формируем строку даты вручную для SQL 2012 (YYYYMMDD_HHmm)
SET @CurrentDate = CONVERT(VARCHAR(8), GETDATE(), 112) + '_' + REPLACE(CONVERT(VARCHAR(5), GETDATE(), 108), ':', '');
--Путь к папке Backup (Стандартный для SQL Express)
SET @BackupFile = N'C:\Program Files (x86)\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\Backup\CircuitDB_' + @CurrentDate + '.bak';
SET @BackupName = N'CircuitDB-Full Database Backup';
-- Выполняем бэкап
106
BACKUP DATABASE [CircuitDB]
TO DISK = @BackupFile
WITH NOFORMAT, NOINIT,
NAME = @BackupName,
SKIP, NOREWIND, NOUNLOAD, STATS = 10;
PRINT 'Бэкап сохранен в: ' + @BackupFile;
GO
PRINT '=========================================================== ==';
PRINT 'Скрипт 05 выполнен успешно. Настройка завершена.'; PRINT 'Время завершения: ' + CONVERT(VARCHAR(30), GETDATE(), 120);
PRINT '=========================================================== ==';
GO
107
Demo_Presentation.sql
/*
============================================================
=====================
ДЕМОНСТРАЦИЯ ВОЗМОЖНОСТЕЙ СИСТЕМЫ (DEMO)
============================================================
===================== */
USE CircuitDB;
GO
PRINT '=========================================================== ==';
PRINT 'ЗАПУСК ДЕМОНСТРАЦИИ';
PRINT 'Время: ' + CONVERT(VARCHAR(30), GETDATE(), 120); PRINT '=========================================================== ==';
GO
/*
============================================================
======
ЭТАП 1: СЛОЖНЫЕ ПРЕДСТАВЛЕНИЯ (VIEWS)
Демонстрация аналитики, CTE, Group By и Having
108
============================================================
====== */
PRINT '--- ЭТАП 1: ПРОСМОТР ОТЧЕТОВ ---';
USE CircuitDB;
GO
--1.1. Полный отчет (INNER JOIN 4 таблиц)
--Добавляем GETDATE(), чтобы видеть время генерации прямо в таблице
SELECT TOP 5
*,
GETDATE() AS [ReportTime]
FROM [Stock].[v_FullComponentReport];
--1.2. Инженерный отчет (Фильтр по SPICE моделям) SELECT
*,
GETDATE() AS [ReportTime]
FROM [Stock].[v_ActiveComponentsSpiceready];
--1.3. СЛОЖНАЯ АНАЛИТИКА (CTE + HAVING)
--Показывает процент активных компонентов по категориям
SELECT
*,
GETDATE() AS [ReportTime]
FROM [Stock].[v_CategoryAnalytics];
GO
109
/*
============================================================
======
ЭТАП 2: ПОИСК И ДИНАМИЧЕСКИЕ ДАННЫЕ Демонстрация генерации даты "на лету" и работы индексов
============================================================
====== */
USE CircuitDB;
GO
PRINT '--- ЭТАП 2: ПОИСК ДАННЫХ ---';
-- 2.1. Поиск по части названия (Артикулу)
EXEC [Stock].[usp_SearchComponents] @Keyword = '555';
-- 2.2. Поиск по производителю (Используем ID из справочника
Ref)
-- (Например, Texas Instruments = 1)
EXEC [Stock].[usp_SearchComponents] @ManufacturerID = 1;
GO
/*
============================================================
======
ЭТАП 3: СОЗДАНИЕ ДАННЫХ (ТРАНЗАКЦИИ)
Демонстрация вставки с проверкой (TRY...CATCH)
110
