baserCMS 固定ページやブログ記事のデータ量(文字数)制限のはなし。

- 2024/10/17 追記
主にデータベース側のデータ量(文字数)制限の事情について整理しました。baserCMSでサイト運用をしていると、「本稿欄に保存できるデータ量を超えています。」などのバリデーションエラーが表示されて、記事やページの保存ができない。。。といったことに遭遇する時があります。
これは、baserCMSコア内で設定されているデータ量(文字数)の64KB制限によるものですが、一方でbaserCMSで利用できるデータベース側でも、データ量(文字数)を制限する設定はあって、その辺りの事情がわからないと対応に苦戦することになります。
というわけで、今回は、掲題のとおり、データ量(文字数)制限のおはなしです。
baserCMSコア内で設定されているデータ量(文字数)制限回避策については、後述するとして、ひとまずデータベース側のデータ量(文字数)制限の事情について整理してみたいと思います。
baserCMSでは、データベース側はMySQL、PostgreSQL、SQLiteの3種類のSQLのいずれかを利用できる仕様になっています。その内のPostgreSQLは、初心者がホスティングサーバーを利用するケースで、ほぼ候補には上がらないと思いますので、ここでは、MySQL、SQLiteのいずれかを対象として話しを進めたいと思います。
まず、MySQLの場合。データ量(文字数)制限の対象となるpagesやblogpostsテーブルの本文入力欄に該当するフィールドのデータ型は、2系から3系まではtext型(65,535バイト)だったように記憶しています。当時私が運用していた3系のサイトをDBマイグレーターで4系に移行した際、必要に駆られてtext型をmediumtextに変更した経緯があったので、てっきり4系でもそのままtext型だと思いこんでいたところ、実はbaserCMS4系自体は、リリース当初からどうもmediumtext型(16,777,215バイト)だったようで、それが、またまた知らないうちにlongtext型(4,294,967,295バイト)になっていた。。。という事実をつい先日知りました。
text型だと思ってしまう理由は他にもあって、先にお話ししたbaserCMSコア内で設定されているデータ量(文字数)の制限が3系(2系は定かで無い)の頃から64KB上限でかかっていたからで、それはDB側の該当フィールドがtext型だから、その許容量(データ量)をバリデーションチェックとしてユーザー側に示すという意味合いで64KB制限が行われているんだと勝手に思い込んでいた訳です。
しかし実際は、MySQLの当該フィールドのデータ型はmediumtextやlongtextに変わっていて、データベースに格納できるデータ量は増えているにもかかわらず、baserCMSコア内で設定されているデータ量(文字数)制限は依然として64KB制限となっていて、意味がありません。
となると、なぜに今もってbaserCMSコア内で設定されているデータ量(文字数)の制限が64KB上限でかかっているのか?疑問ではありますが、ここではひとまず置いておきましょう。
次にSQLiteの場合。上述した本文入力欄に該当するフィールドはBLOB型で、その最大長は1GBのサイズだそうで、今回のデータ量(文字数)の制限を回避するために特に必要な対応はない十分に大きなデータ量と言えます。
ここで、これまでに話にのぼったデータサイズをレイアウト用のHTMLタグや改行コードなどの容量をまったく考慮せず、日本語(2バイト文字※UTF-8の場合、最大3〜4バイト)の文字数にざっくりと置き直(3バイトで計算)してみると、
64KB → 2.1万文字
text型(64KB) → 2.1万文字
mediumtext型(16MB) → 5.3万文字
longtext型(4GB) → 13.3億文字
BLOB型(1GB) → 3.3億文字
ということになります。
現実的には、よほどの巨大なリストや論文などを固定ページやブログ記事として扱わない限り、mediumtext型(16MB)を超える容量が必要になることはないと思います。
というわけで、少なくともbaserCMS4系の最新版を利用している限り、データベースに格納可能な文字数(データ量)の制限値は、MySQL、SQLiteのいずれにおいても億単位の文字数相当であり、データベース側で問題が生じることは、ほぼ無いということになります。
あとは、baserCMS4系(Cake2系)最新版コア内のCakeSchemaでインストールされたMySQL(あるいはSQLite)であれば、baserCMSコア内の「64KBの文字数制限」さえ、運用上必要なサイズに大きくすれば、事実上の文字制限は回避できることになります。
「64KBのデータ量(文字数)制限」回避策
さて、ここでやっと「64KBのデータ量(文字数)制限」回避策の話です。
baserCMSコア内で設定されているデータ制限を大きな値に変更したい場合、以下のコアファイルを変更することになります。また、対象ファイルも固定ページとブログ記事でそれぞれ違います。
対象ファイルと対象箇所は以下。
固定ページの場合は、/lib/Baser/Model/Page.php
ブログ記事の場合は、/lib/Baser/Plugin/Blog/Model/BlogPost.php
ただ、いずれもコアファイルですので、baserCMSをバージョンアップすると上書きされてしまい、元の「64KBのデータ量(文字数)制限」に戻ってしまうので、注意が必要です。
ついでにプラグイン化
そこで、baserCMSをバージョンアップで上書きされてしまわない対策として、プラグイン化してみました。
CharacterLimitChange/Event/CharacterLimitChangeModelEventListener.phpを以下のように作成。
<?php
class CharacterLimitChangeModelEventListener extends BcModelEventListener {
/**
* 登録イベント
*
* @var array
*/
public $events = [
'Blog.BlogPost.beforeValidate',
'Page.beforeValidate',
];
public function blogBlogPostBeforeValidate(CakeEvent $event)
{
$Model = $event->subject();
// ブログ記事本文の本稿および草稿欄のデータ量制限を変更する
$Model->validate['detail'][0]['rule'][1] = 256000; // 本稿欄のデータ量。デフォルト値:64000バイトを →(例:128000 256000 512000)
$Model->validate['detail_draft'][0]['rule'][1] = 256000; // 草稿欄のデータ量。
}
public function pageBeforeValidate(CakeEvent $event)
{
$Model = $event->subject();
// 固定ページの本稿および草稿欄のデータ量制限を変更する
$Model->validate['contents'][1]['rule'][1] = 256000; // 本稿欄のデータ量。
$Model->validate['draft'][1]['rule'][1] = 256000; // 草稿欄のデータ量。
}
}
上記ファイルの制限値を64000バイトから128000、256000、512000バイトなど、必要で無理のないサイズに引き上げることで容量制限を回避します。(私見ですが、よほど特殊なサイトでない限り、512000バイトを越えることはないと思います。)
次に、CharacterLimitChange/config.phpとして、以下を作成。
<?php
/**
* [ADMIN] CharacterLimitChange
*/
$title = 'データ量制限変更';
$description = '固定ページ、ブログ記事本文の本稿および草稿欄のデータ量(文字数)制限を変更する';
$author = '';
$url = '';
これらのファイルを以下のように「CharacterLimitChange」フォルダ内に配置し、app/Plugin/CharacterLimitChange/としてアップロードする。 あとは、通常のプラグインと同様にインストール、有効化、操作を管理画面から行う感じです。 データ量(文字数)の制限でお困りの方、よかったら試してみてください。