Microsoft SQL Server

Microsoft製のエンタープライズデータベース管理システム。Windows環境との深い統合、BI機能、クラウド連携が特徴。SQL Server 2025でベクターデータベース機能追加。

データベースRDBMSエンタープライズSQLT-SQLWindows商用データベース

データベースサーバー

Microsoft SQL Server

概要

Microsoft SQL Serverは、マイクロソフトが開発・提供する企業向けリレーショナルデータベース管理システム(RDBMS)です。Windowsプラットフォームを中心に、Linux環境でも動作する高性能なデータベースソリューションとして、世界中の企業で広く採用されています。1989年に初版がリリースされて以来、継続的な機能強化が行われ、現在では高可用性、ビジネスインテリジェンス、機械学習機能まで統合した包括的なデータプラットフォームへと進化しています。

詳細

SQL Serverは、エンタープライズレベルのデータ管理要件に対応する包括的なデータベースプラットフォームです。標準SQLに加えて、独自拡張のT-SQL(Transact-SQL)を提供し、ストアドプロシージャ、トリガー、ユーザー定義関数などの高度なプログラミング機能をサポートしています。

主要な特徴として、Always On可用性グループによる高可用性とディザスタリカバリ、クエリストアによる自動パフォーマンスチューニング、列ストアインデックスによる分析クエリの高速化、In-Memory OLTPによるトランザクション処理の高速化などがあります。

SQL Serverは複数のエディションを提供しており、Express(無料版)、Standard、Enterprise、Developerエディションがあります。Enterpriseエディションでは、最大8つのセカンダリレプリカをサポートするAlways On可用性グループ、自動チューニング、高度な暗号化機能など、ミッションクリティカルなワークロードに必要な機能を提供します。

近年では、Azure SQL DatabaseやAzure SQL Managed Instanceとして、クラウドネイティブなマネージドサービスも提供され、オンプレミスとクラウドのハイブリッド展開が可能です。また、SQL Server 2017以降ではLinuxサポートが追加され、Docker コンテナでの実行も可能になりました。

メリット・デメリット

メリット

  • Windowsとの高い統合性: Active Directory、.NET Framework、PowerShellとのシームレスな統合
  • 包括的なツールセット: SQL Server Management Studio(SSMS)、SQL Server Data Tools(SSDT)など充実した管理・開発ツール
  • 優れたパフォーマンス: クエリストア、自動チューニング、列ストアインデックス、In-Memory OLTPによる高速処理
  • 高可用性ソリューション: Always On可用性グループ、フェールオーバークラスタリング、データベースミラーリング
  • 統合されたBI機能: SQL Server Reporting Services(SSRS)、SQL Server Analysis Services(SSAS)、SQL Server Integration Services(SSIS)
  • セキュリティ機能: 透過的データ暗号化(TDE)、Always Encrypted、行レベルセキュリティ、動的データマスキング
  • クロスプラットフォーム: Windows、Linux、Docker環境での実行をサポート
  • Azureとの統合: Azure SQL Database、Azure Synapse Analyticsとのシームレスな連携

デメリット

  • ライセンスコスト: Enterprise版は高額で、コア単位のライセンスモデルが複雑
  • リソース消費: 大量のメモリとCPUを必要とし、適切なサイジングが重要
  • Windows中心の設計: Linux版は機能制限があり、一部の機能はWindows版でのみ利用可能
  • 複雑な管理: 高度な機能を活用するには専門的な知識と経験が必要
  • アップグレードの複雑さ: メジャーバージョンアップグレードには慎重な計画と検証が必要
  • ベンダーロックイン: T-SQL固有の機能への依存により、他のデータベースへの移行が困難
  • サイズ制限: Express版には10GBのデータベースサイズ制限がある

参考ページ

書き方の例

基本的な接続とクエリ

-- SQL Server Management Studio または sqlcmd での接続
-- 統合認証
sqlcmd -S localhost\SQLEXPRESS -E
-- SQL Server認証
sqlcmd -S localhost\SQLEXPRESS -U sa -P password

-- 基本的なSELECT文
SELECT 
    ProductID,
    Name,
    ProductNumber,
    StandardCost,
    ListPrice,
    ListPrice - StandardCost AS Profit
FROM Production.Product
WHERE ListPrice > 0
ORDER BY Profit DESC;

