@prefix schema: <https://schema.org/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ks: <https://comcomponent.com/vocab/> .

<https://comcomponent.com/blog/windows-app-local-data-storage-decision-table/#article>
    schema:about <https://comcomponent.com/knowledge/sqlite/>, <https://comcomponent.com/knowledge/json-file/>, <https://comcomponent.com/knowledge/windows-registry/> ;
    schema:mentions <https://comcomponent.com/knowledge/access-database/>, <https://comcomponent.com/knowledge/ace-provider/>, <https://comcomponent.com/knowledge/local-appdata/>, <https://comcomponent.com/knowledge/program-data/>, <https://comcomponent.com/knowledge/roaming-appdata/>, <https://comcomponent.com/knowledge/registry-redirection/>, <https://comcomponent.com/knowledge/wal-mode/>, <https://comcomponent.com/knowledge/atomic-file-replace/>, <https://comcomponent.com/knowledge/partial-write-corruption/>, <https://comcomponent.com/knowledge/multi-machine-data-sharing/>, <https://comcomponent.com/knowledge/sql-server-express/>, <https://comcomponent.com/knowledge/dpapi/>, <https://comcomponent.com/knowledge/dotnet/>, <https://comcomponent.com/knowledge/smb-445/>, <https://comcomponent.com/knowledge/installer/>, <https://comcomponent.com/knowledge/bitness-match-requirement/>, <https://comcomponent.com/knowledge/hardware-replacement/>, <https://comcomponent.com/knowledge/power-loss/>, <https://comcomponent.com/knowledge/app-secrets/> .

<https://comcomponent.com/knowledge/sqlite/> a skos:Concept ;
    skos:prefLabel "SQLite"@ja ;
    skos:definition "デスクトップ業務アプリでよく使われる組み込み型のリレーショナルデータベースエンジン。"@ja ;
    ks:notRecommendedFor <https://comcomponent.com/knowledge/smb-445/> ;
    ks:notRecommendedFor <https://comcomponent.com/knowledge/multi-machine-data-sharing/> ;
    ks:mitigates <https://comcomponent.com/knowledge/partial-write-corruption/> .

<https://comcomponent.com/knowledge/json-file/> a skos:Concept ;
    skos:prefLabel "JSONファイル"@ja ;
    skos:definition "構造化された小さいデータを人間が読める形式で保存する、設定用途の第一候補となるファイル形式。"@ja ;
    skos:altLabel "System.Text.Json" .

<https://comcomponent.com/knowledge/windows-registry/> a skos:Concept ;
    skos:prefLabel "レジストリ"@ja ;
    skos:definition "Windowsが設定情報を階層的なキーと値で保持するシステムのデータストアで、小さなフラグやWindows連携情報の保存に適する。"@ja ;
    skos:altLabel "Windowsレジストリ"@ja .

<https://comcomponent.com/knowledge/local-appdata/> a skos:Concept ;
    skos:prefLabel "%LOCALAPPDATA%"@ja ;
    skos:definition "ユーザーごとの、ローミングしないデータを保存する既知フォルダーで、ユーザーごとのデータの既定の置き場所。"@ja ;
    skos:altLabel "SpecialFolder.LocalApplicationData" ;
    skos:altLabel "AppData\\Local" ;
    skos:altLabel "FOLDERID_LocalAppData" .

<https://comcomponent.com/knowledge/program-data/> a skos:Concept ;
    skos:prefLabel "%PROGRAMDATA%"@ja ;
    skos:definition "全ユーザー共有のデータを保存する既知フォルダー。既定のACLでは別ユーザーが変更できない構成になり得る。"@ja ;
    skos:altLabel "SpecialFolder.CommonApplicationData" ;
    ks:configuredBy <https://comcomponent.com/knowledge/installer/> .

<https://comcomponent.com/knowledge/installer/> a skos:Concept ;
    skos:prefLabel "インストーラー"@ja ;
    skos:definition "管理者権限で動作し、アプリの配置と関連設定を行う導入プログラム。"@ja ;
    skos:altLabel "セットアップ"@ja .

<https://comcomponent.com/knowledge/roaming-appdata/> a skos:Concept ;
    skos:prefLabel "%APPDATA%(Roaming)"@ja ;
    skos:definition "移動ユーザープロファイル環境でログオン・ログオフ時に同期される既知フォルダー。"@ja ;
    skos:altLabel "SpecialFolder.ApplicationData" ;
    skos:altLabel "AppData\\Roaming" ;
    skos:altLabel "%APPDATA%" ;
    skos:altLabel "FOLDERID_RoamingAppData" .

