Skip to main content.

Sunday, October 21, 2007

Ethnaで販売管理システムを部分的に開発してみる(その3)データベース関連

「Ethnaで販売管理システムを部分的に開発してみる」の続きです。今回はデータベース関連の要点と思われる項目についてです。データベースにはMySQLを使用していますので、そのMySQLとEthnaでの実装についてです。

MySQLのストレージエンジン
MySQLのストレージエンジンとして代表的なのが、「MyISAM」と「InnoDB」です。ストレージエンジンを指定せずにテーブルを作成するとMyISAMが選択されます。一方、InnoDBエンジンはトランザクション機能を提供するストレージエンジンとして有名です。

以上のように書きましたが、すいません、今まで意識したこともなかったです。実務でMySQLを使った時は既に設計されたものを使っていました。それで検索して調べてみると、単純には、参照処理が多い場合は「MyISAM」で、更新系処理が多い場合は「InnoDB」みたいな感じでしょうか。(実際にはそれ程単純でもないようですが、まだよく分かりません。)それで、今回はトランザクションと外部キー制約を使うという理由で、ログイン時に使うユーザテーブル(tuser)以外「InnoDB」にしました。(特にユーザテーブル(tuser)を「MyISAM」にした積極的な理由はないです。)販売管理システム等の業務系システムであれば、トランザクションと外部キーは普通に使って、また、長いSQL文を結構使うのが多いような気もします。そうすると、「InnoDB」を使うことが結構多くなるのではと単純に思いました。以下、「MyISAM」と「InnoDB」に関する関連リンクです。

パフォーマンス・チューニングBlog
Hatena::Diary::naoya MyISAM vs InnoDB
[ThinkIT]徹底比較!! MySQLエンジン 第2回:MyISAMとInnoDB

