複数店舗の在庫管理に悩む企業向けに、WordPressマルチサイトとカスタムテーブルを使った一括管理システムの構築方法を実案件をもとに詳しく解説します。
こんな悩み、ありませんか?
「3店舗目がオープンしたけど、在庫管理がバラバラで大変…」「A店の商品がB店にもあるはずなのに、いちいち電話で確認するのは面倒」「お客さんに『他店舗の在庫を確認します』と言って待たせるのが申し訳ない」
先日、神奈川県内で飲食店を3店舗展開するクライアント様から、まさにこのような相談をいただきました。各店舗で独立してWordPressサイトを運営していたものの、店舗間の在庫情報共有がうまくいかず、機会損失が発生していたのです。
もしあなたも複数店舗やブランドの在庫管理で困っているなら、この記事は3分で読む価値があります。WordPressマルチサイト機能を活用した一元管理システムの実装方法を、実際の案件をもとに具体的にお伝えします。
なぜ複数店舗の在庫管理は混乱するのか
典型的な問題パターン
多くの企業が陥る在庫管理の問題には、共通するパターンがあります。まず、各店舗が独立したシステムを使っているケース。ExcelやGoogleスプレッドシート、あるいは個別のWordPressサイトで管理していると、リアルタイムでの情報共有ができません。
次に、手動更新による情報の古さです。A店で商品が売れても、B店のシステムに反映されるまでにタイムラグが発生。結果として、存在しない在庫を顧客に案内してしまう事態が起きてしまいます。
機会損失の実態
前述のクライアント様の場合、月に約15件の「他店舗確認後の再連絡」が発生していました。このうち約30%のお客様が、待ち時間を嫌って他社に流れていたのです。単純計算で月4〜5件の機会損失が生まれていました。
システム分散によるコスト増
各店舗で別々のシステムを使っていると、保守・運用コストも分散します。WordPress サイトが3つあれば、セキュリティアップデート、プラグイン管理、バックアップも3倍。人的コストだけでなく、サーバー費用やライセンス料も無駄になりがちです。
WordPressマルチサイトによる解決アプローチ
マルチサイトアーキテクチャの選択理由
WordPressマルチサイト機能を選んだ理由は、以下の3点です:
- 既存WordPressサイトからの移行コストの低さ
- 共通データベースによる在庫情報の一元化
- 各店舗の独自性を保ちながらの統合管理
単一のWordPressインストールで複数サイトを管理できるため、データベースレベルでの連携が容易になります。
システム構成の全体像
flowchart TD
A[メインサイト<br/>管理画面] --> B[共通在庫テーブル]
B --> C[店舗A サイト]
B --> D[店舗B サイト]
B --> E[店舗C サイト]
F[在庫更新API] --> B
C --> G[顧客A]
D --> H[顧客B]
E --> I[顧客C]実装手順
1. マルチサイト環境の構築
まず、既存のWordPressサイトをマルチサイト化します。wp-config.phpに以下の設定を追加:
// マルチサイト有効化
define('WP_ALLOW_MULTISITE', true);
// ネットワーク設定(サブドメイン方式)
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true);
define('DOMAIN_CURRENT_SITE', 'example.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
2. 共通在庫管理テーブルの作成
各サイトからアクセス可能な共通テーブルを作成します:
// functions.phpまたは専用プラグイン内
function create_inventory_table() {
global $wpdb;
$table_name = $wpdb->base_prefix . 'inventory_shared';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
product_id varchar(100) NOT NULL,
product_name text NOT NULL,
store_id mediumint(9) NOT NULL,
stock_quantity int(11) NOT NULL DEFAULT 0,
last_updated datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY product_store (product_id, store_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
3. 在庫管理APIの実装
REST API を使って各サイトから在庫情報を更新・取得できるようにします:
// 在庫取得API
add_action('rest_api_init', function () {
register_rest_route('inventory/v1', '/stock/(?P<product_id>[a-zA-Z0-9-]+)', [
'methods' => 'GET',
'callback' => 'get_stock_info',
'permission_callback' => '__return_true',
'args' => [
'product_id' => [
'validate_callback' => function($param, $request, $key) {
return is_string($param);
}
]
]
]);
});
function get_stock_info($request) {
global $wpdb;
$table_name = $wpdb->base_prefix . 'inventory_shared';
$product_id = $request['product_id'];
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT store_id, stock_quantity, last_updated FROM $table_name WHERE product_id = %s",
$product_id
)
);
if (empty($results)) {
return new WP_Error('no_stock', '在庫情報が見つかりません', ['status' => 404]);
}
return rest_ensure_response($results);
}
4. フロントエンド表示の実装
ショートコードを使って、各店舗サイトで他店舗在庫も表示できるようにします:
// ショートコード登録
add_shortcode('multi_store_stock', 'display_multi_store_stock');
function display_multi_store_stock($atts) {
$atts = shortcode_atts([
'product_id' => '',
'current_store' => get_current_blog_id()
], $atts);
if (empty($atts['product_id'])) {
return '<p>商品IDが指定されていません。</p>';
}
global $wpdb;
$table_name = $wpdb->base_prefix . 'inventory_shared';
$stocks = $wpdb->get_results(
$wpdb->prepare(
"SELECT s.store_id, s.stock_quantity, b.domain
FROM $table_name s
LEFT JOIN {$wpdb->base_prefix}blogs b ON s.store_id = b.blog_id
WHERE s.product_id = %s AND s.stock_quantity > 0",
$atts['product_id']
)
);
$output = '<div class="multi-store-stock">';
$output .= '<h4>店舗別在庫状況</h4>';
foreach ($stocks as $stock) {
$store_name = get_store_name($stock->store_id);
$is_current = ($stock->store_id == $atts['current_store']);
$class = $is_current ? 'current-store' : 'other-store';
$output .= sprintf(
'<div class="stock-item %s"><span class="store">%s</span>: <span class="quantity">%d個</span></div>',
$class,
$store_name,
$stock->stock_quantity
);
}
$output .= '</div>';
return $output;
}
導入効果の測定
実装から3ヶ月後の効果を測定したところ、以下の改善が見られました:
よくある失敗パターンと対処法
失敗パターン1: パフォーマンスの劣化
問題: 複数サイトが同一データベースにアクセスすることで、サイト表示速度が低下。
対処法:
- Redis や Memcached によるキャッシュ層の導入
- 在庫情報の定期取得(リアルタイム更新の見直し)
- データベースインデックスの最適化
// キャッシュ機能付きの在庫取得
function get_cached_stock_info($product_id) {
$cache_key = "stock_info_" . $product_id;
$cached = wp_cache_get($cache_key, 'inventory');
if ($cached !== false) {
return $cached;
}
$stock_info = get_stock_from_database($product_id);
wp_cache_set($cache_key, $stock_info, 'inventory', 300); // 5分間キャッシュ
return $stock_info;
}
失敗パターン2: 権限管理の複雑化
問題: 各店舗のスタッフが他店舗の在庫を誤って編集してしまう。
対処法:
- カスタム権限の細かい設定
- 編集権限は自店舗のみ、閲覧権限は全店舗に
- 操作ログの記録
// 店舗別編集権限の制御
function restrict_inventory_edit_by_store($user_id, $product_id) {
$user_store = get_user_meta($user_id, 'assigned_store', true);
$current_site = get_current_blog_id();
if ($user_store != $current_site && !user_can($user_id, 'manage_network')) {
wp_die('他店舗の在庫は編集できません。');
}
}
失敗パターン3: データ同期のタイムラグ
問題: 在庫更新が各サイトに反映されるまでに時間がかかる。
対処法:
- WebSocketやServer-Sent Eventsによるリアルタイム通知
- 在庫更新時の即座なキャッシュクリア
- フロントエンドでのAjax自動更新
失敗パターン4: 運用ルールの未整備
実装は成功したものの、運用段階で混乱が生じるケースがよくあります。「どのタイミングで在庫を更新するか」「在庫ゼロの商品はいつ非表示にするか」といったルールが曖昧だと、結局手動での調整が必要になってしまいます。
対処法:
- 在庫管理マニュアルの作成
- スタッフ向けの操作研修の実施
- 定期的な運用見直しミーティングの設定
サイトの改善、プロに任せませんか?
WordPress制作・リニューアル
更新しやすく、集客につながるサイトを構築します
※ 通常1営業日以内にご返信します
まとめ:次のステップ
WordPressマルチサイトを使った複数店舗在庫管理システムは、適切に実装すれば大幅な業務効率化を実現できます。ポイントは技術的な実装だけでなく、運用面での準備も含めた総合的なアプローチです。
導入を成功させる3つの条件
- 段階的な実装: いきなり全店舗で開始せず、2店舗間での小規模テストから始める
- 運用ルールの事前策定: 技術的な機能だけでなく、人的オペレーションの整備が重要
- 継続的な改善体制: 導入後の課題に対応できる体制作り
今回ご紹介したシステムを導入したクライアント様は、3ヶ月で月間売上が約12%向上しました。在庫の見える化により機会損失が減り、スタッフの業務効率も大幅に改善されたからです。
もし「自社でも同様のシステムを導入したいが、技術的な部分が不安」という場合は、ぜひ一度ご相談ください。Fivenine Designでは、20年以上のWeb制作実績を活かし、お客様の業務に最適化されたシステム開発をサポートしています。まずは現状の課題整理から始めて、最適な解決策をご提案いたします。