<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Go on blog</title><link>https://tommay.pages.dev/tags/go/</link><description>Recent content in Go on blog</description><generator>Hugo</generator><language>ja-jp</language><lastBuildDate>Wed, 13 May 2026 01:18:16 +0900</lastBuildDate><atom:link href="https://tommay.pages.dev/tags/go/index.xml" rel="self" type="application/rss+xml"/><item><title>GoでRDBMSの自作を始めた【ファイルマネージャー編】</title><link>https://tommay.pages.dev/posts/go-rdbms-file-manager/</link><pubDate>Wed, 13 May 2026 01:18:16 +0900</pubDate><guid>https://tommay.pages.dev/posts/go-rdbms-file-manager/</guid><description>&lt;h1 id="この記事の要約"&gt;この記事の要約&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;DB自作本「Database design and implementation」の1章〜3章までの感想と備忘録&lt;/li&gt;
&lt;li&gt;ファイルマネージャーをGoで実装&lt;/li&gt;
&lt;li&gt;DB自作するときに使うメソッド等や付随するCS知識の整理&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="はじめに"&gt;はじめに&lt;/h1&gt;
&lt;p&gt;最近、CSの基礎知識不足が原因で様々な場面で弊害を感じています。例えば、技術書の理解に時間がかかったり、普段の開発でもベストプラクティスをなぞるだけになったり、概念的な理解に頼らざるを得なかったりと、技術的なトレードオフを厳密に判断できないなどです。この感覚を減らすために、自分が普段ブラックボックスとして利用している技術の自作を始めることにしました。&lt;/p&gt;
&lt;p&gt;自作は「なぜその技術がその設計になったのか」や内部構造そのものを原理原則から理解する体験が得られるため、CSの基礎知識の習得に効果的とされています。&lt;/p&gt;
&lt;p&gt;自作するものとしてよく挙がるのはOS、コンパイラ、ネットワークスタックなど他にも様々ありますが、本記事ではRDBMSを扱います。自作といっても、まずは教育用の完成されたものの写経がメインになるため温かく見守っていただけると嬉しいです。&lt;/p&gt;
&lt;p&gt;本記事では、CS知識が乏しい人間がRDBMSの自作を始めてみた所感を共有します。RDBMSの自作に興味がある方の参考になれば嬉しいです。&lt;/p&gt;
&lt;h1 id="進め方"&gt;進め方&lt;/h1&gt;
&lt;p&gt;書籍はDB自作界隈で定評のある「&lt;strong&gt;Database Design and Implementation&lt;/strong&gt;」を参考に進めていきます。「&lt;strong&gt;Database design and implementation&lt;/strong&gt;」は&lt;strong&gt;SimpleDB&lt;/strong&gt;という、シンプルかつ完全に機能するDBシステムを章ごとに段階的に実装していく内容になっています。書籍ではJavaで実装されていますが、今回はGoで実装していきます。&lt;/p&gt;
&lt;p&gt;こちらの書籍の自作してみた系の記事は既に多く存在し、お手本のリポジトリも多数ある。写経するだけである程度動くものができてしまうということもあり、ちゃんと理解するために暫定的に以下の方法で進めていくことにした。&lt;/p&gt;
&lt;h4 id="流れ"&gt;流れ&lt;/h4&gt;
&lt;p&gt;各章、以下のステップで進めていく（実装は3章から開始）。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;インプットと概念理解&lt;/li&gt;
&lt;li&gt;データの流れと、なぜその設計が必要なのかなどを図などで整理&lt;/li&gt;
&lt;li&gt;実装&lt;/li&gt;
&lt;li&gt;先人たちのリポジトリから該当章時点のスナップショットや、当時のコミット・PRでの議論を参考に、実装したコードと比較し、理解を深める。&lt;/li&gt;
&lt;li&gt;その章が終わったら記事等でアウトプット&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="書籍中での実装の流れ"&gt;書籍中での実装の流れ&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;ファイルマネージャー（3章）&lt;/li&gt;
&lt;li&gt;バッファマネージャー（4章）&lt;/li&gt;
&lt;li&gt;トランザクションマネージャー（5章）&lt;/li&gt;
&lt;li&gt;レコードマネージャー（6章）&lt;/li&gt;
&lt;li&gt;メタデータマネージャー（7章）&lt;/li&gt;
&lt;li&gt;クエリプロセッサー（8章）&lt;/li&gt;
&lt;li&gt;SQLパーサー（9章）&lt;/li&gt;
&lt;li&gt;プランナー（10章）&lt;/li&gt;
&lt;li&gt;DB接続インターフェース（11章）&lt;/li&gt;
&lt;li&gt;インデックスマネージャー（12章）&lt;/li&gt;
&lt;li&gt;ソート(13章)&lt;/li&gt;
&lt;li&gt;バッファの有効活用（14章）&lt;/li&gt;
&lt;li&gt;クエリオプティマイザー（15章）&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="12章について"&gt;1〜2章について&lt;/h1&gt;
&lt;p&gt;1章では、そもそもデータの管理にはどのような課題があり、それを解決するためにDBシステムはどのような機能を提供しなければいけないのかという話がメインでした。普段は自分がやりたいことが実現できそうなDBの機能を使っているだけでしたが、1章では目的や思想から向き合い、その機能がどういう目的で作られたのかという逆方向のアプローチでDBについて知ることができてとても面白かったです。&lt;/p&gt;
&lt;p&gt;2章では、JDBCという「JavaアプリがDBシステムとやり取りする時に使う標準API」の仕組みや使い方、JDBC問わずAPI側が提供すべき機能といった設計思想、後半ではトランザクションの概要の話がメインでした。&lt;/p&gt;
&lt;h1 id="3章"&gt;3章&lt;/h1&gt;
&lt;p&gt;3章からはいよいよ実装フェーズに入りました。前半はディスクや、OSが提供する2つのインターフェース（ブロックレベルとファイルレベル）、そしてファイルの論理ブロックからディスクの物理ブロックへどのようにマッピングされるのかなどの基本概念を学びました。
後半では実際にSimpleDBのファイルマネージャーを実装しました。&lt;/p&gt;
&lt;h2 id="概念整理"&gt;概念整理&lt;/h2&gt;
&lt;h3 id="ファイルマネージャー"&gt;ファイルマネージャー&lt;/h3&gt;
&lt;p&gt;ファイルマネージャーとはDBエンジンがOSとやり取りを行う部分のことです。&lt;/p&gt;
&lt;h3 id="simpledbが採用しているディスク上のデータを管理する手法"&gt;SimpleDBが採用しているディスク上のデータを管理する手法&lt;/h3&gt;
&lt;p&gt;これは書籍が分かりやすいため引用します。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A compromise strategy is for the database system to store all of its data in one or more OS files, but to treat the files as if they were raw disks. That is, the database system accesses its “disk” using logical file blocks. The OS is responsible for mapping each logical block reference to its corresponding physical block, via the seek method.&lt;/p&gt;</description></item><item><title>Hello World</title><link>https://tommay.pages.dev/posts/hello-world/</link><pubDate>Fri, 12 Sep 2025 01:07:04 +0900</pubDate><guid>https://tommay.pages.dev/posts/hello-world/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello World!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;key1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;key2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;%s, %d&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item></channel></rss>