-- テーブルの作成
CREATE TABLE Sales.Customer (
    CustomerID INT IDENTITY(1,1) PRIMARY KEY,
    FirstName NVARCHAR(50) NOT NULL,
    LastName NVARCHAR(50) NOT NULL,
    Email NVARCHAR(100) UNIQUE,
    CreatedDate DATETIME2 DEFAULT SYSDATETIME(),
    ModifiedDate DATETIME2 DEFAULT SYSDATETIME()
);

T-SQLストアドプロシージャ

-- ストアドプロシージャの作成
CREATE OR ALTER PROCEDURE Sales.usp_GetCustomerOrders
    @CustomerID INT,
    @StartDate DATE = NULL,
    @EndDate DATE = NULL
AS
BEGIN
    SET NOCOUNT ON;
    
    -- パラメータのデフォルト値設定
    IF @StartDate IS NULL
        SET @StartDate = DATEADD(YEAR, -1, GETDATE());
    
    IF @EndDate IS NULL
        SET @EndDate = GETDATE();
    
    -- エラーハンドリングを含むクエリ
    BEGIN TRY
        SELECT 
            o.OrderID,
            o.OrderDate,
            o.TotalAmount,
            od.ProductID,
            p.Name AS ProductName,
            od.Quantity,
            od.UnitPrice
        FROM Sales.Orders o
        INNER JOIN Sales.OrderDetails od ON o.OrderID = od.OrderID
        INNER JOIN Production.Product p ON od.ProductID = p.ProductID
        WHERE o.CustomerID = @CustomerID
            AND o.OrderDate BETWEEN @StartDate AND @EndDate
        ORDER BY o.OrderDate DESC;
        
        -- 注文サマリーも返す
        SELECT 
            COUNT(DISTINCT OrderID) AS TotalOrders,
            SUM(TotalAmount) AS TotalSpent,
            AVG(TotalAmount) AS AverageOrderValue
        FROM Sales.Orders
        WHERE CustomerID = @CustomerID
            AND OrderDate BETWEEN @StartDate AND @EndDate;
            
    END TRY
    BEGIN CATCH
        -- エラー情報を取得
        SELECT 
            ERROR_NUMBER() AS ErrorNumber,
            ERROR_MESSAGE() AS ErrorMessage,
            ERROR_LINE() AS ErrorLine,
            ERROR_PROCEDURE() AS ErrorProcedure;
        
        -- エラーを再発生
        THROW;
    END CATCH
END;
GO

-- ストアドプロシージャの実行
EXEC Sales.usp_GetCustomerOrders 
    @CustomerID = 123,
    @StartDate = '2024-01-01',
    @EndDate = '2024-12-31';

Always On可用性グループ

-- 可用性グループの作成(プライマリレプリカで実行)
CREATE AVAILABILITY GROUP [AG_Production]
WITH (
    AUTOMATED_BACKUP_PREFERENCE = SECONDARY,
    DB_FAILOVER = ON,
    DTC_SUPPORT = PER_DB
)
FOR DATABASE [AdventureWorks], [Sales]
REPLICA ON 
    N'SQL-SERVER-01' WITH (
        ENDPOINT_URL = N'TCP://SQL-SERVER-01.domain.com:5022',
        AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
        FAILOVER_MODE = AUTOMATIC,
        BACKUP_PRIORITY = 50,
        SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY,
                      READ_ONLY_ROUTING_URL = N'TCP://SQL-SERVER-01.domain.com:1433')
    ),
    N'SQL-SERVER-02' WITH (
        ENDPOINT_URL = N'TCP://SQL-SERVER-02.domain.com:5022',
        AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
        FAILOVER_MODE = AUTOMATIC,
        BACKUP_PRIORITY = 50,
        SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY,
                      READ_ONLY_ROUTING_URL = N'TCP://SQL-SERVER-02.domain.com:1433')
    );

-- リスナーの作成
ALTER AVAILABILITY GROUP [AG_Production]
ADD LISTENER N'AG-LISTENER' (
    WITH IP ((N'192.168.1.100', N'255.255.255.0')),
    PORT = 1433
);

-- 読み取り専用ルーティングの設定
ALTER AVAILABILITY GROUP [AG_Production]
MODIFY REPLICA ON N'SQL-SERVER-01'
WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('SQL-SERVER-02','SQL-SERVER-01')));

パフォーマンスチューニング

