Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

курсач / Наволоцкий_1302_v2

.pdf
Скачиваний:
0
Добавлен:
27.12.2025
Размер:
2.69 Mб
Скачать

05_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

Соседние файлы в папке курсач