現行システムのカオスなテーブル設計を、生成AI（gemini）を使って正規化してみたい

# はじめに

例えば、、、、

最初は小さいシステムだったので、一つのテーブルに色んな情報を保持していました。
その後、そのシステムには複数回のバージョンアップが行われ、複雑な業務を行えるシステムに進化したとします。

そのアカウント情報管理テーブルが以下だったとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/f541e0d2-2b59-7372-5ff2-ee5eeae4ae7b.png)

もう少しわかりやすいように、DDLも張っておきます。

```DDL
CREATE TABLE accounts (
  account_id SERIAL PRIMARY KEY, -- PostgreSQLではSERIALを使用
  username VARCHAR(50) NOT NULL UNIQUE,
  email VARCHAR(100) NOT NULL UNIQUE,
  password VARCHAR(255) NOT NULL,
  name VARCHAR(100) NOT NULL,
  birth_date DATE,
  address TEXT,
  phone_number VARCHAR(20),
  role VARCHAR(50) NOT NULL,  -- 権限
  status VARCHAR(20) NOT NULL DEFAULT 'active',  -- 状態
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,

  -- 発送先情報1
  shipping_address1_postal_code VARCHAR(10),
  shipping_address1_prefecture VARCHAR(20),
  shipping_address1_city VARCHAR(50),
  shipping_address1_building VARCHAR(100),
  
  -- 発送先情報2
  shipping_address2_postal_code VARCHAR(10),
  shipping_address2_prefecture VARCHAR(20),
  shipping_address2_city VARCHAR(50),
  shipping_address2_building VARCHAR(100),
  
  -- 発送先情報3
  shipping_address3_postal_code VARCHAR(10),
  shipping_address3_prefecture VARCHAR(20),
  shipping_address3_city VARCHAR(50),
  shipping_address3_building VARCHAR(100),
  
  -- 組織情報1
  organization1_company VARCHAR(100),
  organization1_department VARCHAR(100),
  organization1_group VARCHAR(100),
  organization1_position VARCHAR(100),

  -- 組織情報2
  organization2_company VARCHAR(100),
  organization2_department VARCHAR(100),
  organization2_group VARCHAR(100),
  organization2_position VARCHAR(100),

  -- 組織情報3
  organization3_company VARCHAR(100),
  organization3_department VARCHAR(100),
  organization3_group VARCHAR(100),
  organization3_position VARCHAR(100),

  -- 組織情報4
  organization4_company VARCHAR(100),
  organization4_department VARCHAR(100),
  organization4_group VARCHAR(100),
  organization4_position VARCHAR(100),

  -- 組織情報5
  organization5_company VARCHAR(100),
  organization5_department VARCHAR(100),
  organization5_group VARCHAR(100),
  organization5_position VARCHAR(100),

  -- 部下アカウントID
  subordinate_id1 INT,
  subordinate_id2 INT,
  subordinate_id3 INT,
  subordinate_id4 INT,
  subordinate_id5 INT,
  subordinate_id6 INT,
  subordinate_id7 INT,
  subordinate_id8 INT,
  subordinate_id9 INT,
  subordinate_id10 INT
);
```

カオスですね。
ただ、この程度であれば、手動で正規化できますが、今回は生成AIに正規化の提案をしてもらおうと思います。


## テーブル設計書

テーブル設計書はA5:SQL Mk-2で作成しています。
手順が以下の方がわかりやすく説明してくださっています。

https://qiita.com/Esfahan/items/39509da435da4821cdc7

## 検証環境情報

・DB：PostgreSQL
・生成AIモデル：Gemini（1.5 Flash）

# やってみよう

## テーブル設計書（Excel）をインプットにしてみる

新たなツールの導入も許可されない、ただし生成AIに設計書を読み込ませることは許可がでた場合（知らんけど）、
Excelからテーブルの構造を生成AIに理解してもらい、テーブルの正規化を行ってもらいましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/33c91289-e3df-636e-0abc-d20ae1b076d5.png)

geminiはExcelが未対応でした。

## テーブル設計書（画像）をインプットにしてみる

執筆時点、画像なら大体の生成AIが対応していっているので、力技ですが、
テーブル設計書をキャプチャして読み込ませてみます。
読み込ませたキャプチャは、上記で張ったものと同じです。

:::note info
何度か同じ質問をしてみたんですが、その時により回答が異なります。
テーブル構造の問題点を列挙してくれたり、正規化の必要性を問うてくれる時もあります。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/95a172b6-8d95-0f85-11c3-2bc288308f30.png)

### ER図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/47ec2d74-f6c3-e075-1c14-7bd74ccb2f8b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/30b1a960-b044-2427-27d1-d5693c3bf192.png)

geminiはER図未対応でした。

### DDL

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/f49754b0-b494-1133-da0b-4d9bedc31215.png)

「account_id」だったキーが「user_id」に変更されています。これは既存システムへの影響が大きそうなので、やめてほしいと思いました。
テーブル名については、移行時に新旧テーブルを同居させることでデータ送信しやすい設計にしたのでしょうか・・

あと部下を勝手に下請けにしないでください・・

また今回はポスグレで検証を行ったんですが、「group」が予約語で使用できませんでした。（あれじゃあ何で登録できたんだ？）
ただ、これはDB情報を渡さなかった私が悪いので、見逃します。

https://www.postgresql.jp/docs/9.4/sql-keywords-appendix.html

### テーブル設計書

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/e68b9e34-e56b-0623-ecf9-5de5cf77b481.png)

何度かやってみたんですが、たまに省略されてしまいます。

## DDLをインプットにしてみる

今回は稼働中の既存システムを想定いており、さらにDDLが存在しないという現場だとして、
A5ツールでDDLを出力させて、それをインプットとしたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/426f7922-1f6c-ab3f-2009-2ddc3b86cb24.png)

画像を読み込ませたときと大枠同じですが、テーブル名をオリジナルのままにしてくれたり、
従属者情報としてくれたりしましたが、大枠画像と同じ出力でした。

画像解析能力の高さがうかがえますね。

# まとめ

ここには記載していない細かい気になる点があったのですが、
そこは手で修正すればいいので、おおわくは良しとします。

一から手直しするより正規化を理解したたたき台が作成できるので、よかったのではないでしょうか。

# 余談

基のテーブルのDDLもGeminiを使って作成しました。

冗長構造の情報を五月雨に追加してもらっていましたが、
この超冗長化構造を受け入れてもらえず、何度も説得しましたが、追加してくれませんでした。

最終的には、新規チャットを作成して、追加後のDDLに対して「この情報を追加してください」と都度依頼して追加してもらいました。（手で追加した方が早かったかも）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/201649da-c9b4-3e73-7f72-eb6870bc246c.png)