それから、今回、Windowsの開発環境では、xamppを利用したのですが、xamppでは、デフォルトでは、InnoDBが使えないようになっているようです。InnoDBを使う場合は、(xamppディレクトリ)\mysql\bin\my.cnfで、InnoDBの定義の部分(# Uncomment the following if you are using InnoDB tables の部分)のコメントをはずす必要があります。また、このmy.cnfですが、拡張子を表示するにしていていても、myのように拡張子が表示されない場合があるようです。これは、拡張子「cnf」が Windows のシステムで使用する「SpeedDial」に関連付けられているからです。エクスプローラの[ツール]メニュー[フォルダオプション]の「ファイル タイプ」タブから「CNF SpeedDial」の[詳細設定]で「常に拡張子を表示する」をチェックするとmy.cnfと表示されます。

EthnaからのDBアクセス
Ethna ではデフォルトではDBアクセスに PEAR::DB を利用します。その他、ADODB及び Creole の クラスが使えるようです。今回はデフォルトのPEAR::DBを使っています。この場合、開発マニュアルのデータベースアクセスの一番下の部分を見ると、「prepared statementなど、PEAR_DBの機能をフルに使うには、Ethna_DB_PEARクラスのメンバに直接アクセスする必要があります。」とのことです。今回のサンプルでもこのようにして、prepared statementを使っています。以下その例です。
/**
 *  Salesmgr_OrderManager
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Salesmgr
 */
class Salesmgr_OrderManager extends Ethna_AppManager
{
    //トランザクション開始
    function begin()
    {
        $db =& $this->backend->getDB();
            $db->db->autocommit(false); 
        $db->begin(); 

        return $db;
    }

    //受注データ登録
    function addOrder($db,$data)
    {
        //データ追加
        $sql = "insert into torder(orderDate,orderName,customer,tantou,kingakuGoukei,taxGoukei) values(?,?,?,?,?,?)";
            $stmt =& $db->db->prepare($sql);
        $res =& $db->db->execute($stmt, $data); 
    
        //エラーチェック(ここではPEARからエラーを取得)
        if(PEAR::isError($res)){
            
            //printf($res->getMessage());
            //printf("<br>");

            return -1;
        }
        
        //IDを取得(最新がここで追加したデータとして取得)
        $sql = "select max(orderId) as orderId from torder";
        $result =& $db->query($sql);
        $data = $result->fetchRow();

        return $data[0];
    }

    //受注明細データ登録
    function addMeisai($db, $orderId, $chkArr, $shohinArr, $numArr)
    {
        $sql = "insert into tordermeisai(orderId,lineNo,shohinCode,num) values(?,?,?,?)";
            $stmt =& $db->db->prepare($sql);

        $lineNo = 1;

        for($i=0; $i<ORDER_ITEM_NUM; $i++){
            if( strcmp($chkArr[$i], ORDER_CHECKED) == 0 ){
                $data = array($orderId,$lineNo,$shohinArr[$i],$numArr[$i]);
                $res =& $db->db->execute($stmt, $data); 

                //エラーチェック(ここではPEARからエラーを取得)
                if(PEAR::isError($res)){
                    return false;
                }
        
                $lineNo++;
            }
        }

        return true;
    }

    //
    //以下省略
    //


日本語の文字コード
Ethnaの日本語の内部コードはEUCです。今回、そのままEUCで使っています。そのため文字化け対策で、Ethna_DB_PEARクラスを継承したクラス Salesmgr_DB_PEAR.php を作成してそのクラスを使っています。文字化け対策は、その Salesmgr_DB_PEAR.php の connectメソッドで、接続後に"SET NAMES 'ujis'"を発行しています。
<?php

require_once 'Ethna/class/DB/Ethna_DB_PEAR.php';

//
// MySQLで文字化け防止を追加したEthna_DB_PEARクラス
// 

class Salesmgr_DB_PEAR extends Ethna_DB_PEAR
{
    function connect()
    {   
        $ret = parent::connect();
        if ($ret == 0) {
            $this->query("SET NAMES 'ujis'");
        }
        return $ret;
    }
}

?>

このクラスを利用するためには、コントローラにインクルードして、クラス定義に登録する必要があります。
  /**
  *  @var    array   クラス定義
  */
var $class = array(
    /*
     *  TODO: 設定クラス、ログクラス、SQLクラスをオーバーライド
     *  した場合は下記のクラス名を忘れずに変更してください
     */
    'class'         => 'Ethna_ClassFactory',
    'backend'       => 'Ethna_Backend',
    'config'        => 'Ethna_Config',
    'db'            => 'Salesmgr_DB_PEAR',
    'error'         => 'Ethna_ActionError',
    'form'          => 'Salesmgr_ActionForm',
    'i18n'          => 'Ethna_I18N',
    'logger'        => 'Ethna_Logger',
    'plugin'        => 'Ethna_Plugin',
    'session'       => 'Ethna_Session',
    'sql'           => 'Ethna_AppSQL',
    'view'          => 'Salesmgr_ViewClass',
    'renderer'      => 'Ethna_Renderer_Smarty',
    'url_handler'   => 'Salesmgr_UrlHandler',
);


以上がデータベース関連の要点と思われる項目についてです。

今回作成したプロジェクト一式は以下からダウンロードしてご覧いただけます。テーブルの定義は、schemaディレクトリにあります。
「Ethnaで販売管理システムを部分的に開発してみる」のプロジェクト一式

次は、マスタメンテ実装です。

当サイトでのEthna関連記事一覧


参考書籍
Ethna×PHP [LLフレームワークBooks] (LLフレームワークBOOKS # 2)
Ethna×PHP [LLフレームワークBooks] (LLフレームワークBOOKS # 2)
藤本 真樹一井 崇鶴岡 直也新井 啓太
技術評論社

¥ 1,980 (定価)
¥ 1,980 (Amazon価格)
19pt (Amazonポイント)
 (Amazonおすすめ度)
単行本(ソフトカバー)
通常24時間以内に発送
(価格・在庫状況は1月6日 13:22現在)


グラス片手にデータベース設計~販売管理システム編 (DBMagazine SELECTION)
グラス片手にデータベース設計~販売管理システム編 (DBMagazine SELECTION)
梅田 弘之
翔泳社

¥ 2,520 (定価)
¥ 2,520 (Amazon価格)
25pt (Amazonポイント)
★★★★☆ (Amazonおすすめ度)
単行本
通常24時間以内に発送
(価格・在庫状況は1月6日 13:22現在)