ラベル MySQL の投稿を表示しています。 すべての投稿を表示
ラベル MySQL の投稿を表示しています。 すべての投稿を表示

2017-06-02

大容量のSQLテーブルもOK! ― FileMaker 16 を帳票作成ツールとして使う

 FileMaker Server 16 (以下、FMS16)ではPDF出力をサポートするようになりました。FileMaker Pro はもともと帳票/レポートを簡単に作成できるツールして利用されてきましたが、サーバサイドでPDFが作成できるようになり、面倒なWeb帳票の設計・実装が実に簡単、且つ短時間のうちに行えるようになりました。 データベースは FileMaker でも SQL/XMLデータベースでもOKです。 本稿では MySQL の1500万件のテーブルからデータを抽出し、遅延無くPDFを出力する方法の概要を記します。

開発・運用環境

FileMaker Pro (Advanced) 16 ― 帳票作成ツール*1
FileMaker Server 16/IIS/PHP ― サーバ*2

 *1 帳票を作り、簡単なスクリプトを書くだけであればFileMaker Pro 16(¥4万前後)で事足りますが、複雑なスクリプトを書くには開発用(デバッガ付)の FileMaker Pro Advanced (¥7万前後)が必要です。
 *2 FileMaker Server 16 はFM社直売で¥99,000 (税抜)です。

 FileMaker Server 16 (の カスタムWeb公開 =CWP)の理論上の最大接続数は 2,000、検証接続数は500 ですので(詳細はこちら)、¥20万弱で本格的な帳票開発・運用環境が構築できる可能性があります。

本稿の目的と概要図

Webブラウザ上でから 入出庫システム(バックエンドはMySQL)にアクセスし、入庫伝票をPDF形式で作成・表示することを目的とします。 帳票を構成するテーブルに1000万件単位レコードが存在する場合にも、ユーザにストレスを与えない程度の実行速度で、入庫伝票PDFを表示することも目指します。以下が実装手法の概要図となります。



実装手法

入出庫明細テーブルには 約1500万のレコードがあります。 FileMaker で数十万件を超すテーブルからデータを抽出してPDF帳票を遅延無く作成するには、上図の FMS ⇔ MySQL 間の設計がキモとなります。今回は一般的な FileMaker ESS(External SQL Source 機能)を使う手法 と、原始的な ODBC データ取込を使う2つの手法を実装・テストしました。

実装手法1 ―  FileMaker ESS を使用  データ件数が多くなると低速化する

  1. 本手法では ESS を使用し、MySQLのテーブルを FileMaker のファイル内に直接配置します。下図の「_入庫」や「_取引先_入庫」などがそれに相当し、これらはシャドウテーブルとも呼ばれます。
    ESSは FileMaker 内から直接 MySQL のテーブルを読み書きでき便利なのですが、数十万行を超す大きなテーブルを扱う時には速度が低下するなどの問題があります。ESSの問題点については、古い記事になりますがこちらを参考にしてください。

  1. 入庫伝票レイアウトの開発は FileMaker Pro (Advanced) のGUIを利用し、テーブル内のフィールドや罫線、テキストなどのオブジェクトを配置しながら作成すると、慣れた人なら 短時間で完成すると思います。  
FileMaker Pro により作成した入庫伝票イメージ

  1. 次に FileMaker のスクリプトメーカーで、PHP から渡ってきた入庫No による検索、入庫伝票レイアウトの選択、PDF保存などを行うスクリプト(「実装手法概要図」の「特定のスクリプト」)を作成します。
  2. 最後に PHPファイルからそのスクリプトを実行するように指定します。

実装手法2 ― ODBCデータ取込 を使用 データ件数にかかわらず高速

  1. 本手法では独立した FileMaker ファイルを一つ用意し、その中に FileMaker のテーブル(vw入庫伝票、下図参照)を用意します。

    このテーブルに MySQL から必要最低限のデータを取り込み、そのデータを FileMaker レイアウトを使用してPDF形式で出力します。

    注:ESS は使用せず、したがって MySQL のシャドウテーブルも配置しません。
  2. MySQL側に入庫伝票に必要なテーブル(本例では、入出庫明細、取引先、入庫、商品の4テーブル)を結合した入庫伝票用ビューを作成します。

    ビューの作成は必須ではありませんが、ビューが無いとFileMaker内に4つのテーブルを用意し、4回SELECTクエリを発行して用意したテーブルに対応するMySQLのテーブルデータを取り込む必要があります。ビューを使用すれば、テーブル、クエリー、取込とも1つ/1回で済むので、実行速度的にも有利です。特別な事情がなければ、ビューを使用しましょう。

  3. FileMaker を使用して入庫伝票レイアウトの作成します。テーブル構成が異なるので実装手法1とはその作成方法は異なりますが、FM開発者にとっては容易な作業と思います。
  4. 次にPHPから渡ってきた 入庫No を使用し、 ビューに対して SELCTクエリーを発行し、結果を vw入庫伝票テーブルに取り込み、入庫伝票レイアウトを選択して、PDFを保存するスクリプトを作成します。
  5. PHPからこの FileMaker スクリプトを実行して、PDFを作成・表示する部分は実行手法1と同様です。

テスト結果

上記2つの手法による実装をブラウザからテストしてみました。HTTPリクエストからPDFが表示されるまでの時間は以下の通りです(テストは各5回ずつ実行し、その平均値を記載しています)。

実装手法1: 77秒
実装手法2: 1.2秒 

 その差は圧倒的でした。シャドウテーブルを配置するESSは、SQLクエリーの発行を FileMaker がすべてやってくれるので便利な反面、膨大なクエリーを発行するため速度低下を招きます。 その点、 ファイル内にESSシャドウテーブルを配置せず、SQL SELECT文を自身で指定し、その結果を FileMaker テーブルに取り込む ODBCデータ取込は大きなSQLテーブルに対しては圧倒的に有利です。

思ったこと

実装手法2であれば、数千万件のデータを持つSQLデータベースの帳票作成環境として、その使用に耐えそうです。 実装手法1は10万~20万件程度のテーブルであれば利用可能と思われます。

本稿では SQLデータベースを取り上げましたが、旧FileMaker Server の Webシステムを温存しつつ、下図のように FMS16 を併行運用し、FMS 16 は PDF出力用サーバとして使用する方法も考えられます。

PDF出力をしたいが、 FM16へのアップグレードはできない場合、検討の価値はあるかと思います。





(土屋)




2017-06-01

MySQL ODBC ドライバインストール時のエラー1918

Windows 2012/2016 にMySQLのODBCドライバ5.3.8をインストールしようとすると、
Error 1918.Error installing ODBC  driver MySQL ODBC 5.3 ANSI Driver...
というエラーが表示される。
対策はVC++ラインタイムをインストールすることだが、Windows のバージョンによって、インストールするバージョンが違うらしい。

Windows Server 2012 の場合→VC++2010ランタイム

Windows Server 2016 の場合→VC++2013ランタイム


参考サイト:


(土屋)

2015-02-04

MySQL 5.1 から 5.6 にデータベースを移行する際、source コマンドを使うとエラーが発生することがある

MySQL 5.1 のデータベースのバックアップを取り、別のサーバ機の MySQL 5.6 にインストールする際、source コマンドを使ってデータベースの復元を行うと、以下のようなエラーが発生することがあります。

