SQLServer LocalDB を深堀りしてみた
こんにちは。ディアシステム開発1部開発2課の鶴田です。
今回は SQLServer LocalDB を深堀りしていこうと思います。 ※とりあえずサクッと動かしたい方はこちらの記事が良いです♪
今まではAzure SQLDatabaseやローカルにSQLServer Expressをインストールして開発環境を構築していましたが・・・
- 利用していない間も課金される
- サービスが起動しっぱなし
- チーム内でサービスを共用しているときれいに整えたテストデータをほかの人に使われてしまう(;^ω^)
ところに不便を感じていました。LocalDBであれば、必要な時だけ起動すればよく、リソースの節約になるし、きれいに整えたテストデータを自分専用にできるわけで、ええ感じやん、と。
今回、LocalDBを深堀することで
- DBを作成し
- ログインユーザーを複数作成し
- 別のスキーマを作って
- 動くかどうか確認する
- 一通りの設定ができるPowerShellを作成する
ところまで達成したので、達成に至る過程と成果物、葛藤(笑)を記録として残します。
LocalDBとは
LocalDBは正式名称を「Microsoft SQL Server Express LocalDB」といいます。この機能は、開発者を対象とした SQL Server Express の1機能に位置付けられています。
またVSCodeやVisualStudioとの親和性も高く、1つの開発環境で設定変更可能になります。
まぁ、ええ感じですね。やってみないとわからんけど
インストール
インストールには、SQLServerExpressのインストーラーやオンラインインストーラーが公開されています。 過去のバージョンも公開されています。
インストールすると、SQL Server データベース エンジン の開始に最低限必要なファイルがコピーされます。必要な時だけON、イラン時OFF可能なことも合わさってローカルPCのリソース節約できます。
LocalDBの使い方
インスタンスの作成・起動
LocalDBを使うときは最初にインスタンスを作成、起動します。インスタンスの作成には sqllocaldb create コマンドを使います。
sqllocaldb create インスタンス名
sqllocaldb start インスタンス名
「インスタンスを起動」とは?
インスタンスを起動すると、SQLServerのプロセスが起動します。タスクマネージャーなどで起動を確認できます。インスタンスを停止するとタスクマネージャーからそのプロセスが消えます。
1つのインスタンスは対になるシステムDBを持ちます。そしてインスタンスごとに設定情報を持ちます。
複数の設定情報を切り替えて使いたいときはインスタンスを切り替えるとできます。
インストールされる際にインスタンス名:MSSQLLocalDB はデフォルトとして導入されており、それを使うと手軽なのですが、わたしは以下の理由から開発プロジェクトごとにインスタンスを用意するのが良いと考えています。
- 環境を分離する このインスタンスは「xxxプロジェクト用」「結合テスト用「試す用」なども可能ですし、DBエンジンのバージョンを指定することも可能です
- 壊してもほかに波及しない
- 接続先を明示しやすい
ただ、デメリットもあります。一番のデメリットは
-
管理が大変(;^ω^) 何のインスタンスだったか忘れるんだよねー・・・
-
ディスク消費量が増える ローカルPCであれば容量の心配は少ないのですが、開発をVPCで行う場合はディスク容量が潤沢にない場合もあります。さらにインスタンスごとにシステムDBが作成されるので、消費量はさらに増えます。
今回はより実践向けとするため、別のインスタンスを用意します。今回用意するインスタンスは
myLocalDB
です。では作成と開始を実施します。作成するときはターミナル(PowerShell)で作成します。
PS C:\repos\localdb> sqllocaldb create myLocalDB
LocalDB instance "myLocalDB" created with version 17.0.1000.7.
PS C:\repos\localdb> sqllocaldb start myLocalDB
LocalDB instance "myLocalDB" started.
システムDBが以下のフォルダに作成されます。
%userprofile%\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances\mylocaldb
ちょっと見てみましょう。
ディレクトリ: %userprofile%\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances\mylocaldb
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2026/04/18 18:08 14744 error.log
-a---- 2026/04/18 18:00 26564 error1.log
-a---- 2026/04/18 18:00 0 error2.log
-a---- 2026/04/18 18:00 70144 HkEngineEventFile_0_134209764321980000.xel
-a---- 2026/04/18 18:03 70144 HkEngineEventFile_0_134209766327370000.xel
-a---- 2026/04/18 18:00 1048576 log.trc
-a---- 2026/04/18 18:08 1048576 log_1.trc
-a---- 2026/04/18 18:03 4849664 master.mdf
-a---- 2026/04/18 18:08 2097152 mastlog.ldf
-a---- 2026/04/18 18:03 8388608 model.mdf
-a---- 2026/04/18 18:08 8388608 modellog.ldf
-a---- 2026/04/18 18:03 14811136 msdbdata.mdf
-a---- 2026/04/18 18:08 786432 msdblog.ldf
-a---- 2026/04/18 18:00 137728 system_health_0_134209764324720000.xel
-a---- 2026/04/18 18:08 134656 system_health_0_134209766328430000.xel
-a---- 2026/04/18 18:03 8388608 tempdb.mdf
-a---- 2026/04/18 18:03 516096 templog.ldf
インスタンス1つ作ると48メガですか・・・そうですか・・・意外と多いですね(;^ω^)
中身はDBが使うシステムDBのようです。別のフォルダに移せるのかな・・・?たしかSSMSに既定パス変更機能があったはずですね。
調べてみましょう。
LocalDBにおいてシステムDBは移動可能か?
調べてみると2012年に投稿された記事を見つけました。 https://stackoverflow.com/questions/13778034/how-do-i-change-database-default-locations-for-localdb-in-sql-server-managemen
この投稿では投稿者がSSMSを使ってlocalDbの既定の保存先変更を試みたがエラーが出てうまくいかない旨、紹介されています。
なぜできないのか?
この記事では以下の原因が提示されています。
-
マイグレーションスクリプトを実行する Entity Framework Core の使用 スクリプトで作成されたデータベースの保存場所は、SQL Server のデフォルトのファイル パス設定に依存する(らしい)。
-
SQLServer や SQLExpress をインストールした際にインストールされるデフォルトインスタンス「LocalDB Automatic Instance」に関する取扱い 「LocalDB Automatic Instance」を作成すると特定の機能が上書き&ロックされるそうです。そして、SQLServerのフルバージョン(Standard、Developerのことか?)をインストール済みだったり、古いインスタンスを削除して新しいLocalDBインスタンスを作成したユーザーはこの問題には遭遇しない・・・そうです
-
この問題は「既定の保存先」がレジストリに保存されており、レジストリの書き換えは特定のユーザーのみ可能であることが根本的な問題であることが示唆されていました。これが本当であるならば、ユーザーモードでしか動作しないLocalDB単体では対応方法がないことになります。
フルバージョンのSQLServerをインストールすることで回避可能なようですが、そもそもの出発点がローカルPCのリソースを節約したい、という目的から始まっていますからね・・・
LocalDBのシステムDBはこのままのほうがよさそうですね(;^ω^)
では代わりと言っては何ですが、ユーザーDBのみ別フォルダにしましょう。
ユーザーDBの作成
ユーザーDBの作成に入ります。ここからはSQLClientツール経由で作業します。
SQLClientツールは様々なソフトがありますので、ご自身にあったツールをご利用ください。
接続する際は
サーバー名:(localdb)\myLocalDB 認証:Windows認証
を選択してください。ツールより以下のSQLコマンドを実行し、Databaseを作成します。
CREATE DATABASE [MyDatabase]
ON PRIMARY
(
NAME = N'MyDatabase',
FILENAME = N'C:\repos\localdb\myLocalDB.mdf',
SIZE = 8MB,
FILEGROWTH = 8MB
)
LOG ON
(
NAME = N'MyDatabase_log',
FILENAME = N'C:\repos\localdb\myLocalDB_log.ldf',
SIZE = 1MB,
FILEGROWTH = 1MB
);
このSQLは
MyDatabaseという名前のDatabaseを作成して データファイル名とログファイル名の指定 初期サイズと拡張サイズの指定
を行っています。ちなみにですがデータファイルの初期サイズは最小が8MBのようです。それ以下を指定しても無視されました。
続いて、復旧モデルをSIMPLEに変更しておきます。こうすることでログ肥大化を防ぐことが可能です。
ALTER DATABASE [MyDatabase] SET RECOVERY SIMPLE;
Databaseを作成したら、その配下のオブジェクトを作成します。 現在のDBを、MyDatabaseへ切り替えておきましょう。
USE [MyDatabase];
次はユーザーの作成です。 DbAdminと、CRUD可能なユーザー、SELECTのみが可能なユーザーの3種類を作成します。
この3種類のユーザーを作るやり方は、業務でよく使われます。 DBオブジェクトなどの作成をするときはDBAdminを、 プログラムなどが利用するCRUD可能なユーザー、 そして運用/調査のときに利用するSELECTのみが可能なユーザーを使い分けることで、事故や漏洩時の被害を最小に抑える、という目的です。
CREATE LOGIN [dbAdmin] WITH PASSWORD = N'$DbAdminPassword';
CREATE LOGIN [dbUser] WITH PASSWORD = N'$dbUserPassword';
CREATE LOGIN [dbRUser] WITH PASSWORD = N'$dbRUserPassword';
実際はもう少し複雑なパスワードのほうが良いですよ?(笑)
次はスキーマを作成しましょう。スキーマとは、データベース内のテーブルやビューなどを分類して管理するための入れ物です。テーブルやビューなどのDBオブジェクトの前につけることでスキーマを切り替えることが可能です。 以下の場合、APP がスキーマを表現しています。
SELECT * FROM APP.SAMPLE_T
実際の業務で、スキーマを定義する目的は
- DBオブジェクトを整理する。各オブジェクトの前にスキーマ名が付与されますので、整理・整頓できます。1つのインスタンスを複数の業務で使い分ける場合に利用します。
- 権限管理が容易。スキーマ単位で権限(GRANT)を付与することで権限管理に必要な工数を削減できます。
EXEC(N'CREATE SCHEMA [APP]')
ユーザーとスキーマを作成したら、ユーザーにデフォルトスキーマを割り当てます。
CREATE USER [dbAdmin] FOR LOGIN [dbAdmin] WITH DEFAULT_SCHEMA = [dbo];
CREATE USER [dbUser] FOR LOGIN [dbUser] WITH DEFAULT_SCHEMA = [APP];
CREATE USER [dbRUser] FOR LOGIN [dbRUser] WITH DEFAULT_SCHEMA = [APP];
スキーマ単位にGRANTを設定します。テーブル単位に与えるのは本番環境のみです。開発環境ではやりません。
ALTER ROLE [db_owner] ADD MEMBER [dbAdmin];
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::[APP] TO [dbUser];
GRANT SELECT ON SCHEMA::[APP] TO [dbRUser];
ここまで出来たら、テーブルを作成してみましょう。スキーマはAPPです。
CREATE TABLE [APP].[Sample_T]
(
SampleId INT IDENTITY(1,1) NOT NULL,
SampleName NVARCHAR(100) NOT NULL,
CreatedAt DATETIME2 NOT NULL
CONSTRAINT [DF_T_Sample_CreatedAt] DEFAULT DATEADD(HOUR, 9, SYSUTCDATETIME()),
CONSTRAINT [PK_Sample] PRIMARY KEY CLUSTERED ([SampleId])
);
これで作成完了です。テストしましょう♪
LocalDBの検証
まずはWindows認証で接続します

