japan.internet.comThe Internet & IT Network
RSS
  • ニュース
  • コラム
  • リサーチ
  • ヘッドライン
  • 特集
  • ブログ
  • プレスリリース
  • 専門チャンネル
  • イベント
  • ランキング
  • ニュースメール
2008年9月6日
文字サイズ文字サイズ小文字サイズ中文字サイズ大
デベロッパー2007年10月9日 13:30

MySQLのシステムアーキテクチャ

海外海外internet.com発の記事
  • このエントリーを含むはてなブックマーク
  • この記事をクリップ!
  • Buzzurlにブックマーク
  • Yahoo!ブックマークに登録
  • newsing it!

はじめに

 本稿では、MySQLの内部構造を見ていきます。MySQLサーバのさまざまな部分がどのように連携して動いているかを知ることは、楽しくてためになります。MySQLの実装は、テクノロジーの魅惑的な組み合わせです。このテクノロジーは、おびただしい数の開発者の長年にわたる汗とインスピレーションから生み出された、真に目覚ましい功績にほかなりません。

 オープンソーステクノロジーの楽しみの1つは、それがオープンソースであるという、まさにその点にあります。MySQLのような巨大なシステムのソースコード(※1)を見ると、そのソフトウェアの進化の過程で開発者たちが直面したジレンマを深く理解することができます。本稿では、サーバ自体のソースコードを詳細に検討していくので、どうぞ心してお読みください。たとえ何も手を加えるつもりがなくても、ソースコードを見てみることをお勧めします。それによって、MySQL ABの開発チームが取り組んでいる作業の途方もない大きさを認識できるようになるだけでなく、このソフトウェアがどのように機能しているか、ひいてはMySQLの長所を最大限に活用し、弱点を回避するために自分のプログラムをどのように最適化すればよいかをより深く理解できます。

※1
 執筆時点で、MySQLサーバはざっと50万行のソースコードで構成されています。

 本稿で説明する内容は、MySQLデータベースサーバーシステムの内部構造のドキュメント、および実際のソースコードが基になっています。MySQLのコードリポジトリは絶えず進化しているので、ここで説明するデザイン機能の一部は現在では変化している可能性があり、今後も時間の経過とともに変化し続けると思われます。バージョンの異なるソースコードを見比べると、サブシステムの実装や相互関連の方法に違いがあることに気付くでしょう。しかし、システムの全般的な機能の大部分は、ソフトウェアの進化を通じて維持されています。

 ここで扱う内容の大部分は、Cプログラミングの達人でなくても理解できるはずです。ここではコード自体よりも、サーバ内部の処理の構造と流れや、さまざまなコードライブラリが互いにやりとりするしくみに重点を置きます。本稿の目的は、読者が自分でソースコードやドキュメントを見て回れるように、基本的なロードマップを示すことです。ただし、一部のセクションには、CおよびC++プログラミングのかなりの知識を必要とする上級者向けの内容も含まれます。Cプログラミングの経験が浅い読者は、あまり気にせずに、できる範囲で理解するよう努めてください。

MySQLのソースコードとドキュメント

 ここではMySQLサーバのソースコードを扱うので、本稿の説明を理解し、自らコード調査の冒険に乗り出すために、MySQLの最新のソースコードをダウンロードする必要があります。本稿で使うソースコードは、バージョン5.0.2のソースコードが基になっています。ソースコードをダウンロードするには、MySQLのダウンロードサイトにアクセスし、目的のバージョンをダウンロードします。

注意
 本稿で分析に使ったソース配布物は、5.0.2-alphaソースツリーから取得したものです。MySQLは絶えず進化しているソフトウェアであるため、本稿で説明しているさまざまな実装の詳細は、時間の経過とともに変化する可能性があります。必ず適切なバージョンのソースの開発ドキュメントを入手してください。

ソースコード

 ソースコードは、MySQLサーバの主要なライブラリと、各種の拡張機能が含まれる浅いディレクトリツリーで構成されます。

トップレベルのディレクトリ

 表1に、トップレベルの主要なすべてのディレクトリと、各ディレクトリにあるファイルの簡単な説明、およびファイルの一般的な用途を示します。以降の説明では、この表に示す情報を、各サブシステムに関連するより小さなグループに分類していきます。この大きな表をリファレンスとして使用するとよいでしょう。

