Добавил:
hiiamfool
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:курсач / 05_SecurityAndAdmin
.sql /* =================================================================================
СКРИПТ 05: БЕЗОПАСНОСТЬ, ОПТИМИЗАЦИЯ И ОБСЛУЖИВАНИЕ
Схемы: [Stock], [Ref]
================================================================================= */
USE CircuitDB;
GO
PRINT '=============================================================';
PRINT 'Настройка безопасности и оптимизации...';
PRINT 'Время запуска: ' + CONVERT(VARCHAR(30), GETDATE(), 120);
PRINT '=============================================================';
GO
/* =============================================
ЧАСТЬ 1: ОПТИМИЗАЦИЯ (ИНДЕКСЫ)
Анализ плана выполнения запросов показал необходимость
следующих индексов для ускорения JOIN и WHERE.
============================================= */
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)
Создание Логинов (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')
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)
Используем права на уровне СХЕМ, а не таблиц.
============================================= */
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;
-- Инженер также должен видеть отчеты
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';
-- Выполняем бэкап
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
СКРИПТ 05: БЕЗОПАСНОСТЬ, ОПТИМИЗАЦИЯ И ОБСЛУЖИВАНИЕ
Схемы: [Stock], [Ref]
================================================================================= */
USE CircuitDB;
GO
PRINT '=============================================================';
PRINT 'Настройка безопасности и оптимизации...';
PRINT 'Время запуска: ' + CONVERT(VARCHAR(30), GETDATE(), 120);
PRINT '=============================================================';
GO
/* =============================================
ЧАСТЬ 1: ОПТИМИЗАЦИЯ (ИНДЕКСЫ)
Анализ плана выполнения запросов показал необходимость
следующих индексов для ускорения JOIN и WHERE.
============================================= */
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)
Создание Логинов (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')
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)
Используем права на уровне СХЕМ, а не таблиц.
============================================= */
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;
-- Инженер также должен видеть отчеты
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';
-- Выполняем бэкап
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
Соседние файлы в папке курсач
