はじめに
以下2つの記事の続きです。
本記事では、DBのデータをメンテナンスするためのツールを開発した話を扱います。
ツールの概要
上記の手順で管理することにより、プログラミングの知識が全くない方でも、シナリオを変更できるようになりました。
また、担当者が改行を含むデータを扱いやすくするために、CSVファイルはExcelで編集する運用にしました。
作業環境
OS: Windows10
エディタ: Visual Studio Code、サクラエディタ、Excel(Microsoft365版)
ブラウザ: Microsoft Edge
DB: MariaDB 10.5.12
サーバOS: CentOS 7
Webサーバ: Apache 2.4
言語: PHP 7.4、JavaScript、HTML、CSS
工夫した点
セル内改行
チャットボット画面上で読みやすくなるよう、CSVファイル内の回答文には、改行を多く含めています。
Excelで編集する際には、セル内改行を使っています。
今回、この「改行をデータとして含むCSVレコード」の扱いにとても悩まされました。
CSVファイルを1レコードずつ読み込んで処理するようにしました。
しかし、セル内改行がレコードの終わりだと判定されてしまったため、うまくDBにINSERTできませんでした。
CSVファイルをサクラエディタで開くと、
このように、セル内改行はLF、次のレコードに飛ぶ際はCRLFを使っていることが分かりました。
そこで、
<?php
//■レコードの配列(改行区切り)
$rowArray = explode("\r\n", $csvData);
?>
このようにして、PHPのexplode関数を使用してCRLF区切りで分割することで、解決できました。
参考記事
【初心者向け】PHPで文字列を分割するexplode関数の使い方
CSVファイルに出力
<?php
//■ループしながら連想配列に代入
while ($dbData = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
//■アンシリアライズした結果を取得
$unserialize1 = unserialize($dbData['category'])[0];
if(count(unserialize($dbData['category'])) > 1) {
$unserialize2 = unserialize($dbData['category'])[1];
}
//■データ生成
$csvData .= ",{$dbData['question']},{$dbData['answer']},$unserialize1,$unserialize2\n";
//■アンシリアライズした結果をリセット(第2カテゴリがない項目があるため、unserialize2のみ)
$unserialize2 = '';
}
?>
上記コードはCSVファイルに出力させるためのスクリプトの一部になります。
DBの設計では、categoryカラムを1つしか用意していません。
そのため、1つの質問に対して、カテゴリが2つある(第一カテゴリと第二カテゴリ両方を持つ)CSVレコードをDBにINSERTする際には、PHPの関数、serializeを使用しています。
逆に、DBからCSVファイルへ出力する際には、シリアライズしたデータを元に戻す必要があるため、unserialize関数とcount関数を使用しています。
<?php
//■SQL文
$sql = "SELECT * FROM `{$TableName}` ORDER BY `value` ASC";
?>
valueカラムは、DBにINSERTされた順で連番が振られるようにしています。
そのため、SELECT文のソート条件に指定することで、前回DBにINSERTした順番通りにCSVファイルへ出力されるようにしました。
<?php
//■SQL文(テーブル初期化)
$sql = "TRUNCATE TABLE `{$TableName}`";
?>
また、DBにデータをINSERTする前に、TRUNCATE文を使用することで、全てのレコードを高速に削除し、書き換えています。
おわりに
最初に投稿した記事に載せたチャットボットと比べると、とても使い勝手のいいものが出来たと思いました。
しかし問題点はまだあり、レコード数が増えた場合など、管理をどのようにしていくかがこれからの課題になってくると思います。
最後まで読んでいただき、ありがとうございました