ERROR 1146 (42S02): Table 'test.蜃コ蠎ォ' doesn't exist

この文字化けしたテーブル名は日本語表記になっており、データベースの文字コードは utf8 です。

このような場合は、source コマンドの代わりに  mysql コマンドでデータベースの復旧を試みると解決することがあります。


例:
mysql -uroot -ppassword  < test.sql


【注意点】

mysql コマンドを使って大規模データベースを復旧する際、以下のようなエラーが発生して処理が停止してしまうことがあります。

MySQL server has gone away.

これを回避するには、 my.ini(my.conf) の max_allowed_packet の数値を増やします。

max_allowed_packet = 64M
(デフォルトは 4M)


2015-02-03

Big Table Handling Model in FileMaker/MySQL Environment ― Tentative one


The ordinary FileMaker development model may be not effective for handling big SQL tables.
In this post, we will try to find out clues for handling big tables at a tolerable speed while avoiding the weird application behavior that is unique to SQL big tables.

Definition of terms

Big tables: MySQL tables with more than 10 mil. rows
FileMaker/MySQL development: development using FileMaker for frontend, MySQL for backend
Filemaker-alone development: development using FileMaker for both frontend and backend

Problems of FileMaker's common interface

FileMaker provides the common interface for both FileMaker-alone development and FileMaker/MySQL development, which make it possible that developers can use the almost same method in FileMaker/MySQL development as in FileMaker-alone development.

This is very nice, but as data of MySQL tables grow up, application users will notice a performance slowdown, the application's behavior will become so weird (FileMaker issues a lot of redundant and incomprehensible SQL queries), and operation may become almost impossible.

The following model is a tentative one for mitigating such problems:


Big Table handling model in FileMaker/MySQL Environment

The figure below illustrates how to handle database objects.
.


  1. On MySQL, duplicate big tables and rename them as rpl_originalTableName which are used for replicating records SELECTed by users from original big tables.
  2. In FileMaker relationship graph, place only small tables and Rpl. Tables (do NOT place any big tables as it causes slowdown).
  3.  Create stored procedures in MySQL to SELECT records in big tables and replicate them to Rpl. Tables, and INSERT/DELETE/UPDATE them whenever related records in Rpl.Table are inserted, deleted or updated. The stored procedures are executed from FileMaker's layout.

Common Model vs Big Table Handling Model

The following table indicates the comparison of the common model which is commonly used in FileMaker application development and the Big Table Handling Model(BTHM) based on the figure above.


Common Model BTHM Remarks
Fast development Yes No
Ease of operation Good No so good
Performance for big tables Very poor Good
Weird behaviors Many Minimum
Records order Weird OK Maybe detailed later

Note:
BTHM may not be appropriate for the found set of over 0.1 million, and may not be appropriate for the large number of simultaneous users.



The above two models plus 1 are illustrated in the following video.





N. Tsuchiya

2014-12-04

『FMEasy在庫』 のバックエンドを MySQL に変える(2) ― 在庫


 本稿では、リリース予定の『FMEasy在庫 on MySQL R1.5』(仮称)の商品画面の在庫に関して説明いたします。

 以下が商品画面となります。



 『FMEasy在庫 on MySQL R1.5』では、2つの方法で在庫を算出します。
 一つは「SQL Update方式」、もう一つは「FM計算方式」です。

 それではそれぞれに関して説明します。

SQL Update方式

※特徴
 この方式は“実行”ボタンをクリックすることにより、[在庫基準日]時点の全商品の在庫数を算出して記録します(技術仕様的には、入庫数計/出庫数計/在庫数を「upd在庫」という専用テーブルに記録します)。

 一旦記録されたデータは次に“実行”ボタンを実行するまで更新されません。
したがって、“実行”ボタンクリック時点には最新情報ですが、時間が経過するに従い、最新の在庫数とは異なる可能性が高くなります。

 “実行”ボタンクリック時に入出庫データが大量にある場合、処理に数秒~数十秒、1千万件を超えるような場合は数分かかる可能性がありますが、処理が終了してしまえば即座に数値を表示・印刷できます。
 「SQL Update方式」は、在庫表などで在庫情報をリスト形式で表示・印刷する場合、高速に処理することができます。

注:
 本機能はクライアント/サーバ環境に置いて、FileMaker ServerにODBC設定がされていれば、FileMakerクライアントにはODBCのインストール/設定は不要です。

※操作方法
 実行ボタン ― 任意の[在庫基準日]を指定して本ボタンを実行すると、[在庫基準日]時点の入庫数/出庫数/在庫数が算出・記録されます。

 当方のクライアント/サーバ環境下で、入出明細レコード170万件に対してこの処理を実行すると、30秒~1分程度の時間を要します。

 作成済在庫データ選択ウインドウ(FileMaker 13使用時のみ) ― 実行ボタン右横の黄色の部分をクリックすると、小さなウインドウ(下図)が表示されます。この時、プルダウンメニューをクリックすると、他のユーザ(アカウント)が作成した在庫データの一覧が表示されるので、ここでその内の一つを選択すると、以後、「SQL Update方式」には選択したアカウントが作成した在庫データが表示されます。

他のアカウント(admin/seminar/stockchecker)が作成した在庫データを照会できる。
アカウント右側の日付は、データ作成時に指定した[在庫基準日]



注:
 各ユーザ(アカウント)は[在庫基準日]を指定して“更新”ボタンを実行することにより、全商品の在庫データを作成・記録できます。
同アカウントが次に“更新”ボタンを実行すると、前回作成した在庫データは上書きされます。例えば、admin アカウント で[在庫基準日]に「2014/11/27」と指定して本ボタンを実行すると、全商品に対して[在庫基準日]時点の在庫データが作成されますが、次に adminアカウントが「2015/12/31」を指定して同操作を実行すると、「2014/11/27」時点のデータは上書きされます。

 尚、他のアカウントが作成した在庫データは上述の通り照会することはできますが、別のアカウントで上書きすることはできません。例えば、adminアカウントでログインしている場合、seminar が作成した在庫データの照会はできても、上書きすることはできません。

FM計算方式

※特徴
 この方式は旧来のFileMakerの計算式を使用した在庫算出方法(参考記事)です。この方法のメリットは、常時最新の在庫情報を表示される点です(下記注参照)。

 ディメリットは、入出庫明細にデータが多量にある場合、在庫情報の表示に時間がかかることがある点です。 例えば、入出明細レコードが170万件あり商品Aを含むレコードがその中に2万9千件ある場合、当方の低SPECなクライアント/サーバ環境下では商品Aの[在庫数]を算出するのに5秒強程かかります。

 商品画面で個々の商品情報を一つ一つ計算・表示する場合はまだいいのですが、複数の商品の[在庫数]をリスト形式で表示する場合はかなりのストレスを感じます。

注:
 ネットワーク上の他ユーザが照会中の商品の入出庫データを追加・更新した場合、“画面更新”をクリックすると、最新の在庫情報が表示されます。

※操作方法
 計算するチェックボックス ― チェックすると「FM計算方式」の在庫情報が表示されます。チェックを外すと在庫情報の計算を行わないので、画面表示が高速になります。

 尚、「FM計算方式」の出庫数計/入庫数計/在庫数のフィールドをレイアウト上に配置するだけで、システム起動後に初めて商品レイアウトを開く際に時間がかかります。