<https://comcomponent.com/knowledge/wal-mode/> a skos:Concept ;
    skos:prefLabel "WALモード(Write-Ahead Logging)"@ja ;
    skos:definition "変更をデータベース本体ではなく隣接する-walファイルへ追記していき、読み取りと書き込みを同時に進められるようにするSQLiteのジャーナリングモード。"@ja ;
    skos:altLabel "journal_mode=WAL" ;
    ks:incompatibleWith <https://comcomponent.com/knowledge/smb-445/> .

<https://comcomponent.com/knowledge/smb-445/> a skos:Concept ;
    skos:prefLabel "SMB(TCP 445)"@ja ;
    skos:definition "ファイル共有とリモート名前付きパイプが使うプロトコルとポート。"@ja ;
    skos:altLabel "ファイル共有ポート"@ja .

<https://comcomponent.com/knowledge/dotnet/> a skos:Concept ;
    skos:prefLabel ".NET(Core以降)"@ja ;
    skos:definition ".NET Frameworkの後継となる、クロスプラットフォーム対応の.NETランタイム(.NET 5以降)。"@ja ;
    skos:altLabel ".NET Core" ;
    skos:altLabel "モダンな.NET"@ja .

<https://comcomponent.com/knowledge/dpapi/> a skos:Concept ;
    skos:prefLabel "DPAPI"@ja ;
    skos:definition "実行中のマシン上でアプリの秘密情報を保護するWindowsのデータ保護API。"@ja ;
    skos:altLabel "データ保護API"@ja ;
    ks:recommendedFor <https://comcomponent.com/knowledge/app-secrets/> .

<https://comcomponent.com/knowledge/app-secrets/> a skos:Concept ;
    skos:prefLabel "アプリの秘密情報"@ja ;
    skos:definition "業務アプリが扱う接続文字列・APIキーなどの秘密情報。ログオン済みマシンではドライブ暗号化では守れない。"@ja ;
    skos:altLabel "接続文字列"@ja ;
    skos:altLabel "APIキー"@ja .

<https://comcomponent.com/knowledge/registry-redirection/> a skos:Concept ;
    skos:prefLabel "レジストリリダイレクター(Wow6432Node)"@ja ;
    skos:definition "64bit Windowsで32bitプロセスからのHKLM\\Softwareアクセスを自動的にWow6432Node配下へ転送する仕組み。"@ja ;
    skos:altLabel "Registry Redirector" .

<https://comcomponent.com/knowledge/access-database/> a skos:Concept ;
    skos:prefLabel "Access(.accdb)"@ja ;
    skos:definition "JET/ACEエンジンを使うMicrosoft Accessのローカルデータベースファイル形式。新規開発でデータストアに選ぶ理由はほぼない。"@ja ;
    skos:altLabel "JET/ACEデータベース"@ja ;
    skos:altLabel ".accdb" ;
    ks:requires <https://comcomponent.com/knowledge/ace-provider/> .

<https://comcomponent.com/knowledge/ace-provider/> a skos:Concept ;
    skos:prefLabel "ACE(Access Database Engine)プロバイダー"@ja ;
    skos:definition ".accdb/.mdbへコードから接続するために必要な、Officeのデータアクセスコンポーネント。"@ja ;
    skos:altLabel "Microsoft.ACE.OLEDB" ;
    ks:requires <https://comcomponent.com/knowledge/bitness-match-requirement/> .

<https://comcomponent.com/knowledge/bitness-match-requirement/> a skos:Concept ;
    skos:prefLabel "bitness一致要件"@ja ;
    skos:definition "ネイティブモジュール(in-procのCOMコンポーネント、P/Invokeで呼ぶDLL、ベンダー提供SDKのDLLなど)を読み込むホストプロセスと、そのモジュールのビット構成(32bit/64bit)が一致していなければならないという制約。"@ja ;
    skos:altLabel "32bit/64bitの一致"@ja ;
    skos:altLabel "bitness match" .

<https://comcomponent.com/knowledge/multi-machine-data-sharing/> a skos:Concept ;
    skos:prefLabel "複数マシンからのデータ共有要件"@ja ;
    skos:definition "複数拠点・複数ユーザーが同じデータへ同時に読み書きしたいという要件。ローカル保存技術ではどれも対応しきれない。"@ja .