この状態で接続するとインスタンスに対する管理ユーザーとして接続できます。
DBを切り替えて・・・
USE MyDatabase;
スキーマの一覧を表示してみます。
SELECT name
FROM sys.schemas
ORDER BY name;
うん。ありますね!
次はユーザーごとにCRUDが分かれているか?ですね。
INSERT, SELECT, UPDATE, DELETE それぞれ確認します
(中略)
できてますね!
ええ感じです。
最後にここまでの学びをもとに、PowerShellを作成しました。ダウンロードは ここ からダウンロードできます。
スクリプトの使い方
使い方
- スクリプト内の設定値を変更する。 変更する箇所は以下の通り
- インスタンス名 $InstanceName = "myLocalDB"
- データベース名 $DatabaseName = "AppDb"
- データベース管理者IDとパスワード
$DbAdminUser = "DBAdmin"
$DbAdminPassword = "DbAdmin#2026!"
- CRUD可能なユーザーIDとパスワード
$User1Name = "user1"
$User1Password = "User1#2026!"
- 参照のみ可能なユーザーIDとパスワード
$ReadOnlyUserName = "ReadOnlyUser"
$ReadOnlyUserPassword = "ReadOnly#2026!"
- 管理者のデフォルトスキーマ名
$AdminDefaultSchema = "dbo"
- その他のユーザーのデフォルトスキーマ名
$AppSchema = "APP"
- データDBファイルの保存場所
$MdfPath = Join-Path $DataDir "$DatabaseName.mdf"
$LdfPath = Join-Path $DataDir "$`{DatabaseName}`_log.ldf"
- 実行する際は、Windowsのターミナル(PowerShell)より実行する。引数は以下の通り。 DataDir データを保存するフォルダ。省略するとPowerShellが実行されているフォルダ
LocalDbVersion LocalDBのエンジンバージョン。省略するとデフォルトのバージョンになる。
例: .\CreateLocalDb.ps1 -DataDir "D:\SqlData" -LocalDbVersion "16.0"
- 実行したあと、PowerShellの保存フォルダ内に以下のファイルが作成されます。
- init_localdb.sql ・・・DB作成後からのSQLスクリプト
- connectionStrings.txt ・・・プログラム向けの接続スクリプト
補足1 インスタンス、データベース、スキーマの関係を1行で!
インスタンス・・・SQLServerのプログラム
データベース・・・データの入れ物
スキーマ ・・・データベース内で整理・分類できる単位
今回作ったのは以下の構成です。
MyLocalDb :インスタンス
└─ AppDb :データベース
├─ dbo :スキーマ
│ └─ (管理用オブジェクトなど)
└─ app :スキーマ
├─ Sample_T :テーブルなど
└─ Sample_V
補足2 sqllocaldbのコマンド
情報取得
sqllocaldb info MSSQLLocalDB
インスタンス開始
sqllocaldb start MSSQLLocalDB
インスタンス停止
sqllocaldb stop MSSQLLocalDB
インスタンスの削除
sqllocaldb stop MSSQLLocalDB -k
sqllocaldb delete MSSQLLocalDB
sqllocaldb info
インスタンスへ接続
sqlcmd -s "(localdb)\MSSQLLocalDB"