表1 ソースツリーのトップレベルのディレクトリ
ディレクトリ内容
/bdbBerkeley DBストレージエンジンハンドラの実装ファイル
/BUILDプログラムコンパイルファイル
/clientmysqlコマンドツール(クライアントプログラム)の実装ファイル
/datamysqlデータベース(システムデータベース)のスキーマ、データ、およびインデックスファイル
/dbugデバッグ用のユーティリティコード
/Docsドキュメント(内部構造の開発者用ドキュメントとMySQLオンラインマニュアル)
/heapMEMORYストレージエンジンハンドラの実装ファイル
/includeコアシステムのヘッダーファイルおよび型定義
/innobaseInnoDBストレージエンジンハンドラの実装ファイル
/isam古いISAMストレージエンジンハンドラの実装ファイル
/libmysqlMySQL CクライアントAPI(すべてのCソースファイルおよびヘッダーファイル)
/libmysqldMySQLサーバーコアライブラリ(C、C++、および一部のヘッダーファイル)
/libmysqltestMySQLのテスト用の簡単なプログラム
/merge古いMergeストレージエンジンハンドラの実装ファイル
/myisamMyISAMストレージエンジンハンドラの実装ファイル
/myisammrgMyISAM Mergeストレージエンジンハンドラの実装ファイル
/mysysコア関数ライブラリ、および低レベルの基本関数
/regex正規表現関数ライブラリ
/scripts共通ユーティリティのシェルスクリプト
/share国際化されたエラーメッセージ
/sqlサーバの実装の本体、およびサーバとクライアントのすべての主要な処理のコアクラスと実装
/sql-benchMySQLのベンチマーク用シェルスクリプト
/strings低レベルの文字列処理関数
/support-files設定済みのMySQL設定ファイル(my-huge. cnfなど)
/testsテストプログラムとスクリプト
/vioネットワーク/ソケットユーティリティ機能、仮想I/O、SSLなど
/zlib圧縮機能のソースファイル

 ここで少し時間を取り、ソースコードを見て回って楽しんでもかまいませんが、きっとすぐにソース配布物を構成するクラス、構造体、およびC関数の迷路で迷子になってしまうでしょう。最初に参照すべき場所は、/Docsディレクトリにある配布物のドキュメントです。その後で、本稿の説明に従って主要なサブシステムや、さまざまなシステム機能に対応するコアファイルがある場所を見ていきます。

CおよびC++のプログラミング用語

 本稿では、CおよびC++のさまざまなプログラミングパラダイムを扱います。Cのソースコードファイルは、配布物の中で「.c」という拡張子が付いているファイルです。C++のソースファイルには「.cc」という拡張子が付いていますが、Windowsの一部のシステムでは「.cpp」という拡張子が付いている場合もあります。CとC++のどちらのソースファイルでも、「.h」という拡張子を持つヘッダーファイルを#includeディレクティブでインクルードすることができます。CおよびC++では、ソースファイルで使用する関数と変数をヘッダーファイルで定義するのが習わしになっています。

 通常、ヘッダーファイルにはソースファイルと同じ名前を付けて「.h」という拡張子を付けますが、必ずしもそうでないこともあります。システムのソースコードを見るときに最初にすることの1つは、変数と関数が「どこで」定義されているかを確認することです。ときには、ヘッダーファイルの広大な階層を調べて、変数や関数がどこで公式に定義されているかを見つけることが必要になります。

 当然、読者は変数や関数がどのようなものかをよく知っているはずなので、ここではあまり詳しく解説しません。ただし、CおよびC++のプログラミングでは、それ以外のデータ型と用語が頻繁に使われます。特に、本稿では次の用語を使います。

  • 構造体
  • クラス
  • メンバ変数
  • メンバメソッド

 「構造体」は、本質的に一連のデータのコンテナです。構造体は一般に次のような形で定義されます。

typedef struct st_heapinfo /* Struct heap_info */
{
   ulong records; /* Records in database */
   ulong deleted; /* Deleted records in database */
   ulong max_records;
   ulong data_length;
   ulong index_length;
   uint reclength; /* Length of one record */
   int errkey;
   ulonglong auto_increment;
} HEAPINFO;

 ここに示したのは、/include/heap.hで定義されている構造体です。ここでは、struct (st_heapinfo)を構成するさまざまなデータ型のメンバ変数(recordsmax_recordsなど)をいくつか定義し、このst_heapinfo構造体をHEAPINFOという別名で表すことをtypedefで定義しています。Cコードのコメントは、//または/* ... */という文字で表します。

 一方、「クラス」はCの構造体に似たC++のオブジェクト指向構造ですが、「メンバ変数」の他に「メンバメソッド」を持つことができます。メンバメソッドはクラスの関数で、クラスの「インスタンス」を通じて呼び出すことができます。