<https://comcomponent.com/knowledge/sql-server-express/> a skos:Concept ;
    skos:prefLabel "SQL Server Express"@ja ;
    skos:definition "データベース10GBまで無償で使えるSQL Serverのエディションで、ローカル保存を卒業する際のサーバー型DBの選択肢の一つ。"@ja ;
    ks:recommendedFor <https://comcomponent.com/knowledge/multi-machine-data-sharing/> .

<https://comcomponent.com/knowledge/partial-write-corruption/> a skos:Concept ;
    skos:prefLabel "書き込み中断によるファイル破損"@ja ;
    skos:definition "ファイルへの書き込みが電源断などで中断され、中途半端な内容のまま残って読み込めなくなる状態。"@ja .

<https://comcomponent.com/knowledge/power-loss/> a skos:Concept ;
    skos:prefLabel "電源断・OSクラッシュ"@ja ;
    skos:definition "システム全体が突然停止する障害。電源喪失やブルースクリーンなど。キャッシュ上のダーティページを失わせる。"@ja ;
    skos:altLabel "電源喪失"@ja ;
    skos:altLabel "ブルースクリーン"@ja ;
    skos:altLabel "システム障害"@ja ;
    ks:mayCause <https://comcomponent.com/knowledge/partial-write-corruption/> .

<https://comcomponent.com/knowledge/atomic-file-replace/> a skos:Concept ;
    skos:prefLabel "アトミックなファイル置き換え(File.Replace)"@ja ;
    skos:definition "一時ファイルに書き込んでから既存ファイルと入れ替える、書き込み中断時の破損を防ぐファイル更新パターン。"@ja ;
    skos:altLabel "File.Replace" ;
    ks:prevents <https://comcomponent.com/knowledge/partial-write-corruption/> .