入出明細に170万件のレコードがある場合、当方の環境下では、1分前後の時間を要します。

 この詳しい理由については割愛しますが、簡単に言うと入出明細テーブルのビューに対して、DISTINCT句を含むクエリを発するためです。
「FM計算方式」が不要であればこれらの3フィールドはレイアウト上から削除して構いません。


以上

2014-11-25

『FMEasy在庫』 のバックエンドを MySQL に変える(1) ― 概要


 『FMEasy在庫 R1.0/R1.5』ではバックエンドに FileMakerデータベースを使用しています。
 本稿では、これを MySQL 5.1或は5.6に置き換える方法の概要を説明すします。なお、本稿は『FMEasy R1.5』に沿って解説を進めていきます。

はじめに

FileMaker によるアプリで、バックエンドを FileMaker から SQLデータベース(ESS、External SQL Source)に置き換えるとき、リレーションシップのウインドウで各TOをFileMakerテーブルからESSテーブルに貼り替えるわけですが、このときリレーション、レイアウト、スクリプトおよびびセキュリティ内のフィールド等が壊れてしまいます(詳細は後述)。
 この場合、壊れた設定をひとつひとつ手動で設定し直さなければならなくなります。実に無意味で苦痛な作業を強いられるわけですが、対策が記されたサイトがみつかりました。

FileMaker, mySQL, and ESS; A Little Known Secret, to Me Anyway

 上記を要約すると、ESSテーブルに貼り替える前に、「FileMakerのテーブルを作成日順でソートし、そのソート順にESSテーブルのフィールドを並び替えた後に、FileMakerのリレーションを張り替えろ」、というもの。
 小社でこの方法をやってみましたが、うまくいきませんでした(やはりフィールドのマッピングが壊れてしまう)。もし上記のリンクの方法で「旨くいったぜ」という方がいれば、一報頂ければ望外の喜びとなります。
 ということで、以下、無意味?で苦痛なバックエンドの変更手順を解説します。

開発環境


小社における開発環境は以下のとおり。


FileMaker Pro 12/13 Advanced
FileMaker Server 12/13 Advanced
MySQL 5.1/5.6
ODBC 5.1/5.2/5.3
MySQL Workbench 5.2/6.2

MySQL5.6で使用するODBCドライバは...
外部 SQL データソースに対してサポートされている ODBC ドライバ


注:
 FileMaker 12/13 による MySQL 5.5 の使用はビューが認識されない等の問題があるため、お勧めしません。

 MySQLの管理ツールはいろいろあります。あえてMySQLコマンドラインを使うならそれも良いですが、他にも以下のようなツールがあります。
で、どれがいいの、という議論は、
Workbench, Navicat, TOAD for MySQL?

 なお、MySQL Workbench 6.2 は 5.1/5.2 に比べるとかなり良くなってる印象です。

データベース及びテーブルを作成する

ツールが決まったらスキーマ(ここでは名称を easyinv15 とする)とテーブルを作成します。このとき、テーブル名とフィールド名は、『FMEasy在庫 R1.0/1.5』のデータ用ファイル EasyData15.fmp12 のテーブル/フィールド名と合致させるようにします。
 なお、計算フィールドについてはMysqlApp.fmp15 のシャドーテーブル(後述)で作成可能ですが、パフォーマンスが劣化するのでなるべく使用しないように設計します。また、グローバルフィールド(グローバル値を持つテキスト/数値/日付/タイムスタンプ/オブジェクトの各フィールド、ここでは計算フィールドを除く)はシャドウテーブル内では作成できないため、グローバルフィールドに関連する処理は再設計が必要となります。特に在庫関連機能の再設計は面倒なので、機会を改めて述べたいと思います。

さて、スキーマ/テーブルの作成が終了したら、右図のようにODBC設定を行います。














 

外部データソースの変更とリレーションキーの再設定

次にFileMaker側。まず、「FMEasy在庫 R1.5」の EasyApp15.fmp12 を複製して適当な名称を付けます(ここでは、MysqlApp.fmp12)。つぎのこのファイルを開きます。[ファイル]メニュー→[管理]→[外部データソース...]を選択し、下図のように設定します(名前は EasyODBC15 とする)。このとき、もともとあったFileMakerのデータソース EasyData15 は削除しておきます。


 つぎに「リレーションシップ」タグを開くと、元の EasyData15.fmp12 のテーブルによるリレーション設定は喪失して下記の図のようになっているので、個々のTOを上記で登録した EasyODBC15 のテーブルに正しく張り直します。
 この際、元の EasyApp15.fmp12のリレーションシップ画面またはその印字物を参考にします。



この時、TO名は元のママになるよう注意します。たとえば、「入出明細_入庫」TOを選択し直すと「入出明細」になってしまうので、張り直す直前にTO名をコピーし、張り直し後に「入出明細」になったらペーストして上書きすると良いでしょう。

 なお、この張り直し後に[テーブル]タブをクリックすると、今選択したMySQLのテーブルがイタリック(斜体)で表示されます。
 これらのテーブルは(MySQLの)シャドウテーブルと呼ばれます。このシャドウテーブル内では計算フィールドを作成することができますが、他のフィールドは作成できません。MySQLテーブルのフィールドを新設/変更/削除するには、MySQLコマンドライン等の他ツールを使用する必要があります。




レイアウトのフィールド張り替え

TOを張り替えてた時点で、レイアウト上のフィールドも誤ってマップされてしまうので、各レイアウトの各フィールドを一つ一つ、張り直す必要があります ― 絶望的に退屈だけど、間違えられない作業ですね。

TO張り替え後、壊れてしまった取引先レイアウト ― 一つ一つレイアウトを開き
不正なフィールドを一つ一つ張り替えていく

スクリプトはStandardのものを開いてコピペ

次はスクリプトです。MysqlApp.fmp12内のスクリプトに設定されているフィールド名もグチャグチャになっているので、元の「FMEasy在庫 IWP/WD R1.5」の正しいスクリプトをコピって、MysqlApp.fmp12側に貼ります。
 具体的には、MysqlApp.fmp12 とともに EasyApp15.fmp12を開き、双方のファイルの「スクリプトの管理」ウインドウを開きます。次に EasyApp15.fmp12 側のスクリプトを開いて中身をすべてコピーし(Cntrl+A → Cntrl+C)、対応する MysqlApp.fmp12 のスクリプトを開きペーストしていきます(Cntrl+A → Deleteキー → Cntrl+V)。

MysqlApp.fmp12 の壊れたスクリプト。フィールドに関するステップが壊れている。
MysqlApp.fmp12側で正しいスクリプトの中身をコピーし、上図でCntrl+A をしてスクリプトの中身を選択、
Deleteキーで削除、Cntrl+V で 正しいモノをペーストし直す。
  これを壊れてしまったすべてのスクリプトに対して繰り返し実行します。

値一覧の修正

値一覧も修正が必要になります。下図で赤枠は壊れてしまったモノです。青枠はMySQLでは数値フィールドに文字列を入力することが許容されないため修正を要するモノで、これらのフィールドがスクリプトに使用されている場合は、数値のみをセットするようにスクリプトも修正する必要があります。