ソースコードの分析に役立つDoxygen

 ソースコードの分析には、Doxygenなどのツールを使うことをお勧めします。Doxygenを使うと、ソース配布物からコードの構造を調べることができます。このツールは、MySQLのように、1つの実行処理で何百ものクラスメンバと関数を呼び出す巨大なソース配布物の関数を調査するのにきわめて有効です。ドキュメント形式の出力を見ると、クラスや構造体がどこで定義され、どこで実装されているかがわかります。

 Doxygenでは、このツールで生成されるドキュメントの出力形式を必要に応じて設定でき、UMLの継承図やコラボレーション図を生成することさえできます。ソースコード内のクラス階層を示すだけでなく、関数が定義および実装されている場所へのリンクも生成できます。

 Unixマシンでは、DoxygenのWebサイトからソースコードをダウンロードし、手順に従ってインストールします(インストール方法の説明もWebサイトから入手できます)。グラフィカルな出力を生成するには、先にGraph Visualizationツールキットをhttp://www.graphviz.org/からダウンロードしてインストールします。Doxygenをインストールしたら、次のコマンドを実行し、Doxygenが処理するデフォルトの設定ファイルを作成します。

# doxygen -g -s /path/to/newconfig.file

 /path/to/newconfig.fileオプションには、Doxygenのドキュメントの生成先となるディレクトリを指定します。設定ファイルが作成されたら、好みのエディタで設定ファイルを開き、必要なセクションを編集します。変更する必要があるのは、通常はOUTPUT_DIRECTORYINPUT、およびPROJECT_NAMEの設定だけです。設定ファイルを編集したら、次のコマンドを実行します。

# doxygen </path/to/config-file>

 参考のために、MySQL 5.0.2のDoxygenの出力例をhttp://www.jpipes.com/mysqldox/で公開しています。

MySQLのドキュメント

 システムの内部構造のドキュメントは、MySQLのソースコードをダウンロードすると利用できるようになります。ファイルはソースツリーのDocsディレクトリにあり、「internals.texi」というTEXIドキュメントになっています。

 このTEXIドキュメントでは、次のトピックが詳しく説明されています。

  • コーディングのガイドライン
  • オプティマイザ(必読)
  • 重要なアルゴリズムと構造
  • 文字セットとそれに関連する問題
  • MySQLがさまざまなSELECT処理を実行する方法(必読)
  • MySQLがクエリを変換する方法
  • 通信プロトコル
  • レプリケーション
  • MyISAMのレコード構造
  • .MYIファイル構造
  • InnoDBのレコード構造
  • InnoDBのページ構造

 内部構造のドキュメントは、サーバの特定の主要な要素(特にクエリオプティマイザ)を調べるうえで非常に役立ちますが、各サブシステムが相互にやりとりする方法には直接触れていないことに注意してください。このやりとりの方法を調べるには、ソースコード自体と開発者のコメントを確認する必要があります(※2)。

※2
 サブシステムの通信の変化に対応できるように、開発者が通信に関する説明を意図的に省いたかどうかが議論を呼ぶところです。
注意
 最新の「internals.texi」ドキュメントにも、誤ったハイパーリンク、参照、および不正確なファイル名やパスが数多く含まれるため、すべての内容をそのまま受け入れずにきちんと確認する必要があります。「internals.texi」ドキュメントは、使用しているMySQLサーバのバージョンよりも古いことがあります。

TEXIおよびtexi2htmlの表示

 TEXIはGNU標準ドキュメント形式です。さまざまなユーティリティを使い、TEXIのソースドキュメントを他の(おそらくもっと読みやすくて移植性のある)形式に変換することができます。Emacsやそれに類するエディタでは、TEXI形式を読みやすくするTEXIメジャーモードがサポートされています。

 HTML形式で表示したければ、texi2htmlという無料のPerlベースのユーティリティを利用できます。このユーティリティでは、TEXIのソースドキュメントから、非常に柔軟な設定ができるHTML出力を生成できます。texi2htmlはhttp://cvs.savannah.gnu.org/viewvc/texi2html/texi2html/からダウンロードできます。このユーティリティをダウンロードしたら、次のような方法でインストールします。

