# データベース設計書

## 概要

本ドキュメントは、Etherpad-liteプロジェクトのデータベース構造を定義する設計書です。Etherpadはキーバリュー型データベース（UeberDB）を使用しており、従来のリレーショナルデータベースとは異なるスキーマレス構造を採用しています。本書では、各キーの構造と保存されるデータの形式を定義します。

## テーブル一覧

| テーブル名（キープレフィックス） | 対応エンティティ | 説明 |
| --- | --- | --- |
| groups | Groups | 全グループのID一覧を保持 |
| group:$GROUPID | Group | グループの詳細情報 |
| pad:$PADID | Pad | パッドの基本情報（属性テキスト、プール、ヘッド等） |
| pad:$PADID:revs:$REVNUM | Revision | パッドのリビジョン情報 |
| pad:$PADID:chat:$CHATNUM | ChatMessage | パッドのチャットメッセージ |
| pad2readonly:$PADID | ReadOnlyMapping | パッドIDから読み取り専用IDへのマッピング |
| readonly2pad:$READONLYID | ReadOnlyMapping | 読み取り専用IDからパッドIDへのマッピング |
| token2author:$TOKENID | TokenMapping | トークンから著者IDへのマッピング |
| mapper2author:$MAPPER | AuthorMapping | 外部アプリケーション識別子から著者IDへのマッピング |
| mapper2group:$MAPPER | GroupMapping | 外部アプリケーション識別子からグループIDへのマッピング |
| globalAuthor:$AUTHORID | Author | 著者の詳細情報 |
| session:$SESSIONID | Session | セッション情報 |
| author2sessions:$AUTHORID | AuthorSessions | 著者のセッション一覧 |
| group2sessions:$GROUPID | GroupSessions | グループのセッション一覧 |

## 各テーブル定義

### 1. groups

全ての既存グループのIDを管理するオブジェクト。グループIDをキーとし、値は常に`1`。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| [groupID] | Number | NO | グループが存在することを示すフラグ（値は常に1） |

### 2. group:$GROUPID

グループの詳細情報を保持。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| pads | Object | NO | グループに属するパッドのIDをキーとするオブジェクト（値は常に1） |
| mappings | Object | YES | 外部マッパーからグループへのマッピング情報 |

### 3. pad:$PADID

パッドの基本情報を保持。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| atext | Object | NO | 最新の属性付きテキスト（text, attribsを含む） |
| pool | Object | NO | 属性プール（AttributePool） |
| head | Number | NO | 最新リビジョン番号 |
| chatHead | Number | NO | 最新チャットエントリ番号 |
| publicStatus | Boolean | YES | パッドの公開状態フラグ |
| savedRevisions | Array | YES | 保存されたリビジョンの配列 |

### 4. pad:$PADID:revs:$REVNUM

パッドの各リビジョン情報を保持。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| changeset | String | NO | このリビジョンの変更セット |
| meta | Object | NO | メタ情報オブジェクト |
| meta.author | String | YES | このリビジョンの著者ID |
| meta.timestamp | Number | NO | リビジョン作成のタイムスタンプ |
| meta.pool | Object | YES | キーリビジョンの場合のみ、属性プール |
| meta.atext | Object | YES | キーリビジョンの場合のみ、属性付きテキスト |

### 5. pad:$PADID:chat:$CHATNUM

パッドのチャットメッセージを保持。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| text | String | NO | チャットメッセージのテキスト |
| authorId | String | NO | メッセージ送信者の著者ID |
| time | Number | NO | メッセージのタイムスタンプ |

### 6. pad2readonly:$PADID

パッドIDから読み取り専用IDへのマッピング。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| (value) | String | NO | 対応する読み取り専用ID（r.で始まる16文字のランダム文字列） |

### 7. readonly2pad:$READONLYID

読み取り専用IDからパッドIDへのマッピング。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| (value) | String | NO | 対応するパッドID |

### 8. token2author:$TOKENID

トークンから著者IDへのマッピング。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| (value) | String | NO | 対応する著者ID |

### 9. mapper2author:$MAPPER

外部アプリケーション識別子から著者IDへのマッピング。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| (value) | String | NO | 対応する著者ID |

### 10. mapper2group:$MAPPER

外部アプリケーション識別子からグループIDへのマッピング。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| (value) | String | NO | 対応するグループID |

### 11. globalAuthor:$AUTHORID

著者の詳細情報を保持。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| colorId | Number/String | NO | 著者の色ID（パレットインデックスまたはHexカラー） |
| name | String | YES | 著者の表示名 |
| timestamp | Number | NO | 最終活動タイムスタンプ |
| padIDs | Object | YES | 著者が貢献したパッドIDをキーとするオブジェクト（値は常に1） |

### 12. session:$SESSIONID

セッション情報を保持。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| groupID | String | NO | セッションが属するグループID |
| authorID | String | NO | セッションが属する著者ID |
| validUntil | Number | NO | セッションの有効期限（UNIXタイムスタンプ） |

### 13. author2sessions:$AUTHORID

著者のセッション一覧を保持。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| sessionIDs | Object | NO | セッションIDをキーとするオブジェクト（値は常に1） |

### 14. group2sessions:$GROUPID

グループのセッション一覧を保持。

| カラム名 | データ型 | NULL | 説明 |
| --- | --- | --- | --- |
| sessionIDs | Object | NO | セッションIDをキーとするオブジェクト（値は常に1） |

## 備考

### データベースエンジン

EtherpadはUeberDB2を使用しており、以下のデータベースバックエンドをサポートしています：
- DirtyDB（開発用）
- PostgreSQL
- MySQL/MariaDB
- SQLite
- MongoDB
- Redis
- その他

### ID生成規則

| ID種別 | フォーマット | 例 |
| --- | --- | --- |
| 著者ID | `a.` + 16文字のランダム文字列 | `a.abc123def456ghij` |
| グループID | `g.` + 16文字のランダム文字列 | `g.xyz789uvw012stuv` |
| セッションID | `s.` + 16文字のランダム文字列 | `s.mnop345qrst678` |
| 読み取り専用ID | `r.` + 16文字のランダム文字列 | `r.efgh901ijkl234` |
| グループパッドID | `$GROUPID$` + パッド名 | `g.xyz789uvw012stuv$mypad` |

### キーリビジョン

リビジョン番号が100の倍数（0, 100, 200, ...）の場合、そのリビジョンは「キーリビジョン」として扱われ、属性プール（pool）と属性テキスト（atext）が追加で保存されます。これにより、任意のリビジョンへの効率的なアクセスが可能になります。

### データ整合性

- セッション削除時は、`session:$SESSIONID`レコード削除前に`group2sessions`と`author2sessions`が更新される
- グループ削除時は、関連するパッド、セッション、マッピングがすべて削除される
- パッド削除時は、関連するリビジョン、チャット、読み取り専用マッピング、著者との関連がすべて削除される