-- クエリストアの有効化
ALTER DATABASE [AdventureWorks] 
SET QUERY_STORE = ON (
    OPERATION_MODE = READ_WRITE,
    CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 30),
    DATA_FLUSH_INTERVAL_SECONDS = 900,
    MAX_STORAGE_SIZE_MB = 1000,
    INTERVAL_LENGTH_MINUTES = 60,
    SIZE_BASED_CLEANUP_MODE = AUTO,
    QUERY_CAPTURE_MODE = AUTO,
    MAX_PLANS_PER_QUERY = 200
);

-- 実行プランの分析
SET STATISTICS IO ON;
SET STATISTICS TIME ON;

SELECT c.CustomerID, c.FirstName, c.LastName,
       COUNT(o.OrderID) AS OrderCount,
       SUM(o.TotalAmount) AS TotalSpent
FROM Sales.Customer c
LEFT JOIN Sales.Orders o ON c.CustomerID = o.CustomerID
WHERE o.OrderDate >= DATEADD(MONTH, -6, GETDATE())
GROUP BY c.CustomerID, c.FirstName, c.LastName
HAVING COUNT(o.OrderID) > 5
ORDER BY TotalSpent DESC;

-- 列ストアインデックスの作成
CREATE CLUSTERED COLUMNSTORE INDEX CCI_FactSales
ON Sales.FactSales
WITH (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0);

-- 自動チューニングの有効化
ALTER DATABASE [AdventureWorks] 
SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN = ON);

In-Memory OLTP

-- メモリ最適化ファイルグループの追加
ALTER DATABASE [AdventureWorks] 
ADD FILEGROUP [InMemory_FG] CONTAINS MEMORY_OPTIMIZED_DATA;

ALTER DATABASE [AdventureWorks] 
ADD FILE (
    NAME = N'InMemory_File',
    FILENAME = N'C:\Data\AdventureWorks_InMemory.ndf'
) TO FILEGROUP [InMemory_FG];

-- メモリ最適化テーブルの作成
CREATE TABLE Sales.OrdersInMemory (
    OrderID INT IDENTITY(1,1) NOT NULL PRIMARY KEY NONCLUSTERED,
    CustomerID INT NOT NULL,
    OrderDate DATETIME2 NOT NULL,
    TotalAmount DECIMAL(18,2) NOT NULL,
    Status TINYINT NOT NULL,
    
    INDEX IX_CustomerID NONCLUSTERED (CustomerID),
    INDEX IX_OrderDate NONCLUSTERED (OrderDate)
) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);

-- ネイティブコンパイルストアドプロシージャ
CREATE PROCEDURE Sales.usp_InsertOrderInMemory
    @CustomerID INT,
    @TotalAmount DECIMAL(18,2)
WITH NATIVE_COMPILATION, SCHEMABINDING
AS
BEGIN ATOMIC WITH (
    TRANSACTION ISOLATION LEVEL = SNAPSHOT,
    LANGUAGE = N'日本語'
)
    INSERT INTO Sales.OrdersInMemory (CustomerID, OrderDate, TotalAmount, Status)
    VALUES (@CustomerID, SYSDATETIME(), @TotalAmount, 1);
END;

セキュリティ機能

-- 透過的データ暗号化(TDE)の有効化
-- マスターキーの作成
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Strong_Password_123!';

-- 証明書の作成
CREATE CERTIFICATE TDE_Certificate 
WITH SUBJECT = 'TDE Certificate for AdventureWorks';

-- データベース暗号化キーの作成
USE [AdventureWorks];
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE TDE_Certificate;

-- TDEの有効化
ALTER DATABASE [AdventureWorks]
SET ENCRYPTION ON;

-- Always Encryptedの設定
CREATE COLUMN MASTER KEY [CMK_AlwaysEncrypted]
WITH (
    KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
    KEY_PATH = N'CurrentUser/My/Certificate_Thumbprint'
);

CREATE COLUMN ENCRYPTION KEY [CEK_AlwaysEncrypted]
WITH VALUES (
    COLUMN_MASTER_KEY = [CMK_AlwaysEncrypted],
    ALGORITHM = 'RSA_OAEP',
    ENCRYPTED_VALUE = 0x...
);

-- 行レベルセキュリティ
CREATE FUNCTION Security.fn_SecurityPredicate(@UserID INT)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
    SELECT 1 AS fn_SecurityPredicate_Result
    WHERE @UserID = USER_ID() OR IS_ROLEMEMBER('db_owner') = 1
);

CREATE SECURITY POLICY Sales.CustomerSecurityPolicy
ADD FILTER PREDICATE Security.fn_SecurityPredicate(UserID) 
ON Sales.Customer
WITH (STATE = ON);