質問: データベース初心者です。素っ頓狂なことを言っていたら申し訳ありません。 DB設計について疑問です。 リレーショナルデータベースシステムを使用して例えばPOSシステムを構築するとします。 その際、顧客情報や日報情報など、複数レコードが想定されるデータに関しては、テーブルを定義してRDBSに格納すると効率よくシステムを運用しやすくなるでしょう。 しかし、システムの仕様(「自動入金チェックの有無(true or false)」や「緊急時のロック機能の有無(true or false)」など)のような2値データの集合は、どのように表現するのが一般的なのでしょうか。 --- ここで、条件を以下のように定義します。 * システムの仕様である2値の設定データが1000個あるとします(極端ですが)。 * システムとして定期的なバックアップを行います。RDBSに格納しているデータに関しては、RDBSに備わっているバックアップ機能を用います。 * システムの仕様データも、バックアップ対象とします。 * システムの仕様データは、システム起動時に一回だけロードし、メンテナンス時以外はその後アクセスしません。 --- 私の中で現状考えられるのは以下です。 1. 仕様データもRDBSに格納する。そのために、「自動入金チェックの有無」や「緊急時のロック機能の有無」のようなカラムを1000個用意した1レコードからなるテーブルを用意する。 2. 仕様データは、xmlやjson形式のファイルで用意し、RDBSとは別途に格納する。ただし、この場合はRDBSのバックアップ機能の対象外となるので、別途バックアップ機能を実装する。 3. 2に似ているが、XMLDBSを別途用意し、仕様データに関しては、XMLDBSで運用する。 自分なりに、上記のメリット・デメリットを考えてみました。 * 1は、RDBSで完結してデータを格納でき、RDBSのバックアップ機能をそのまま使える。しかし、仕様データのテーブル表現が不自然に感じ、データを取り扱う際もRDBのメリットがないように思える * 2は、直感的に仕様設定を定義でき、仕様に関するメンテナンス性もよいと思う。しかし、バックアップ機能を別途実装する手間がある * 3は、2のメリットに加え、アクセス効率も良い。しかし、XMLDBSを立てるコストがある。 --- 皆様の**業務上の経験**や、**一般則**等ありましたらお教えいただければ幸いです。 また、質問内容自体がおかしかったり、不自然な構成を想定しているようであれば、その点の指摘も頂ければと思います。 よろしくお願い致します。 ### 補足です。 条件に以下を追加します。 * エンドユーザには、クライアントサーバ形式でシステムを提供する。エンドユーザは基本的にはクライアント側しか操作しないが、データベースはサーバ側に格納する。 イメージとしては、店舗内にPOS端末(クライアント)が複数あり、売り上げ情報等をサーバのデータベースを管理しているという感じです。 店舗全体としての仕様データをサーバ側に格納するものと考えています。 後出しで申し訳ありません。よろしくお願いします。
回答: ユースケースによって最適な方法は決まってきます。 * マルチテナントのクラウドサービス化することを考えているなら、これらの設定値ほとんどはシステム設定値というよりは顧客ごとの動作設定ということになり、RDB格納、顧客ごとに行ができる、カラム数の多いテーブルになります。 設定フラグごとにカラムを作るのでなく、第一正規形違反なのですが64ビット整数であるBIGINTカラムに64個のフラグをビット単位で持たせてしまうやり方も有効です。アプリ側でフラグが増えるたびにADD COLUMNを流すのは大変ですし、このフラグ値を検索やソートや外部キー参照などの対象にすることはまずないので正規形でなくても困らないんですよね。 * そうでなく、また、稼働中に設定変更することはまずなくて設定変更するのならシステムの瞬断も許されるということなら、RDB格納ではなく外部化します。 ただここで、JSONやXMLファイルにするのでなく環境変数にすることはできないかご検討ください(項目数が多いんで苦しそうですが)。 JSONやXMLファイルにするとしたら、開発リポジトリには本番用の設定ファイルを入れますか、それも開発用のを? どちらも間違いのもとになる要素があるんですよね... 一つの手としては、項目数がとても多いので設定ファイルのJSONかなんかにする、リポジトリには本番用と開発用を両方入れる、どの設定ファイルを参照するかは環境変数で設定する、さらに環境変数で任意の項目を上書きできるということにしておく、とかだとそれなりに運用も合理化できそうです。 * 稼働中にメンテタイムなしで設定変更が必要? 仕方ありません、RDBでもNoSQLDBでもに突っ込むしか。