その他


 「FMEasy在庫」では不要ですが、他のシステムではアクセス権限セットやカスタム関数についても修正が必要になる可能性があります。



 以上、やっていて実に虚しくなる作業ではあり、もうすこしスマートな方法があるのではないかと。

 ということで、次回は在庫算出についてご紹介します。
 FileMakerのリレーションを使用して、「FMEasy在庫 R1.0/R1.5」のように、

    前回繰越在庫+SUM(今回入庫数)-SUM(今回出庫数)

 とかやってしまうと、FileMakerバックエンドより時間がずーっとかかってしまうので、方法と、高速なMySQLの実力を発揮できそうな方法の2つをご紹介したいと思います。




(土屋)

2012-07-06

MySQL Workbench の EER モデリングツールでリレーションシップ検証 3 (リレーションシップアイコンの種類と使い方)

前回、前々回の記事で、外部キーの設定と制約の定義方法について説明してきましたが、今回は EER モデリングツールのリレーションシップアイコンの種類と使い方について説明します。

EER モデリングでリレーションシップの設定を行う場合は、画面の左下に並ぶ 6 種類のアイコンを使います。




 既存のテーブル列を使ってリレーションシップを設定する

大抵の場合は、先に基本的なテーブルを予め定義しておき、後でリレーションシップを設定する作業手順となるでしょう。そのような場合は、上記赤囲みの一番下のアイコンを使用します。

このアイコンを使って作成されたリレーションは、たとえば次のようになります。




青囲みの列に注目してください。ブランドテーブルの [ブランドID]、および取扱商品テーブルの [ブランドID] は共に既存の列にが使われています。


 外部キー専用の列を子テーブルに新規追加し、1対1 の非依存型(non identifying)リレーションシップを設定する


子テーブルに外部キー用の列が作成されていない場合に、親テーブルと 1対1 の非依存型のリレーションシップを設定する場合は、一番上のアイコンをクリックします。
非依存型(non identifying)リレーションシップについては、こちらの記事をご覧ください。

このアイコンを使って作成されたリレーションは、たとえば次のようになります。



青囲みの列に注目してください。ブランドテーブルの [ブランドID]はそのままですが、取扱商品テーブルには、 [ブランド_ブランドID] という専用の列が新たに追加されています。
また、ブランドテーブル側、および取扱商品テーブル側の支線は枝分かれしていないため、このリレーションシップが 1対1 の関係となっていることがわかります。

非依存型リレーションシップの場合、コネクタは破線で表現されます。


 外部キー専用の列を子テーブルに新規追加し、1対多の非依存型(non identifying)リレーションシップを設定する

子テーブルに外部キー用の列が作成されていない場合に、親テーブルと 1対多の非依存型リレーションシップを設定する場合は、上から二番目のアイコンをクリックします。
非依存型(non identifying)リレーションシップについては、こちらの記事をご覧ください。

このアイコンを使って作成されたリレーションは、たとえば次のようになります。



青囲みの列に注目してください。ブランドテーブルの [ブランドID]はそのままですが、取扱商品テーブルには、 [ブランド_ブランドID] という専用の列が新たに追加されています。
また、ブランドテーブル側の支線が枝分かれしていないのに対し、取扱商品テーブル側の支線が三つに枝分かれしているため、ブランド 1 に対し、取扱商品が多の関係になっていることがわかります。

非依存型リレーションシップの場合、コネクタは破線で表現されます。


 外部キー専用の列を子テーブルに新規追加し、1対1 の依存型(identifying)リレーションシップを設定する

子テーブルに外部キー用の列が作成されていない場合に、親テーブルと 1対1 の依存型のリレーションシップを設定する場合は、上から三番目のアイコンをクリックします。
依存型(identifying)リレーションシップについては、こちらの記事をご覧ください。

このアイコンを使って作成されたリレーションは、たとえば次のようになります。



青囲みの列に注目してください。ブランドテーブルの [ブランドID]はそのままですが、取扱商品テーブルには、 [ブランド_ブランドID] という専用の列が新たに追加されています。
また、ブランドテーブル側、および取扱商品テーブル側の支線は枝分かれしていないため、このリレーションシップが 1対1 の関係となっていることがわかります。

依存型リレーションシップの場合、コネクタは実線で表現されます。


 外部キー専用の列を子テーブルに新規追加し、1対多の依存型(identifying)リレーションシップを設定する


子テーブルに外部キー用の列が作成されていない場合に、親テーブルと 1対多の依存型リレーションシップを設定する場合は、上から四番目のアイコンをクリックします。
依存型(identifying)リレーションシップについては、こちらの記事をご覧ください。

このアイコンを使って作成されたリレーションは、たとえば次のようになります。



青囲みの列に注目してください。ブランドテーブルの [ブランドID]はそのままですが、取扱商品テーブルには、 [ブランド_ブランドID] という専用の列が新たに追加されています。
また、ブランドテーブル側の支線が枝分かれしていないのに対し、取扱商品テーブル側の支線が三つに枝分かれしているため、ブランド 1 に対し、取扱商品が多の関係になっていることがわかります。

依存型リレーションシップの場合、コネクタは実線で表現されます。



 多対多のリレーションシップを設定する



子テーブルに外部キー用の列が作成されていない場合に、親テーブルと多対多のリレーションシップを設定する場合は、下から二番目のアイコンをクリックします。

このアイコンを使って作成されたリレーションは、たとえば次のようになります。




多対多の場合は、子テーブルの外部キーと親テーブルの主キーを結び付けると、テーブル名_has_テーブル名 という名前のテーブルが新たに作成されます。
このテーブルは、子テーブルに対する外部キーおよび親テーブルに対する外部キーをそれぞれ持っている点に注目してください。

上図の場合では、ブランド_has_取扱商品 というテーブルに、取扱商品テーブルの主キーに対する外部キー、およびブランドテーブルの主キーに対する外部キーが作成されることを示しています。


外部キーを確認すると、以下のようになっています。


○ブランドテーブルに対する外部キー



ブランドテーブルの主キー[ブランドID]に対する外部キーが作成されています。



○取扱商品テーブルに対する外部キー




取扱商品テーブルの主キー[商品ID]に対する外部キーが作成されています。



【関連リンク】
MySQL Workbench 基礎講習コース





2012-07-05

MySQL Workbench の EER モデリングツールでリレーションシップ検証 2 (外部キー制約の種類と動作)

前回の記事では、リレーションシップ構築時の idendifying (依存型)および non identifying (非依存型) の考え方と設計方法について述べましたが、今回は外部キーで設定可能な制約の種類と動作について説明します。


【外部キー制約とは】

子テーブル側の外部キーと、親テーブルの主キーの参照整合性を維持するために、子テーブル側の外部キーの動作を制限するものです。

たとえば、前回のブランドと取扱商品との関係性では、取扱商品テーブル側に不明な外部キー([ブランドID])が存在しないように制御したり、ブランドテーブル側から特定のブランドを削除した場合、そのブランドに関連する商品を取扱商品から自動的に連動して削除させたりといった振る舞い(制約)を設定します。


MySQL Workbench の EER モデリングでは、下図のように Foreign Key タブ上の Foreign Key Option を選択するだけで外部キー制約の設定が行えます。



【On Update と On Delete】

外部キー制約のオプションは、更新時(On Update)、削除時(On Delete)に大別されます。

