こんにちは!RSSでバックエンドの開発を行っているM.K.です。
本日は私が新卒1年目のときに、読みたくないViewの調査をAIチャットにお願いした話をしたいと思います。
このブログは以下のような方を対象としています。
- 古いシステムのクエリを読むことが大変だと感じている方
- ChatGPTでどのようなことができるのかを知りたい方
- 新卒1年目がどんなことをやっているか気になる方
Viewとは?
Viewとは、クエリの結果を1つのテーブル(仮想テーブル)として扱うことができるものです。
Viewを使用する主なメリットを2つ紹介します。
・セキュリティ強化
開発者に見せたくない情報がある際に、仮想テーブルを使う場合があります。
仮想テーブルはクエリの実行結果をテーブルとして扱うことが可能なため、同じテーブルに存在する個人情報など必要のない情報にアクセスされる心配がありません。
・コードがキレイになる
開発しているとクエリがどうしても長くなってしまうことがあります。
直接コードに記すと読みにくい場合があるため、取得するクエリをViewにし、コードには仮想テーブルから取得するという指示だけ書くことでコード上の可読性を上げることができます。
RSSでの生成AIの使用に関して
タイトルに書いてあるとおり、RSSでは生成AIを活用しています。
生成AIの活用にあたっては、主にセキュリティやコストに関して議論を交わしました。
特に、生成AIとして世界的に衝撃を与えたChatGPTが登場した当初は議論が活発でした。
主に「ChatGPTビジネス製品」と「APIを活用した自社開発AIチャット」の比較という構図で議論が展開されましたが、最終的にはコスト面で自社開発側に軍配が上がりました。
このような経緯を踏まえ、RSSではOpenAIのAPIを利用したAIチャットを開発・運用しています。
(なお、今回の記事で使用したキャプチャはすべて自社開発ツールの画面です。)
調査に使用したプロンプトとモデル
<調査の目的>
各Viewが使用しているテーブル・カラムを調査し影響範囲を可視化すること。
<使用モデル>
GPT-4o(検証日:2025/02/20)
<プロンプトの仕様>
事前にExcelにDB名とView名とViewのクエリをまとめたシートを用意しておきます。
取得方法はMySQLの場合、以下のクエリで取得可能です。
SELECT
TABLE_NAME AS view_name,
VIEW_DEFINITION AS view_query
FROM
INFORMATION_SCHEMA.VIEWS
WHERE
TABLE_SCHEMA = 'your_database_name';
入力:ExcelからDB名とView名とクエリをコピーし貼り付け(複数クエリ可)
出力:調査先ViewのDB名・調査先View名・DB名・テーブル名・カラム名
結果はExcelにコピペできる形式で出力されます。
<調査に使用したプロンプト>
プロンプトとは、生成AIにお願いする際の文言を指します。
データベース参照テーブル指示書
概要: SQLクエリで使用されているデータベース名とテーブル名を特定し、指定されたフォーマットに従ってEXCELに貼り付けても縦に並んで表示される形式でリストアップします。
指示書
入力
指定されたSQLクエリを入力します。このとき、クエリの前の2列にデータベース名とビュー名を以下のように記します
DB名 ビュー名 SQLクエリ
解析
クエリで使用されているデータベース名とテーブル名とカラム名を特定します。
出力形式
以下の形式で結果を出力します。EXCELに貼り付けた際に、正しく縦に並ぶようにします。
DB名 ビュー名 DB名 テーブル名1 カラム名
DB名 ビュー名 DB名 テーブル名2 カラム名
例:
指定されたSQLクエリ
test_DB test_view select id,name from `test_DB`.`user`
出力結果(タブ区切りで表示)
test_DB test_view test_DB user id
test_DB test_view test_DB user name
使用方法
以上の形式で、最初の2列にデータベース名とビュー名を書き、その次にSQLクエリを書きます。
クエリで参照しているデータベース名とテーブル名とカラム名を特定します。
特定したデータベース名とテーブル名を、指定されたフォーマット(タブ区切り)で縦に並べて出力します。
出力結果をコピーしてEXCELに貼り付けると、正しく縦に並びます。
具体的な指示例
入力例
test_DB test_view select id,name from `test_DB`.`user`
出力例(タブ区切り)
test_DB test_view test_DB user id
test_DB test_view test_DB user name
もう一つの例として、複数のテーブルを含むクエリ入力の場合
test_DB test_view select user.id,user.name,company.company_name from `test_DB`.`user` join `test_DB`.`company` on (`user`.`id` = `company`.`user_id`)
に対する出力例(タブ区切り)
test_DB test_view test_DB user id
test_DB test_view test_DB user name
test_DB test_view test_DB company company_name
この指示に従って、SQLクエリから参照しているテーブルを特定し、指定されたフォーマットで縦に並べて出力してください。
調査結果
調査結果の10クエリ分を表示します
| 使用テーブル数 | テーブルの一致率 | 使用カラム数 | カラム一致率 | |
| クエリ1 | 8 | 100% | 45 | 97.7% |
| クエリ2 | 9 | 100% | 40 | 92.5% |
| クエリ3 | 1 | 100% | 21 | 100% |
| クエリ4 | 2 | 100% | 13 | 100% |
| クエリ5 | 13 | 100% | 44 | 79.5% |
| クエリ6 | 1 | 100% | 115 | 100% |
| クエリ7 | 4 | 100% | 85 | 89.4% |
| クエリ8 | 2 | 100% | 9 | 100% |
| クエリ9 | 3 | 100% | 18 | 88.8% |
| クエリ10 | 2 | 100% | 73 | 82.1% |
実際に入力した値と、出力結果を表示します(テスト用の内容です)
入力内容
| rss_DB | tantou_view | select `rss_DB`.`user`.`ka` AS `ka`,`rss_DB`.`user`.`last_name` AS `last_name`,concat(ifnull(`rss_DB`.`user`.`last_name`,”),ifnull(`rss_DB`.`user`.`first_name`,”)) AS `name` from `rss_DB`.`user` where ((`rss_DB`.`user`.`ki` = 17) and (`rss_DB`.`user`.`q` = 1) and (`rss_DB`.`user`.`delete_flg` <> 1) and ((`rss_DB`.`user`.`last_name` is not null) or (`rss_DB`.`user`.`last_name` <> ”))) |
出力内容
rss_DB tantou_view rss_DB user ka
rss_DB tantou_view rss_DB user last_name
rss_DB tantou_view rss_DB user first_name
rss_DB tantou_view rss_DB user ki
rss_DB tantou_view rss_DB user q
rss_DB tantou_view rss_DB user delete_flg
調査所感
テーブルの正答率は100%であるため、テーブルの使用調査の信頼度は高いといえます。
カラムに関しては漏れが多いため、人力での再度確認が必要です。
しかし、自分で一つひとつみてカラム名をまとめるよりは格段に早く処理できました。
WHERE句にあるカラム名や、同じテーブルの取得を一箇所にまとめていないなどしていると
カラムの一致率が下がる傾向がある点には注意しましょう。
心配な方はカラムに関しては「抜け漏れない?」と再度聞くと「クエリ7・9・10」では一致率が100%になったので、常時一度抜け漏れがないかの確認をすると良いかと思います。
まとめ
今回はクエリの調査でしたが、現在は生成AIを用いてコーディングしています。
私はTypeScriptの型宣言などの決まった記述をするものに関してはAIに書かせています。
新卒1年目は調査やバグの修正など調べることばかりだと思います。
また、知らないことばかりで質問したいけど先輩が忙しそうで聞けないときなども
手伝ってくれる良きパートナーです。
皆さんもAIを活用して効率の良い開発をしていきましょう!
レイスシステムソリューションズ株式会社のソフトウェア開発や、
採用に関するお問い合わせについては、下記のリンクにてお問い合わせください。
-1.png)