# tar -xzvf texi2html-1.76.tar.gz
# cd texi2html-1.6
# ./configure
# make install

 ここでは、執筆時点の最新版のtexi2htmlを展開し、Linuxシステムにインストールしています。次に、ソース配布物に含まれる「internals.texi」ドキュメントのHTML版を生成します。

# cd /path/to/mysql-5.0.2-alpha/
# texi2html Docs/internals.texi

 このコマンドを実行すると、ソースツリーの/Docsディレクトリに「internals.html」という新しいHTMLドキュメントが生成されます。これで、内部構造のドキュメントをWebブラウザで参照できるようになります。参考のために、このHTMLドキュメントもhttp://www.jpipes.com/で公開しています。

MySQLのアーキテクチャの概要

 MySQLのアーキテクチャは、相互に関連する関数セットの集まりで構成されます。これらが連携し、データベースサーバのさまざまな要求を満たします。多くの著者が、これらの関数セットは実際にはコンポーネント、つまり完全にカプセル化されたパッケージであることを示唆しています(※3)。しかし、ソースコードにはこれが事実であることを示す証拠はほとんどありません。

※3
 たとえば、Vikram Vaswani著『MySQL: The Complete Reference』(McGraw-Hill/Osborne)やhttp://wiki.cs.uiuc.edu/cs427/High-Level+Component+Diagram+of+the+MySQL+Architectureを参照してください。

 たしかに、このアーキテクチャには類似のタスクを処理する関数から成る独立した関数ライブラリが含まれています。しかし、従来のオブジェクト指向プログラミングの意味での、完全なコンポーネントレベルの機能の分離は行われていません。ですから、ソースコードでBufferManagerやQueryManagerというクラスを探しても期待を裏切られることになります。そのようなクラスは存在しないからです。一部の開発者、特にJavaの経験を持つ開発者にとっては、クライアントオブジェクトの要求をオブジェクト中心のアプローチで満たすために各種の「マネージャ」オブジェクトを含むコードを書くのが普通のことになっていますが、MySQLでは状況が異なります。

 場合によっては、特にクエリキャッシュやログ管理サブシステムのソースコードでは、オブジェクト指向に近いアプローチを取っていることがあります。しかしほとんどの場合、MySQLのシステム機能は、各種の関数ライブラリ(構造体のコアセットの引渡しを担当)とクラス(コード実行の詳細を担当)を通じて実行されます。カプセル化されたアプローチのような、コンポーネント自身が内部の実行を管理し、他のコンポーネントに対してAPIを提供するという形は取りません。

 その理由の1つとして、システムアーキテクチャが複数の言語で書かれており、CとC++の両方のソースファイル、およびユーティリティとして機能する多数のPerlおよびシェルスクリプトで構成されていることが挙げられます。CとC++では機能上の特性が異なります。C++は完全なオブジェクト指向言語で、Cは手続き型に近い言語です。MySQLのシステムアーキテクチャでは、特定のライブラリがすべてCで書かれているため、オブジェクト指向のコンポーネント型のアーキテクチャを実現することはほぼ不可能です。もちろん、サーバーサブシステムのアーキテクチャはパフォーマンスと移植性の問題にも大きくかかわっています。

メモ
 MySQLは絶えず進化しているソフトウェアなので、コーディングや命名のスタイルと整合性にばらつきがあります。たとえば、古いMyISAMハンドラファイルと新しいクエリキャッシュのソースファイルを見比べると、命名規則、開発者のコメントの付け方、および関数名の基準に著しい違いがあることがわかります。しかも、本書の印刷間際になって、MySQL 5.1ではディレクトリ構造とソースレイアウトが大幅に変更されるという噂が流れています。

 さらに、ソースコードや内部構造のドキュメントを分析すると、コンポーネントやパッケージについて言及されている部分がほとんどないことがわかります(※4)。代わりに、さまざまなタスク関連の機能についての記述が見つかります。たとえば、内部構造のTEXIドキュメントでは「オプティマイザ」に言及していますが、ソースコードにはOptimizerという名前のコンポーネントもパッケージもありません。代わりに、内部構造のTEXIドキュメントには、「オプティマイザは、RDBMSでクエリ用にどの実行パスを選択すべきかを判断する一連のルーチンである」と記載されています。わかりやすくするために、ここでは関連する一連の各機能を「コンポーネント」ではなく「サブシステム」と呼ぶことにします。そのほうが、さまざまな関数ライブラリの構成をより正確に表しているように思われるからです。