これらは、親テーブル側(上図ではブランド)側の動作を示しており、親テーブル側のレコードが更新されたり(On Update)、削除されたり(On Delete)したときに、子テーブル(上図では取扱商品)の関連レコードの扱いを定義するという意味です。
そして、実際の関連レコードの扱いは、上図の赤囲みのドロップダウンリストから選択します。


【外部キー制約の種類】

ドロップダウンリストから選択可能な外部キー制約は次のとおりです。

RESTRICT/NO ACTION
子テーブルに関連レコードがあったら、親レコードの更新/削除を許可しない。

NO ACTION はステートメントおよびすべてのトリガーが起動された後に子テーブルの値がまだ有効であれば変更は許可される。
これに対し、RESTRICT は、子テーブルに関連レコードが存在する場合、変更は絶対に許可されない。
RDBMS ではこのような厳密な動作の違いがあるものもあるが、MySQL では RESTRICT と NO ACTION の挙動は同じ。


たとえば、取扱商品(子テーブル側)の登録を始めたら、ブランド名(親テーブル側)の変更をさせないようにする場合がこれに相当します。

CASCADE
親テーブルのレコードを更新/削除したら、子テーブルのレコードも更新/削除する。
厳密には、親テーブルの主キーの値を更新したら、子テーブルの外部キーの値も同じ値で更新され、親テーブルのレコードを削除したら、そのレコードに関連する子テーブルのレコードも連動して削除される。

たとえば、特定のブランド(親テーブル側)を削除したら、そのブランドを持つすべての取扱商品(子テーブル側)を削除するようにする場合がこれに相当します。

SET NULL
親テーブルのレコードを更新/削除したら、子テーブルの外部キーの値を NULL に設定する。
これにより、当該レコードの親子関係が解除されることになる。

たとえば、ブランド(親テーブル側)を削除したとしても、取扱商品(子テーブル側)は将来の管理用にデッドストックとして残しておく場合がこれに相当します。


親テーブルの主キーを変更した場合、および親レコードを削除した場合の外部キー制約の振る舞いを表にすると、以下のようになります。


動作条件挙動親(子なし)親(子あり)
On UpdateRESTRICT/NO ACTION親主キー更新可親主キー更新不可変化なし
CASCADE親主キー更新可親主キー更新可外部キー連動更新
SET NULL親主キー更新可親主キー更新可外部キーNULL
On DeleteRESTRICT/NO ACTION親レコード削除可親レコード削除不可変化なし
CASCADE親レコード削除可親レコード削除可子レコード連動削除
SET NULL親レコード削除可親レコード削除可外部キーNULL


【SQL による外部キー制約の例】


前述の外部キー制約のパターンのうちのいくつかを、実際の SQL による定義でいくつか確認してみましょう。太字が外部キーの設定と制約を定義している部分です。特に赤字の部分に注目してください。
挙動については、前項のテーブルをご覧ください。



例1: 
On Update: NO ACTION
On Delete: CASCADE

--
-- Table structure for table `取扱商品`
--

