最初に考えるべきは、データベース エンジンである MyISAM です。データベース エンジンは、MySQL がデータを格納する方法です。MyISAM の詳細については、http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html を参照してください。参照整合性が必要な場合 (推奨)、データベース エンジンを InnoDB ( http://dev.mysql.com/doc/refman/5.0/en/innodb-storage-engine.html ) にする必要があります。InnoDB を使用すると、外部キーを作成し、その外部キーの関係を強制できます (MyISAM では難しい方法であることがわかりました)。MyISAM は、MySQL データベースのデフォルト エンジンです。phpMyAdmin (MySQL および PHP の開発に強く推奨されるツール) を使用している場合は、データベースのエンジン タイプを簡単に変更できます (以下を参照してください:http://www.electrictoolbox.com/mysql-change-table-storage-engine/ )。
そうは言っても、MyISAM と InnoDB データベース エンジンの両方で検索やクエリを実行できます。列にインデックスを付けて検索クエリ (SELECT ステートメント) を高速化することもできますが、INSERT ステートメントにかかる時間が長くなるというトレードオフがあります。データベースがそれほど大きくない場合 (つまり、何百万ものレコード)、顕著な違いは見られないはずです。
デザインに関しては、対処すべきことがいくつかあります。最初に理解する必要があるのは、エンティティ関係図または ERD です。これは、テーブルとそれに対応する関係の図です。
存在できる関係にはいくつかのタイプがあります。多対多の関係は最も複雑で、データベース内で直接生成することはできず、断続的なテーブルで解決する必要があります (例を挙げてさらに説明します)。
1 対 1 の関係は単純です。この例は、すべての従業員のリストを持つ従業員テーブルと、すべての給与のリストを持つ給与テーブルがある場合です。1 人の従業員は 1 つの給与しか持つことができず、1 つの給与は 1 人の従業員にのみ属することができます。
そうは言っても、ミックスに追加するもう1つの要素はカーディナリティです。カーディナリティとは、関係が存在する可能性があるかどうか、または存在する必要があるかどうかを示します。前の従業員の例では、給与と従業員の間に関係がなければなりません (関係がない場合、従業員は支払われない可能性があります)。この関係は次のように解釈されます。従業員には 1 つの給与しかなく、給与には 1 つの従業員しかいない場合もあります (給与は従業員に属さずに存在する可能性があるため)。
「one and only one」というフレーズは、1 対 1 の関係であることを表します。「しなければならない」および「かもしれないし、そうでないかもしれない」というフレーズは、存在する必要がある関係または必要でない関係を指します。これは、従業員テーブルの給与 ID の外部キーを null にすることはできず、給与テーブルには従業員を参照する外部キーがないため、デザインに変換されます。
EMPLOYEE
id PRIMARY KEY
name VARCHAR(100)
salad_id NOT NULL UNIQUE
SALARY
id PRIMARY KEY
amount INTEGER NOT NULL
一対多の関係は、複数の関係を持つ可能性として定義されます。たとえば、ポートフォリオに関連して、クライアントは 1 つ以上のプロジェクトを持っている場合があります。したがって、プロジェクト テーブル client_id の外部キー フィールドは、繰り返される可能性があるため、一意にすることはできません。
多対多の関係は、複数が双方向にできる場合に定義されます。たとえば、正しく表示されているように、プロジェクトには 1 つまたは複数のタグがあり、タグは 1 つまたは複数のプロジェクトに割り当てられている場合があります。したがって、その多対多を解決するには PROJECT_TAGS テーブルが必要です。
あなたの質問に直接対処することに関しては、別のメディア タイプ テーブルを作成する必要があります。プロジェクトが複数のタイプに関連付けられる可能性がある場合は、断続的なテーブルが必要で、フィールドをproject_media_type テーブルを primary_type と呼びます。これにより、プロジェクト タイプを主にそのメディア タイプとして区別できますが、カテゴリでフィルタリングする場合、他のカテゴリに分類される可能性があります。
これにより、再帰的な関係が生まれます。再帰的な関係または media_types を持つ可能性があるため、parent_id というフィールドを追加する必要があります。media_type テーブルの ID を参照して、parent_id に外部キー インデックスを追加します。最上位の親 media_types はすべて、parent_id に null 値を持つため、null を許可する必要があります。したがって、使用できるすべての親 media_types を選択するには:
SELECT * FROM media_type WHERE parent_id IS NULL
次に、各親をループして子を取得するには、次のクエリを使用できます。
SELECT * FROM media_type WHERE parent_id = {$media_type_row->id}
これは再帰関数にする必要があるため、子がなくなるまでループします。階層カテゴリに関連する PHP を使用したこの例は、再帰関数カテゴリ データベースで見ることができます。
これが役に立てば幸いですが、基本的には、データベースの設計とモデリングの学期全体を強調しようとしました。さらに情報が必要な場合は、ERD の例も添付できます。