※4
 /sql/mysqld.cppのinit_server_components()関数は奇妙な例外です。ただし実際には、このメソッドはいくつかの機能サブシステムの起動時に実行され、ストレージハンドラとコアバッファを初期化します。

 各サブシステムは、サーバの他のサブシステムからの情報を受け付けるとともに、他のサブシステムにデータを提供するように設計されています。これを標準的な方法で行うために、これらのサブシステムは明確に定義された「関数アプリケーションプログラミングインターフェイス(API)」を通じてこの機能を公開します(※5)。サーバのパイプラインを通じて要求とデータが送られると、サブシステムはこれらの明確に定義された関数とデータ構造を介して相互に情報をやりとりします。ここでは、それぞれの主要なサブシステムについて考察しながら、これらのデータ構造とメソッドの一部を見ていきます。

※5
 この抽象化により、通常は、関連する関数セットが相互に疎結合(つまり依存)するようになります。いくつかの例外を除き、MySQLのコンポーネントはおおむね疎結合です。

MySQLサーバのサブシステムの構成

 MySQLサーバーアーキテクチャの全体の構成は、レイヤー型ではあるものの、特に階層型ではない構造をしています。ここでこのような区別をしているのは、MySQLサーバーアーキテクチャのサブシステムが互いにまったく依存していないからです。

 階層型の構成では、コンポーネントがツリー状の一連のクラスから派生するため、サブシステムは互いに依存して機能します。たしかに、一部のサブシステム(特にSQL解析および最適化サブシステム)内にはツリー状のクラスの構成がありますが、サブシステム自体は階層型の配置に従っていません。

 基本関数ライブラリおよびサブシステムの特定のグループは、低レベルの処理を担っています。これらのライブラリとサブシステムは、ストレージエンジンシステムの抽象化をサポートする役目を果たしています。ストレージエンジンシステムは、要求側のクライアントプログラムにデータを提供します。図1に、このレイヤー構造の全体図とそれらのサブシステムを示します。

 クライアントプログラムがストレージエンジンの抽象化されたAPIとやりとりしている点に注意してください。これにより、クライアント接続はストレージエンジンに依存しないステートメントを発行することができます。つまり、クライアントはどのストレージエンジンがデータ要求を処理しているかを知る必要がありません。InnoDBとMyISAMのどちらのレコードを取得する場合でも、クライアントに特別な機能は必要ありません。このしくみのおかげで、MySQLではさまざまなストレージ要件とメディアに合わせて機能を拡張することができます。

図1 MySQLのサブシステムの概要
図1 MySQLのサブシステムの概要

基本関数ライブラリ

 MySQLのすべてのサブシステムは、共通関数の基本ライブラリを共有して使います。これらの関数の多くは、サブシステム(および開発者)がオペレーティングシステム、メインメモリ、または物理的なハードウェア自体を直接操作せずに済むようにするために存在しています(※6)。さらに、基本関数ライブラリによって、コードの再利用と移植が可能になります。この基本ライブラリの大部分の関数は、/mysysおよび/stringsディレクトリのCソースファイルにあります。表2に、この基本ライブラリのコアファイルと場所の一部を示します。

表2 関数の一部のコアファイル
ファイル内容
/mysys/array.c動的配列の関数と定義
/mysys/hash.c/.hハッシュテーブルの関数と定義
/mysys/mf_qsort.cクイックソートのアルゴリズムと関数
/mysys/string.c動的文字列の関数
/mysys/my_alloc.cいくつかのメモリ割り当てルーチン
/mysys/mf_pack.cファイル名およびディレクトリパスのパッキングルーチン
/strings/*低レベルの文字列およびメモリ操作の関数、およびいくつかのデータ型の定義
※6
 ただし、特定のコンポーネントやライブラリは、パフォーマンスやその他のメリットを実感できる場面では、引き続きオペレーティングシステムやハードウェアを直接操作することになるでしょう。

まとめ

 データベースサーバの内部構造の世界への小旅行をお楽しみいただいたでしょうか。本稿では、MySQLのソースコードを手に入れる方法と、ドキュメントをさまざまな形式で設定および取得する方法を紹介しました。次に、サーバのサブシステムの全体的な構成の概要について説明しました。

 本稿はMichael Kruckenberg、Jay Pipes共著『Pro MySQL』(Apress、2005年7月、ISBN:159059505X)第4章からの転載です。出版社の許可を得て転載しています。

著者紹介

Mike Kruckenberg(Mike Kruckenberg)
古くからのMySQLの愛好者で、Webベースのアプリケーションの初期の時代からMySQLを公私ともに利用してきた。本業で長年にわたってMySQL全般の大黒柱となってきただけでなく、MySQLコミュニティの活発なメンバーでもある。『Pro MySQL』の共同執筆の他に、『MySQL Cluster Certification Study Guide』の共同執筆もしており、『Linux Magazine』誌ではMySQL関連の記事を定期的に書いている。MySQLのソースコードの変更を扱った近日刊行予定の書籍『Expert MySQL』(Apress)では技術レビューを担当。「MySQL Speakers, Writers, and Experts Guilds」のメンバーとして、技術カンファレンスで定期的に講演を行い、mike.kruckenberg.comではMySQLやその他の(大半は)技術的な事柄について精力的に記事を書いている。
Jay Pipes(Jay Pipes)
MySQLのNorth American Community Relations Manager。『Pro MySQL』(Apress、2005年)の共同執筆者で、『Linux Magazine』誌でも記事を書いている。また、ソフトウェア開発者がMySQLを最も有効に活用する方法を見いだすための支援を定期的に行っている。MySQL Users Conference、RedHat Summit、NY PHP Conference、OSCON、Ohio LinuxFestなどで、パフォーマンスチューニングに関する会議を開催してきた。現在は妻のJulie、および4匹のペットとともにオハイオ州コロンバスに在住。ありあまるほどの自由時間に、腹を空かした2匹の猫と騒がしい2匹の犬に邪魔されていなければ、PHPコードの空想にふけり、_clone()の分岐について熟考している。
最新トップニュース
データメーション
【データメーション】
OSについて気に入らないこと(9月5日)
ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」
【ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」】
「導入期〜成長期へ!一歩一歩と前進を目指す『Annoii(アノイ)』」/maka hou,Inc.(9月5日)
最新テクノロジーの意外な処方箋
【最新テクノロジーの意外な処方箋】
グリッドコンピューティング技術でETに遭遇(9月5日)
Graphic Design Forum
【Graphic Design Forum】
古い Emigre を探して (9月3日)
エンジニアの独り言
【エンジニアの独り言】
データをローカルに保存するWebアプリケーション(8月22日)
デスマーチからの脱却
【デスマーチからの脱却】
30min. iPhoneアプリリリース(8月18日)
最新ハイテク講座
最新ハイテク講座
なぜ勝った? 世界No.1シェアをつかんだ“Windows”(9月5日)
developer.com
developer.com
デザインパターンの使い方: Composite(9月5日)
最新アフィリエイト事例にみる成功の法則
最新アフィリエイト事例にみる成功の法則
コンバージョンレートを高めよう!(9月5日)
百式のネットビジネス研究
百式のネットビジネス研究
ガジェット購入時に将来の買取保証プランを提供する「TechForward」(9月5日)
週刊-サイト別アクセス状況データ
週刊-サイト別アクセス状況データ
ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(9月4日)
「IT の耳」
「IT の耳」
【書評】『検索にガンガンヒットさせる SEO の教科書』――SEO テクニックで効果的に PR する(9月4日)
検索エンジンマーケティング
検索エンジンマーケティング
果たしてモバイル SEO は必要なのか?(9月4日)
Eメールマーケティング事情
Eメールマーケティング事情
読者が迷惑メールと認識する時…(9月3日)
日本と韓国のインターネットビジネス最新動向調査
日本と韓国のインターネットビジネス最新動向調査
日本と韓国の動画サイト比較1―現状(9月3日)
SNSをビジネスに活用しよう
SNSをビジネスに活用しよう
「しまじろう」に学ぶ企業内コミュニティの活性化のポイント(9月2日)
海外のインターネットコムアメリカ韓国ドイツトルコ
Copyright 2008 Jupitermedia Corporation All Rights Reserved.http://www.internet.com/