- ベストアンサー
MySQLの効率的な使い方
- MySQLを効率的に利用するための基本的な使い方を解説します。
- MySQLでのデータベース設計のポイントと、効率の良いテーブルの作成方法について説明します。
- ファイル保存方式からMySQLに移行することで、データの安全性やアクセス速度を向上させることができます。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>鞄などは全ユーザー分をまとめて、1テーブルにするということでしょうか? そうですね。自分なら用途別に基本1つずつのテーブルにまとめます。 以前書いたもので言うと、ユーザ・テーブル、鞄テーブル、銀行テーブル、メール・テーブル、アイテム・テーブルの4つのテーブルです。 メール・テーブルは、例えば、ユーザID、着信年月日、件名、本文などの列構成とすると、 select メール・テーブル.* from メール・テーブル where ユーザID=Aさん order by 着信年月日; などと検索できますね。 ユーザ・テーブルは、副問い合わせによる検索で鞄テーブルの中身をユーザ指定で検索できます。 お使いのMySQLバージョンが5.0とのことなので、副問い合わせも可能ですし、ストアドプロシージャも有効ですね。 自分の環境は、4.0なので、それらが使えず苦労します^^;
その他の回答 (4)
- mooboogie
- ベストアンサー率68% (28/41)
正規化についてはこちら。 http://www.mirai.ne.jp/~suehiro/am/kihonyougo/normal.htm 冗長性を排除した結果なんで、データ量が増えるというのは基本的にありません。 鞄マスタの件です。 1000個のアイテムを持つ鞄でもまったく問題ありません。 Aさんの鞄の中身を調べるには、 select * from 鞄マスタ where id = AさんのID; とするだけですね。 鞄マスタの中身で、 Aさん 帽子 Aさん 手袋 Bさん 扇子 Cさん エッチな本 Aさん 靴 上記select文で問題なく検索できます。 できますが、ユーザー数が多い場合に検索速度に問題があるかもしれません。 更新の件です。 ココではメール・マスタとなっていますが、頻繁に更新される可能性のあるテーブルだと、テーブルロックはキツイと思います。 そのようなテーブルの開発は、行ロック方式のデータベースしか経験がないのでわかりませんが、アプリ側でのフォローが必要になると思います。 更新タイミングというのも、重要になると思います。 ユーザーがログアウトする際におこなうのか、即更新するのか。 多少待たせてもよいなら、表レベルロックでもまったく問題がなくなります。 論点が枝分かれしてきたようなので、一旦区切りを付けたほうが良いかもしれませんね。 要はデータベースに合わせるなら、アプリ側で柔軟に対応させるしかないということになると思います。 MySQL(3.23)を使用する長所短所。 長所。 同時アクセスによる破損の心配は少ない。 データベース設計により、管理が楽になる。 短所。 テーブルロックされた状態で更新作業したユーザに対するフォローをアプリケーション側で用意しなければならない。 こんな感じでしょうかねぇ。がんばってくださいね。
お礼
お礼が遅くなりました。申し訳御座いません。 > 正規化 第一正規形を間違えて理解していたようです。 失礼致しました。 > 鞄マスタ 有難う御座います。 実感できる程速度に差は無さそうですし、大丈夫そうですね。 実際、大規模なサイトでは数万件のレコードなんてザラなんでしょうし・・・。 これまでのテキストファイルによる設計と比較しても、全く問題なさそうです。 > 更新 テーブルロックだとやはりキツイですか・・・。 理論上だけではとても私には片付けられそうにありませんし、 実際に稼動してみて、様子を見ながらアプリ側に対策を講じていきたいと思います。 最終手段として、InnoDB型に対応したサーバーに変更できなくもないですが。 これまで色々とご教授下さり、本当に有難う御座いました。 とても勉強になりました。本題は解決致しましたので、一件落着です。 また機会がありましたら、宜しくお願い致します。
- mooboogie
- ベストアンサー率68% (28/41)
年末は、仕事的にヒマなので、問題ナシです^^ 3.2ですかぁ。となると、副問い合わせもストアドも使えないですねぇ。 3.2の知識がありませんので申し訳ありませんが、4.0の場合であれば、joinを使用して問い合わせします。 容量の件は、現状のユーザ毎にテーブルを作る場合より、正規化した方がデータ量は減るので、問題がないと思います。 百万件程度のレコード数でもインデックスをきちんと使えば問題がなさそうです。 一番の問題は、検索より更新になると思います。
お礼
ご回答有難う御座います。 お言葉に甘えさせて頂きます^^; 3.2だとちょっと面倒臭そうですね・・・。 ただサーバーを乗り換えるのは大変なので、とりあえずどうにかしたいと思います^^; > ユーザ毎にテーブルを作る場合より、正規化した方がデータ量は減る ユーザー毎にテーブルを作るようなことを正規化と呼ぶのではないのでしょうか? インデックスの使い方がイマイチ分からないのですよね^^; 前回の話に舞い戻ってしまい申し訳ないですが、 鞄・マスタ等の場合、ユーザーIDとアイテムIDの2カラムで良いことが分かりましたが、 仮に1000個程入れられるようにする場合、アイテムIDのデータ容量に比べて 同じユーザーIDが何度も重複してデータが無駄に大きくなってしまうように思いますが、 データベースの場合、このあたりは自動的に調整されるのでしょうか。 > 一番の問題は、検索より更新 これは、リンク先にあるテーブル型やロック関連のことでしょうか。 やはり大量のユーザー固有のデータを持つものについては、 InnoDBで行ロックを行った方が良いのかもしれませんが、 実装サーバー上のMySQL3.23ではInnoDBに対応していないようです;; 頻繁に更新・検索されるであろうメール・テーブルなんかをMyISAMで扱うのは問題ありでしょうか・・・
- mooboogie
- ベストアンサー率68% (28/41)
お困りの点がようやく分かりました。スミマセン。 アイテム・マスタをどうするか。 オンラインゲームで考えると、アイテム=>身につけている防具、武器、銀行に預けているお金・物品など。 大規模なゲームであれば、数千、数万ものアイテムが存在すると思います。 だから、アイテム毎に列を設けるわけにはいかない。 上に挙げた例で、防具。 防具だと、頭、首、胴体、腕、手、足、靴、アクセサリーの8部位に分けてみます。 よって、ユーザ・マスタの8カラムで足ります。 鞄とか銀行、家は、たくさん物が入るし、”部位”は関係ないので、困ります。 鞄マスタ、銀行マスタを作り、「ユーザID、アイテムID」の2カラムで足ります。 ユーザ・マスタには、鞄ID、銀行IDの2カラム増になるんでしょうか。 実際は画面の表示ポジションとか、あるんでしょうけど。 勉強になりそうなので、深追いさせてもらってます^^;
お礼
返信が遅くなってしまい、大変申し訳御座いません。 > 鞄マスタ、銀行マスタを作り、「ユーザID、アイテムID」の2カラムで足ります。 ユーザーID別にテーブルを分けるべきではないかと考えていたのですが、 これは、鞄などは全ユーザー分をまとめて、1テーブルにするということでしょうか? となるとメールなども1つのテーブルで用が足りるということでしょうか? 参考URL、とても為になりました。 メタデータという考え方もあるんですね。 ストアドプロシージャなど、まだ知らないものも色々あるようで、 もっと学ばなければいけないことが良く分かりました。
- mooboogie
- ベストアンサー率68% (28/41)
ふつーに考えると、 user.log、user/[ID].log > ユーザー・マスタ item/[ID].log > アイテム・マスタ mail/[ID].log > メール・マスタ になるんでしょうねぇ。管理のしやすさだと。 お尋ねの可用性、対高負荷性に関しては、自分も興味があるので、援護投稿ということで。 データ量によるらしいですけど。 http://www.mysql.gr.jp/mysqlml/mysql/msg/3588 同時アクセス http://www.mysql.gr.jp/mysqlml/mysql/msg/2551
お礼
有難う御座います。 ご教授頂いたサイト、参考になりました。 共有サーバーなので、できるだけ負荷は掛けないようにしないといけないのですが、 扱うデータは精々メガバイトのレベルですので、それ程気にしなくても良いのかもしれませんね。 ただ、やはり将来性を考えてできるだけ効率の良いシステム設計を採用したい気持ちがあります。 自分なりに調べたところ、一般的にはデータの正規化は重要みたいで、 1つのテーブルでユーザー情報からアイテム、メールなどを一まとめにするのは良くないようですね。 過去の投稿などにも似たような書き込みがありましたが、どれも正規化を薦める回答のようでした。 しかし、MySQLを用いたWEBアプリケーションの開発に携わっている方のお話を探したら、 大規模なサービスでも、だいたいテーブル数は50程度のようです。 (どのようなサービスなのかは不明でしたが。) ということは、SNSのようにユーザー個別のデータが大量に必要になるケースで正規化を行うと、 私の考えのように数万個のテーブルを用いることになるので、 やはりマイナーというか効率が悪いのかもしれません。 どうすべきなのか、ますます分からなくなりました。 item というテーブルに全ユーザー分のアイテムを保管する方法もあると思うのですが、 そうするとカラム数は固定なので、アイテム数も限定しなければならないですよね。 それはやはり困るので、1つのフィールドにカンマ区切りでデータを複数個入れる方法も考えたのですが、 それだとデータベースを使っている意味が失われる気もします。 mixiであるとか、オンラインゲームであるとか、ほとんどの登録性のサービスで、 同様にデータベースを使っていると思うのですが、 それらはどのような構成になっているのでしょうかね・・・。 書店で色々MySQL関連の本を探してみたのですが、 どれも掲示板程度の小規模なプログラムばかりを対象としていて、参考になるものが見つかりません。 なお、同時アクセスの方の件は、気にすることはないみたいですね。 実際に設置して試してみたいと思います。
お礼
素早いご回答に感謝致します。 > 用途別に基本1つずつのテーブルにまとめます。 そうだったのですか。大きな疑問が解けました。 詳しいご説明まで、本当に有難う御座います。 ユーザーが毎日書ける日記などもこの方式で問題ないでしょうか。 仮に五千ユーザーがいるとして、1ユーザー辺り200件まで保存できるとすると、 最大百万行にも及ぶことになりますが、大丈夫でしょうか? 現時点ではそんな規模は大きくならないと予想していますが、 将来のことも視野に入れると、2GB制限などの問題はないのでしょうか。 (現在のレンタルサーバーでは、容量オーバーですが^^;) MySQLは、ローカルチェックでは、5.0を使用するのですが、 実際に設置するサーバーは、3.2のようなので、色々不便が多いですかね^^;; 質問応答を繰り返させてしまって申し訳ないです。