<https://comcomponent.com/knowledge/hardware-replacement/> a skos:Concept ;
    skos:prefLabel "ハードウェア交換"@ja ;
    skos:definition "マザーボード交換やドライブの別PCへの移設など、起動環境が変わるハードウェアの変更。"@ja ;
    skos:altLabel "マザーボード交換"@ja ;
    skos:altLabel "ドライブ移設"@ja .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/json-file/> ;
    rdf:predicate ks:storedIn ;
    rdf:object <https://comcomponent.com/knowledge/local-appdata/> ;
    schema:description "ユーザーごとの設定・データをWindowsアプリが自前で持つ場合、本記事はLocalAppDataを既定の置き場所として推奨しており、JSONファイルはまずここに置く。ポータブル運用や、利用者にファイルの場所を選ばせる設計では別の場所になる"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/shell/knownfolderid> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sqlite/> ;
    rdf:predicate ks:storedIn ;
    rdf:object <https://comcomponent.com/knowledge/local-appdata/> ;
    schema:description "同じくユーザーごとの業務データ・履歴をWindowsアプリが自前で持つ場合、本記事はSQLiteファイルもLocalAppDataを既定の置き場所とする。全ユーザー共有のデータや、利用者が保存先を選ぶ設計では別の場所になる"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/shell/knownfolderid> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sqlite/> ;
    rdf:predicate ks:storedIn ;
    rdf:object <https://comcomponent.com/knowledge/program-data/> ;
    schema:description "全ユーザー共有のデータとして扱うSQLiteはProgramData配下にACL設計とあわせて置く"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/shell/knownfolderid> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/program-data/> ;
    rdf:predicate ks:configuredBy ;
    rdf:object <https://comcomponent.com/knowledge/installer/> ;
    schema:description "ProgramData配下を全ユーザー共有の読み書き領域にするには、インストーラーでフォルダーを作成しACLを明示的に設定する必要がある"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/shell/knownfolderid> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/roaming-appdata/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/sqlite/> ;
    schema:description "サイズの大きいデータやマシン固有のデータをRoamingに置くと同期の遅延や別マシンへの汚染を招くため、増え続けるSQLiteのようなデータをRoamingへ既定にしないほうがよい"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/shell/knownfolderid> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sqlite/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/wal-mode/> ;
    schema:description "SQLiteはPRAGMA journal_mode=WALを明示的に設定した場合にWALモードで動き、読み取りと書き込みを同時に進められるようになる。既定はロールバックジャーナルモード"@ja ;
    ks:evidence <https://www.sqlite.org/wal.html> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/wal-mode/> ;
    rdf:predicate ks:incompatibleWith ;
    rdf:object <https://comcomponent.com/knowledge/smb-445/> ;
    schema:description "WALモードは同じマシン上のプロセスが共有メモリを使うことを前提としており、SMB越しのネットワークファイルシステム上では機能しない"@ja ;
    ks:evidence <https://www.sqlite.org/wal.html> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sqlite/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/smb-445/> ;
    schema:description "SMB越しのファイルロックは環境依存の問題が多く、SQLite公式もネットワークファイルシステム上での共有を破損原因の筆頭に挙げている"@ja ;
    ks:evidence <https://www.sqlite.org/howtocorrupt.html> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dotnet/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/sqlite/> ;
    schema:description "SQLiteを使う場合、.NETからはMicrosoftがメンテナンスするADO.NETプロバイダーMicrosoft.Data.Sqlite、またはEF CoreのSQLiteプロバイダーで利用する"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/standard/data/sqlite/> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dpapi/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/app-secrets/> ;
    schema:description "機密情報はどの形式に保存するとしても平文で置かず、保存前にDPAPIで暗号化することが本記事の推奨である(Credential Lockerなど他の保護手段も選択肢になり得る)"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.security.cryptography.dataprotectionscope> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/windows-registry/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/registry-redirection/> ;
    schema:description "64bit Windowsのレジストリは32bit/64bitプロセスの分離にレジストリリダイレクター(Wow6432Node)の仕組みを使う"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/winprog64/registry-redirector> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/access-database/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/ace-provider/> ;
    schema:description ".accdbにコードからアクセスするにはACE(Access Database Engine)プロバイダーが必要である"@ja ;
    ks:evidence <https://learn.microsoft.com/troubleshoot/power-platform/power-automate/desktop-flows/cannot-connect-access-database-engine-ole-db> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/ace-provider/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/bitness-match-requirement/> ;
    schema:description "アプリのビット数とACEのビット数が一致していなければ接続できないという制約が付きまとう"@ja ;
    ks:evidence <https://learn.microsoft.com/troubleshoot/power-platform/power-automate/desktop-flows/cannot-connect-access-database-engine-ole-db> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sqlite/> ;
    rdf:predicate ks:succeeds ;
    rdf:object <https://comcomponent.com/knowledge/access-database/> ;
    schema:description "既存のAccess資産と連携する場合でも、長期的にはSQLiteまたはサーバー型DBへの移行パスを持つことが勧められている"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/apps/develop/data-access/sqlite-data-access> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sqlite/> ;
    rdf:predicate ks:notRecommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/multi-machine-data-sharing/> ;
    schema:description "SQLiteを含むローカル保存の技術はどれも複数マシンからの共有には向かない"@ja ;
    ks:evidence <https://www.sqlite.org/whentouse.html> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sql-server-express/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/multi-machine-data-sharing/> ;
    schema:description "複数拠点・複数ユーザーで同じデータを触る要件が出てきたら、SQL Server Expressなどのサーバー型DBを立てる判断ラインになる"@ja ;
    ks:evidence <https://learn.microsoft.com/sql/sql-server/> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sqlite/> ;
    rdf:predicate ks:mitigates ;
    rdf:object <https://comcomponent.com/knowledge/partial-write-corruption/> ;
    schema:description "SQLiteはトランザクションにより、書き込み中断による破損への強さがJSONファイルより高い"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/standard/data/sqlite/> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/power-loss/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/partial-write-corruption/> ;
    schema:description "書き込み中の電源断が起きると、中途半端な内容のファイルが残り次回起動時に読めなくなる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.io.file.replace> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/atomic-file-replace/> ;
    rdf:predicate ks:prevents ;
    rdf:object <https://comcomponent.com/knowledge/partial-write-corruption/> ;
    schema:description "一時ファイルに書いてからFile.Replaceで置き換える方式は、書き込み中断による破損を防ぐ定石である"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.io.file.replace> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/json-file/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/partial-write-corruption/> ;
    schema:description "アトミックな置き換えを行わずに書き込むと、書き込み中の電源断でJSONファイルが中途半端な内容のまま残り読めなくなる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.io.file.replace> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dpapi/> ;
    rdf:predicate ks:incompatibleWith ;
    rdf:object <https://comcomponent.com/knowledge/hardware-replacement/> ;
    schema:description "DPAPIで保護した値は同一ユーザー・同一マシンでしか復号できないため、マザーボード交換のような端末移行では単純な複製だけでは戻せない"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.security.cryptography.dataprotectionscope> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/app-secrets/> ;
    rdf:predicate ks:storedIn ;
    rdf:object <https://comcomponent.com/knowledge/json-file/> ;
    schema:description "DPAPIで暗号化した機密情報のbytesは、平文でない値としてJSONファイルなどの器にそのまま保存できる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.security.cryptography.dataprotectionscope> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .
