- ベストアンサー
大規模なショッピングサイトのDB設計について
はじめまして。 今回、以下のような規模のショッピングサイトを構築しようと思っています。 商品数が1万点を超えます。 商品の詳細ページ、分類ページはテンプレートを用意してユーザがアクセスする度に商品データベースにアクセスしてデータを読み込もうと思っています。 この際に生じた疑問点があります。 ・1万点を一つの商品テーブルで扱う場合に、アクセスしたときにどれくらい遅くなるのかという点。このような規模の場合、どんな設計にするべきなのか?気をつけるべきことがあるのか?教えて下さい。 ・顧客数や受注伝票が多数想定されるので、いくつかのテーブルにわけようと思っているのですが、どのような分け方が一般的なのでしょうか? 使用する言語がPHP、DBにはMySQLかPostgreSQLの場合について考えています。 宜しくお願い致します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
セッション管理のDBの複数テーブル使用については、私は知らないです。 要は、DBのデータのライフサイクルで、同じデータ形態でも、質が変わって しまえば、他のテーブルに移し、アクセス頻度の高いオブジェクトのインターフェースのパフォーマンスを落とさない。という目的(msystemさんがおっしゃってること)でなら、複数のテーブルを使うことに反対はしません。というか、やったほうが いいかと。 特に伝票なんかは、起票から承認、集計~決算まで1ヶ月くらいの間に急激に 質が変化し、特に締め日などアクセスのピークを迎え、以後、履歴参照のアクセス程度になります。 ならば、履歴用のDBなりTableに移して、Table内にはアクセス頻度の高いものだ けを最小限に抑えよう。こういったやり方はあると思います。 商品のデータなんかは、ライフサイクルが伝票なんかと比べると(履歴としての 利用を除けば)長いので、参照系、伝票のような短い期間に状態が変わるものは 更新系、同じ伝票でも、参照が主になってしまたものは参照系なんてふうに分け、 Table分けにとどまらず、DBまで、それ以上にWebServerなどのサーバまで分け てしまってもいいし、更新系の方をスペックを上げるとか、などなど。 私の発言の、 >どんなに件数が増えようと、1テーブルとして扱ったほうがいいです。 これも、場合によるね、ってことになってしまいますが。 フリーライセンスでも、細かい点で違いがあります。 MySQLはGPLでPostgreSQLはBSDだったかと。 GPLは、そのプログラム(ここではMySQL)を利用し、そのプログラムがないと 動作しない使用側プログラムは、使用側プログラムもソースをつけて配布し なければならない。って認識でいますが、これも正確でなさそうだけど。 パッケージで販売するんじゃなければ(1顧客のために作り上げる)大きな 問題ではないと思いますが。あと、そのプログラムの開発者に感謝する義務が ある、とかね。 BSDは、ほぼなんでもあり。
その他の回答 (4)
- msystem
- ベストアンサー率42% (79/186)
>処理だけ(CPUだけ)別にして、データベースは共通のHDDということでしょうか? >よろしければ教えて下さい。 一般的にデータベースでパフォーマンスが悪い原因は、HDDの使い方の悪さです。例えば、検索のためにインデックスを作りますが、インデックスをアクセスすることでHDDへのアクセス頻度を減らすのも目的の一つです。データベースサーバーに多くのメモリが必要であることもそうだし、テーブル設計と物理設計というのをわけてそれぞれ技術分野があるのもHDDなどの使用方法をしっかり考えることが重要であることをあらわしています。 余談が多くなってしまいましたが、「参照系と更新系でわける」というのは次のようなことをいっています。 もともと、DBMSによって得意な分野、不得意な分野があります。例えばMySQLは参照は得意だが更新処理は弱い、PostgreSQLは更新はそこそこ強い、Oracleなどの商用DBMSは更新などの安定性はほとんど問題になりませんが、要求ハードウェアのコストが高いなどの特徴があります。 そこで、受注などの更新系の処理は安定性の高い商用DBMSを使用し、在庫数や商品一覧など参照系の処理をMySQLなど参照が得意で、安価なDBMSを使用し(理由はアクセス数が増えたときに、複数サーバーを導入しやすくなり、レプリケーション運用することにより、負荷分散効果を期待できます)、更新系DBMSから必要なデータだけ参照系DBMSを更新することで、負荷分散しています。つまり、CPUをわけることで負荷分散するのではなく、コンピュータ自身を分け、なおかつ、それぞれ得意分野のDBMSを使用することで、パフォーマンスを出す方法です。 snake103さんのHDDを共通に持ち、CPUをわけるのは一般にクラスタによる方法になると思いますが、この方法でパフォーマンスを稼ぐのは難しい方法です。(この方法は更新処理での信頼性は高いです。シェアードディスク方式と呼び、Oracleのみが対応しています) その他のクラスタDBMSは、ディスクは共有せずレプリケーション機能を使いパフォーマンスを良くしています。(参照のパフォーマンスには有利ですが、更新処理は難しくなっています。シェアードナッシング方式と呼ばれ、SQLServer、DB2などが採用しています) つまり、HDDを共有すると、一見パフォーマンスが良くなりそうですが、DBMSのボトルネックをさらに締め付けることになるため、特にオープンソースのDBMSではおすすめできません。(クラスタ自身をおすすめできません) いずれにせよ、パフォーマンスのためには、できるだけHDDにアクセスせず、アクセスするときにも、できるだけアクセスが集中しないようにHDDを分散する(HDDの台数は増えます)ことを考えるのが、王道です。
- cse_ri2
- ベストアンサー率25% (830/3286)
DBはOracleとかMS-SQLServerの経験が多いのですが、 一般的な観点でコメントします。 >・1万点を一つの商品テーブルで扱う場合に、アクセス >したときにどれくらい遅くなるのかという点。このような >規模の場合、どんな設計にするべきなのか?気をつける >べきことがあるのか?教えて下さい。 DBサーバのスペックにもよりますが、一万点くらいでしたら それほど多い部類には入らないと思います。 適切なインデックスを作成することくらいでしょうか。 >・顧客数や受注伝票が多数想定されるので、いくつかの >テーブルにわけようと思っているのですが、どのような >分け方が一般的なのでしょうか? 明細データが多い場合、OracleやMS-SQLServerではパーティショニング 機能(一つのテーブルを複数の領域に分割して、部分的な 更新や検索の処理速度を向上させる)で、特定のテーブル のアクセス速度を向上させたりするのですが、MySQLやPostgreSQL にその機能があるかどうか知りませんので、月や期といった 単位で受注テーブルを変えてみてはどうでしょうか。 もちろん、PGでは対象となる期間によってアクセスする テーブル名は変更するようにしておきます。
- msystem
- ベストアンサー率42% (79/186)
1万点の商品数ですが、これだけでどの程度のスピードになるかは分かりません。 データベースの種類、索引のつけ方、コンピュータ(CPU、メモリ)ハードディスクの性能、PHPでの処理内容など、処理速度を決める要因は多数あります。(当損データベースへのアクセス方法などにもよります)VanillaTeaさんがおっしゃっていますが、やってみるのが一番だと思います。 いくつかのテーブル分けるということですが、これもよしあしだと考えます。Oracleなどでは、パーティショニングというのが使えますが(これだと、比較的自由度が高い)MySQLやPostgreSQLなどではプログラムで分散させることになると思います。 テーブル分散は、基本はHDDの分散を目的にしています。つまり、テーブルを分散することが目的ではなく、データアクセスのHDDを分散させることが目的です。ということは、HDDをSCSIにしSCSIバスもできるだけ分け、HDDもできるだけ多く取り付け、それぞれのテーブルにできるだけアクセスが均等になるようなキーを見つけることが重要なポイントになります。このあたりを考慮していただければ、比較的に容易にどのように分けるかは分かると思います。(当然データ分析は必要になりますが) あと、パフォーマンスを考えるなら、更新系処理と参照系処理を別のコンピュータに分散するというのも、最近の手法になります。 いずれにしても、もともとのテーブル設計(論理設計)をしっかりした後、物理設計になると思います。ひとまとめにして考えると、まず収拾のつかないデータベースになると思います。(VanillaTeaさんの言っているとおり、安定性、可用性も考えてくださいね)
補足
有難う御座います。 皆さん丁寧にお答えいただき感謝しております。 ご回答の中の「更新系処理と参照系処理を別のコンピュータに分散するという…」 ついてですが、処理だけ(CPUだけ)別にして、データベースは共通のHDDということでしょうか? よろしければ教えて下さい。
- VanillaTea
- ベストアンサー率52% (13/25)
結局、環境次第なんで、やってみないと分からない、って結論になるのでは? 心配なら、DBに何万件かのデータぶち込んで、プロトタイプのプログラム組む なりしてデータ取ってみては?目標のレスポンス得られるか調べればいい。 CPU能力やメモリをどれだけ強化すれば、どれだけパフォーマンスが上がるか の簡単な目安になるし、なにより、安心できるでしょう。 あれこれ想像して心配してるより。 「性能の分析のためにプロトタイプ作ります。今しかありません。一週間ください」と強気で。 一週間は言い値なので、開発期間、工数、人員などにより適宜。 中規模でもDBの分散、Applicationの分散、Web Serverの分散、これらが 見かけ上1個に振舞うプラットフォームを使うケースが増えてるのでは? (後の拡張を考えて) servlet(Java)での開発では普及してますが、PHPだとどうでしょうかねえ。 それと、MySQL、PostgreSQLの最大データサイズ(tableやら行やらトータルやら) versionによっても異なります。分散化はできないかな。 速度だけに注目してますが、安定度も重要ではないですか?障害の起こりにくさ、 障害時の復旧、バックアップなど、性能についてだけでも考えなければならない ことはたくさんあります。 どんなに件数が増えようと、1テーブルとして扱ったほうがいいです。 本来、DBがやるべきことを特殊な設計で逃れようとすることは、後から手がつ けられない事態になるのが想像できます。DBの能力にまかせるべきというか。 あとは明らかに遅くなるSQLを書かないこととか。 MySQLはライセンスに注意してください。 支離滅裂ですが、思いつくままに書いてみました。
補足
有難うございます。 お答えいただきとても嬉しく思っております。 参考になりました。 ちょっとお聞きしたいのですが、 セッション管理のDBで1テーブルの件数を限定し、それ以上超えたら別のセッションテーブルに保存するという話を聞いたことがあるのですが、この場合のメリットが 私にはよくわからなかったのですが、メリットはあるのでしょうか? また、MySQLはフリーライセンスではないのですか?
お礼
VanillaTeaさん、msystemさん、cse_ri2さん、みなさん有難うございました。 とても参考になりました。 今の自分には、手一杯の知識なので、いろいろ試してみたいと思います。 また機会がありましたら宜しくお願い致します。