DROP TABLE IF EXISTS `取扱商品`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `取扱商品` (
  `ブランドID` int(11) DEFAULT NULL,
  `商品ID` int(11) NOT NULL AUTO_INCREMENT,
  `商品名` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`商品ID`),
  KEY `fk_取扱商品_ブランド` (`ブランドID`),
  CONSTRAINT `fk_取扱商品_ブランド` FOREIGN KEY (`ブランドID`) REFERENCES `ブランド` (`ブランドID`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;



例2: 
On Update: CASCADE
On Delete: SET NULL


--
-- Table structure for table `取扱商品`
--


DROP TABLE IF EXISTS `取扱商品`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `取扱商品` (
  `ブランドID` int(11) DEFAULT NULL,
  `商品ID` int(11) NOT NULL AUTO_INCREMENT,
  `商品名` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`商品ID`),
  KEY `fk_取扱商品_ブランド` (`ブランドID`),
  CONSTRAINT `fk_取扱商品_ブランド` FOREIGN KEY (`ブランドID`) REFERENCES `ブランド` (`ブランドID`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;


2012-07-04

MySQL Workbench の EER モデリングツールでリレーションシップ検証 1 (Identifying と Non identifying)

MySQL Workbench の便利な機能に EER モデリングツールがあります。


MySQL Workbench の EER モデリング例 


EER モデリングツールを使うことによって、データベースの基本設計を行い、それを使って MySQL  データベース本体を生成したり(フォワードエンジニアリング)、既存の MySQL データベースを EER モデリングツールに読み込ませて(リバースエンジニアリング)設計内容を修正した後で再び MySQL データベースに同期(シンクロナイジング)させたりすることができます。

EER モデリングツールの魅力は、何といってもデータベース設計を視覚的に行えるところにあることでしょう。
テーブル定義、列定義はもちろんのこと、テーブルオブジェクトの配置、リレーションシップの設定などもマウスクリックや簡単な入力作業である程度の設計が可能です。

MySQL Workbench は、MySQL の公式サイトからダウンロードできます。

ダウンロード先:MySQL Workbench 5.2


今回より、MySQL Workbench の EER モデリング機能で設定可能なリレーションシップの種類と、その動作の違いについて数回に分けて説明します。

リレーションシップの種類には、一対一、一対多、多対多、自己リレーションなどがありますが、それらの基本的な概念は他のサイトでも多く触れられているため、本記事では省略します。


【Identifying と Non identifying】

EER でリレーションシップ設定を行い、外部キーの設定情報を確認したときに以下のようなチェックボックスが気になった方もいらっしゃるのではないでしょうか。



そこで、今回は、上記のリレーションの外部キー属性となる、identifying と non identifying の違いについて説明します。


Identifying relationship (依存リレーションシップ)--- 子テーブルの外部キーの一部に親テーブルの主キーが組み込まれた形となり、親テーブルなしでは成り立たない関係。


たとえば、ブランド契約で販売する商品が、撤退時に商品の取扱いも同時に終了するように、ブランドテーブルと取扱い商品テーブルを関連づける場合、[商品ID] および[ブランドID] の組み合わせで外部キーを作り、[ブランドID]  が存在しなければその商品は存在し得ないような厳密な設計を行います。



本来、子テーブル側の主キーは一つ([商品ID])ですが、依存型リレーションシップの場合は親テーブル側のIDを識別するための列([ブランドID])も主キー扱いとなりますので、上図のように子テーブルの主キーは二つとなります(どちらも欠かせません)。
 
 EERモデリングでは、identifying リレーションのコネクタは、上図のように実線で表現されます。

 この場合、外部キー設定がされている取扱商品テーブル構成をダンプ(SQL表記)させると、以下のようになります。
 太字表記の部分が今回のチェック項目になりますが、特に赤字の部分に注目してください。[商品ID] および [ブランドID] の両方が主キー となっています。

--
-- Table structure for table `取扱商品`
--

DROP TABLE IF EXISTS `取扱商品`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `取扱商品` (
  `ブランドID` int(11) NOT NULL,
  `商品ID` int(11) NOT NULL AUTO_INCREMENT,
  `商品名` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`商品ID`,`ブランドID`),
  KEY `fk_取扱商品_ブランド` (`ブランドID`),
  CONSTRAINT `fk_取扱商品_ブランド` FOREIGN KEY (`ブランドID`) REFERENCES `ブランド` (`ブランドID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;


Non identifying relationship(非依存リレーションシップ)--- 親テーブルの主キーと子テーブルの外部キーでリレーションシップを構築するが、子テーブルに外部キーとは独立した主キーを持っている関係。


前述のモデルの応用例として、ブランド管理が廃止され商品だけが残った場合にも、在庫商品を処分(販売)できるように、ブランドを問わず商品を管理して扱う場合は、親テーブルが削除された場合にも、子テーブルの商品だけは残して管理できるように設計します。





EERモデリングでは、non-identifying リレーションのコネクタは、上図のように破線で表現されます。


この場合、外部キー設定がされている取扱商品テーブル構成をダンプ(SQL表記)させると、以下のようになります。
太字表記の部分が今回のチェック項目になりますが、特に赤字の部分に注目してください。[商品ID] のみが主キー となっています。
--
-- Table structure for table `取扱商品`
--


DROP TABLE IF EXISTS `取扱商品`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `取扱商品` (
  `ブランドID` int(11) NOT NULL,
  `商品ID` int(11) NOT NULL AUTO_INCREMENT,
  `商品名` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`商品ID`),
  KEY `fk_取扱商品_ブランド` (`ブランドID`),
  CONSTRAINT `fk_取扱商品_ブランド` FOREIGN KEY (`ブランドID`) REFERENCES `ブランド` (`ブランドID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;



【関連リンク】
MySQL Workbench 基礎講習コース


2012-06-16

『売上猫くん on MySQL』開発日記 - 番外25 - 行ロックについて

小社主催の「FileMaker+MySQL開発の講習」の受講者の方から「FileMakerとMySQLのシステムで、FileMaker(単体システム)のような行ロックってできないの?」との質問を講習前に頂いた。
FileMaker単体のシステムでは、ユーザがあるレコードを編集中に他のユーザが同レコードを編集しようとしても「他のユーザが編集中」旨が表示され、他のユーザは先行するユーザが編集を終了するまで編集することができなくなる。質問の趣旨はこれをFileMaker/MySQLのシステムでも実現したいということ。 
FileMaker標準機能では、FileMaker/MySQL 環境下で排他的行ロックはできない。 が、方法としては2つある。一つはMySQLのロック機能(select for update)を使用する方法(MySQLの排他的行ロック)、もう一つはMySQLテーブルにロックフラグを用意し、最初に編集を開始したユーザがそのフラグに自分のIDを書き込み、後続の他ユーザの編集を禁じるようにごりごりスクリプトで制御方法(FileMaker単体の行ロックと似ているという意味で、FileMakerライクなロック)。 以下はこの2つのロックの実装方法について。

1.MySQLの排他的行ロック
まず、MySQLの排他的行ロック機能を使うと、FileMakerはどのように反応するのか、試してみる。

MySQLコマンドラインで、

  begin;
  select 売上No from 売上ヘッダ where 売上No=1 for update;


を実行する。 次にFileMakerの売上画面で売上No=1のレコードを開いてみると、何事もなく表示される。次にこのレコードの任意のフィールド値を変更してみると普通に変更できる。 さらに、レコードをCommitすると… 出た、必殺のコーヒーマーク! これがMySQLの排他的行ロックである。 ここで、MySQLコマンドラインで、


 commit;


を実行すると、コヒーマークは消えて、レコードがCommitされた。 MySQLの排他的行ロック(select for update)は他ユーザがレコードをselectすることを妨げず、よってFileMakerのレイアウト上にも表示される。 また一旦表示されたレコードは、他のユーザが編集していたとしても、後発ユーザの編集を妨げるよなFileMaker的ロックは行われない。 しかし、いざCommitを実行しようとすると、コーヒーマックが出て、select for update を実行したユーザのトランザクションがCommitかRollbackされるまで、コヒーマークが出たまま、つまりロックされた状態となる。
【FileMakerとMySQLコマンドライン】
select ~ for update 後にFMで編集→確定ボタンすると、コーヒーカップが… 
注:
通常、ロックが発生から60秒後に、「[MySQL][ODBC 5.1 Driver][mysqld-5.1.58-community]Lock wait timeout exceeded; try restarting transaction」というエラーが返る。レコード確定ステップ実行後に後処理がある場合は、このエラーをトラップして処理を中止するなど適切な処理を行わないと、システムが暴走する可能性があるので要注意
FileMakerからも「SQLを実行」スクリプトステップに上記内容を直書きしたり、ストアドプロシージャをCALLすれば、ロックやトランザクションを利用できる。試しに


BEGIN
start transaction;
 select * from 売上ヘッダ where 売上No=1 for update;
 select sleep(60);
 rollback;
END;


というストアドプロシージャを作成して、「SQLを実行」ステップからこれをCALLしてみる。 問題なく実行でき、結果、60秒の間そのレコードは更新できなくなる。しかし 「SQLを実行」 ステップはクライアントPCにDSN登録がないと実行できない、という問題があるため、FileMakerからMySQLトリガを発生させてストアドを実行したい(この方法については『売上猫くん on MySQL』開発日記 - 3 - FMからストアド、トリガを参照)。 ということでトリガから上記のストアドを実行しようとすると、「 Not allowed to return a result set from a trigger」というエラーが出るので、レコードセットが返らないように下記のようにストアドを書きなおした。

BEGIN
    declare temp int;
    start transaction;
        select Count(*) into temp from 売上ヘッダ where  売上No =1 for update;
        select sleep (60) into temp;
        update appliasons set ret="OK" where ID=appId;
    commit;
END
ところが残念なことが重なる。今度は「Explicit or implicit commit is not allowed in stored function or trigger.」というエラーが返ってくる。 これでMySQLのトリガではトランザクションが使用できないことがわかった。まえに小生が書いた記事『売上猫くん on MySQL』開発日記 - 番外12 - トリガの制約に、この件をちらっと書いていた(恥)。 
結論としては、ストアドを直接実行すればMySQLのロックを実行できるが、トリガを介したストアド実行によるロックは不可、ということになる。

尚、FM12の新関数ExecuteSQL関数では、MySQLのロックは利用できない(つか、この関数、相当中途半端な上、意味不明なクエリを発する。書いた通りの動きをしないこともあるし…。この辺りは後日機会があれば)。


2.FileMakerライクなロック
次にFileMakerライクなロック。これは開発者が自分でゴリゴリ書かなくてはならないのでかなり面倒だ。 以下は小社のFileMaker/MySQL講習テキストから実装方法を引用する。
【実装】
“編集”ボタンを用意し、レコードを変更する必要があるユーザには“編集”ボタンを実行して「編集モード」にすることを義務付ける。編集モードでなければレコードの変更は実行できないよう制御するとともに、“編集”ボタン実行時には、当該レコードのロックフラグフィールド(cntLockId)にユーザ固有のIDをセット。このフラグが解除されない間は他ユーザが当該レコードの変更を行えないように制御。ユーザがレコードの更新を終えCommitした瞬間にこのロックフラグフィールドを解除するように設計する。
名称
種類
仕様
cntLockId
フィールド
(
テキスト)
編集ボタンを実行するとこのフィールドにユーザ固有のID=Get ( 持続 ID )が入力され、このIDを持たない他ユーザは編集不可となる。 
cntLockTiime
フィールド
(
タイムスタンプ)
編集ボタン実行時に[cntLockId]とともに本フィールドにはサーバのタイムスタンプ(現日時)が入力される。 このタイムスタンプによりデッドロックになっていないかを判断し、管理者は適切な処理をおこなう。
cntLockAC
フィールド
(
テキスト)
必要に応じて作成。編集ボタン実行時にGet ( アカウント名 )が入力される。 これを利用すれば、編集実行者を画面上に表示することができる。
(ユーザが手入力可能なフィールド)
フィールド
OnObjectEnterスクリプトトリガを用いて、[cntLockId<> Get ( 持続 ID )の場合は、フィールドに入れない(フィールド値を変更できない)ように制御。
編集
ボタン
上記のcntLockId/ cntLockTiime/ cntLockAC参照。左記3フィールドに値を入力後にレコードを確定する。これによりそのレコードは他ユーザによる編集が不可となる。
確定
ボタン
上記のcntLockId/ cntLockTiime/ cntLockACの値をクリア(ロックを解除)後、レコードを確定する。
復帰
ボタン
デッドロックしないよう([cntLockId]の値が残らない)ように制御。
他のボタン
ボタン
削除ボタン、削ボタン(売上明細削除用)など、当該レコードを変更する可能性があるボタン、スクリプトは[cntLockId]に他ユーザのIDがある場合は、実行出来ないように制御する。

【編集ボタンによるFileMakerライクなロック】

[cntLockId]と同じGet(持続ID)を持つユーザのみが編集可となり、確定ボタンが完了すると[cntLockId][cntLockTime][cntLockAC]はnullとなり、他のユーザも編集可能となる。


注:
サーバのRemote Desktop Service を介して複数人でFileMakerを使用する場合、Get(持続ID)は重複すると思われる。この場合、他の方法で個別IDを取得すること。

(土屋)

2012-06-08

SQL関連記事と『売上猫くん on MySQL』開発日記の一覧








【FileMaker/MySQL環境での大容量データ取扱(英語のみ/動画による実例あり)】
Big Table Handling Model in FileMaker/MySQL Environment ― Tentative one
FileMaker vs Access 実行速度比較検証


【FMEasy在庫 on MySQL関連】
『FMEasy在庫』 のバックエンドを MySQL に変える (1) ― 概要
『FMEasy在庫』 のバックエンドを MySQL に変える (2) ― 在庫1
 


【その他のFileMaker/MySQL関連】
 ファイル起動時にFileMakerからMySQLに投げられるクエリ



【MySQL Workbench関連】
MySQL Workbench の EER モデリングツールでリレーションシップ検証 1 (Identifying と Non identifying)
MySQL Workbench の EER モデリングツールでリレーションシップ検証 2 (外部キー制約の種類と動作)

MySQL Workbench の EER モデリングツールでリレーションシップ検証 3 (リレーションシップアイコンの種類と使い方)
 



【売上猫くん開発日記 ― 番外編】
番外1 -全データベース削除→リストア
番外2 - MySQLミラーサイト
番外3 - 0を書き込みできない
番外4 - mysqldump で文字化け?
番外5 - ポータルで検索できない
番外6 - リモートのログを mysqlbinlog できない
番外7 - FileMaker内にMySQLの一般ログを表示する
番外8 - insert...select構文とODBC
番外9 - 外部キー制約設定でのたうちまわる
番外10 - 開発再開
番外11 - 外部キー ってさぁ… orz
番外12 - トリガの制約
番外13 - MySQL Workbenchの憂鬱(ほぼ私的メモ)
番外14 - テーブル毎に権限を設定する(ほぼ私的メモ)
番外15 - 再び権限(私的メモ)
番外16 - FMで大きなSQLテーブルは扱えるのか? ― その1
番外17 - FMで大きなSQLテーブルは扱えるのか? ― その2
番外18 - FMで大きなSQLテーブルは扱えるのか? ― その3
番外19 - FMで大きなSQLテーブルは扱えるのか? ― その4
番外20 - ウィンドウ内容の再表示ステップ実行時のクエリ
番外21 - βリリースしまつた
番外22 -SQL SECURITY の DEFINER/INVOKER指定
番外23 - FileMaker vs Access ~ 実行速度編 ~
番外24 - MySQL 5.5は使用できるのか?
番外25 - 行ロックについて


【売上猫くん開発日記 ― 本篇】(←メインになる筈が、見捨てられた哀れな本編)
1 (題目無)
2 - 開発環境
3 - FMからストアド、トリガ



2012-06-05

『売上猫くん on MySQL』開発日記 - 番外24 - MySQL 5.5は使用できるのか?

FileMakerとMySQL 5.0/5.1で開発してきた人へ:

『売上猫くん on MySQL R5.0β』は、FileMaker 11(FM11)/MySQL 5.1で開発した。 そのDBダンプをMySQL5.5上 にリストアして、FM11フロントエンド(NekoApp.fp7)からアクセスしようとすると、以下のような状況となり、アクセスできない。



このNekoApp.fp7をFileMaker 12(FM12)でNekoApp.fmp12に変換し、MySQL5.5にアクセスするとどうか?



と、さらに悲惨なこととなる。


NekoApp.fp7のリレーションシップ画面を開いてみると、下図のように一見すると正しくテーブルは認識されているようだが、TOをダブルクリックしてみるとTOとテーブルのリンクが消失していて、テーブルを指定し直す必要がある。


また、その指定し直しの過程でリレーションシップが飛んでしまったりもする。 TOとリレーションシップをすべて再設定・確認するだけども大変な作業になるし、検証作業も含めると… 膨大な作業になる。


注:
  • 使用しているODBCのバージョンは、5.1.11。 
  • FM社が公式サポートするMySQLは現時点でMy SQL 5.1 Community Editionのみ。
  • MySQL5.1を介さず、最初からFM11/12とMySQL5.5でリレーションシップ(TO)を作成しておけば、とりあえずは動作するようである(要検証)。

2011-01-25

『売上猫くん on MySQL』開発日記 - 番外22 -SQL SECURITY の DEFINER/INVOKER指定

ようやく再リリース!、と思ったのもつかの間。 MySQLデータベース neko のインストール後、テーブル(実際はビュー)にアクセスできない現象が発生。 CREATE VIEW するときの SQL SECURITY [DEFINER | INVOKER]に問題があることがわかったので、以下、そのメモ。
(ということで、1/25現在、ダウンロード停止中 )
(1/25 18:00~、ダウンロード再開)

DEFINER/INVOKER

DEFINER指定:
Stored/Viewに対して実行アカウントがExecute/Selectできる権限さえあれば、Stored/Viewの内容はDEFINERの権限で実行される→Stored/Viewが実行できない可能性は少ない(DEFINERがroot@localhost なら、ほぼ確実に実行できる筈。)

INVOKER指定:
Stored/Viewに対してExecute/Selectできる権限があっても、Stored/Viewの内容は実行アカウントの権限に基づき実行される→Stored/Viewが実行できない可能性は、DEFINER指定に比し大きい。

例:
CREATE DEFINER = 'admin'@'localhost' PROCEDURE p1()
SQL SECURITY DEFINER (or INVOKER)
BEGIN
UPDATE t1 SET counter = counter + 1;
END;


DEFINER指定:実行アカウントに Execute権限さえあれば、t1テーブルのUPDATE権限は不要( 'admin'@'localhost'の権限で実行される)
INVOKER指定:INVOKER(実行者) は Execute権限とUPDATE権限の両方必要。 

尚、下記サイトでは、セキュリティ上、INVOKER の使用を推奨している。


参考サイト
http://dev.mysql.com/doc/refman/5.0/en/stored-programs-security.html
(対応の日本語頁は無く、DEFINER | INVOKERに関する日本語サイトも少なし)

以上

2011-01-17

『売上猫くん on MySQL』開発日記 - 番外21 - βリリースしまつた

ダウンロード再開しまつた。 MySQL 5.5 に対応させようとしましたが、簡単には修正できなさそう。当面は諦めモード。 ということで、本製品は、現段階では、MySQL 5.5 には非対応!ですので、ご注意ください。 (11/01/21 土屋追記)



最新版のMySQL 5.5で動作しないことが判明したため、一時ダウンロード停止! トホホ…(11/01/20 土屋追記)



ようやく「売上猫くん on MySQL 5.0」のβ版(フリーウェア)をリリースすることになりました。
売上明細のテーブルに200万程度のレコードを入れてテストを行っています。
現時点でできるかぎりの巨大テーブル対応と、ストアドプロシジャやトリガを使用した高速化を行っています。 200万行のテーブルがあっても、起動が若干遅いこと、起動後最初に売上明細テーブルにアクセスにいくと10秒位コーヒーマークがでる位で、使用できるレベルではないか、と思ってます。 1000万件クラスのテーブルになると、今以上の対策がいるかも知れないです。

ご興味のある方は下記からダウンロードしてくださいね。 

売上猫くん on MySQL 5.0βのサイト
http://www.tpc.jp/product/neko/50/index.htm

ダウンロードページ


尚、バージョンを 5.0 としているのは、FileMaker Pro 5/6 で作成した旧製品「売上猫くん 4.5」の機能のほとんどを継承しているからです。データベース(バックエンド)に MySQL を使用した猫くん製品は、これが最初となります。


2010-11-16

『売上猫くん on MySQL』開発日記 - 番外20 - ウィンドウ内容の再表示ステップ実行時のクエリ

SQLデータベースを使用時、あるユーザが行った更新は他のユーザの画面に即時反映されることは無い。他のユーザが更新を行ったか否かを確認するには、[ウィンドウ内容の再表示]ステップを使用するが、このステップには、「キャッシュ結合結果を書き込む」「キャッシュされたSQLデータ」という2つのオプションがある。 オプションによって、SQLデータベースに送られるクエリにはどういう違いがあるのか?

1.キャッシュ結合結果を書き込む/キャッシュされたSQLデータの両オプション選択時
SELECT ID,`〒`,`住所` FROM vw_zips WHERE ID IN(121013,121014,~) 等のクエリを発行、画面は更新される

2.キャッシュ結合結果を書き込のみ
クエリ実行されず、画面未更新

3.キャッシュされたSQLデータのみ
上記1と同様

4.オプション無
クエリ実行されず、画面未更新

FileMakerの[レコード]-[ウィンドウ内容の再表示]を実行すると、1と同じ結果となり、画面は更新される。


注:
  • Selectクエリの対象となるフィールドは、レイアウトテーブルの全フィールドと、そのレイアウト上の関連フィールドに限られる。 よって、関連フィールドの値を最新に更新したい場合は、そのフィールドをレイアウト上に明示的に配置しなければなならい点に要注意。
  • 他ユーザが追加したレコードについては、[ウィンドウ内容の再表示]ステップでは表示できない。追加されたレコードをSelcectするような検索を実行すること。
参考URL
http://www.filemaker.co.jp/help/html/scripts_ref2.37.9.html


2010-11-05

『売上猫くん on MySQL』開発日記 - 番外19 - FMで大きなSQLテーブルは扱えるのか? ― その4

前回は、FM社製のドキュメント(日本語版英語版)内の一文を引用し、それを小生なり解釈すると「他のフロントエンド開発ツールに比べるとFileMakerのESSはかなり限定されていること、また一見してFileMaker単体のシステムと同じ結果を返すように見えても異なることがある。ユーザはESSの限界と特性を意識して使用すべし」となる旨のことを書いた。これに加えて、同ドキュメントにもう一つ気になる文章がある。
    ESS は、FileMaker Pro ソリューションを、FileMaker Pro のみをベースにしたソリューションの限界を超えてスケールアップできる手段として設計されたものではありません。(ESS is not designed as a means to allow a FileMaker Pro solution to scale beyond the limits of a purely FileMaker Pro based solution.)
この一文は何のことを言っているのか? この日記番外シリーズにも書いたように、FileMakerソリューションであっても、当然ながら、SQLデータベースの多くの機能---ビュー、ストアドプロシジャ、トリガ、ログ照会、バイナリ/トランザクションログからのリカバリ等----FileMaker純正データベースエンジンでは不可能だった機能の恩恵に浴せる。この場合、主語を“ESS”ではなく“FileMaker”にすれば、「FileMaker Pro のみをベースにしたソリューションの限界を超えてスケールアップできる」のである。

とするとこの文は、「FileMaker純正データベースエンジンが実用的には(“論理的”にではない)取り扱うことができない大きなテーブルをSQLデータベースのそれに置き換えても、やはり実用的には取り扱うことはできない」と言っているのだと思われる。 タイトルにある「 FMで大きなSQLテーブルは扱えるのか?」という命題への直接否定のようだ。

直接否定だとすると、FileMakerの理論上、仕様上の限界はデータベース単位で8TBであるが、実用上の“限界”はどのくらいなのだろう? 古い記事だが、「(個人的な意見だがテーブルベースで)100万を超える位なら大丈夫だよ」とある。 小社でも数十フィールドあるFileMakerテーブルに100万~200万弱のレコードを収納して数年間、運用している。 200万レコード程度をFileMakerの“限界”と仮定すると、その“限界”を超えて、と主張するには、レコード件数的には400万レコード以上をテスト時の最大数とすれば十分だろうか。ちなみに、『売上猫くん on MySQL』のテスト環境で、いまのところ一番大きなテーブルのレコード数は約180万件である。

ただレコード件数をいくら増やそうとも、ユーザが強いストレスを感じたり、安定性が無いシステムでは“実用的”とは言えない。 “実用的”と言うには、その1とその2で書いたような問題をできる限り顕在化させてはいけない。問題6の激遅ソートは回避策がないので、ユーザによるカスタムソートの実用性は非常に低い。 その他の問題については、回避策を施したり、 運用で調整する(例えば、.fp7ファイルをサーバ上に置かず、ローカルに置く)ことにより、緩和できるものと判断している。 だが結局、「FileMaker Pro のみをベースにしたソリューションの限界を超えてスケールアップでき」たかどうかというのは、公正なエンドユーザの判断に拠る、としかいいようがない。

(土屋)

注:
「~限界を超えて~」については、上記の英文をキーにググってみたが(その3の参考URLを参照)、2007年当時は否定的な見方が優勢だった。 2008年以降は関連する記事を見つけることができなかった。


関連リンク:『売上猫くん on MySQL』開発日記の記事一覧