0

現在、私のウェブサイトには 40 以上のテーブルがあり、MySQL を十分に活用しているとは思えません。私はMoodleに似たウェブサイトを作っています。基本的には、コースごとにグループ化された学生のテストを保持するだけです。

元のテーブル:

courses - Lists all courses (ID, Name)
c_$id   - Lists all the Tests (ID, Name, etc) for course number $id
a_$id   - Lists all questions for the test number $id (Question, A, B, C, D)
g_$id   - Lists all grades for the course with course number $id.
c_a     - Lists course ID and assignment ID pairs ex: (1,2) (1,3) (2,2) (2,3)

テーブル リビジョン 1:

courses   - Lists all courses (ID, Name, etc)
tests     - Lists all tests (ID, Name, etc)
questions - Lists all questions from all tests (ID, Ques, Ans)
grades*   - Lists all grades (studentID, courseID, testID, grade)
students* - Lists all students and their courses (StudentID, courseID)

grades* テーブルは、基本的に 3 つの主キーと 1 つの値です。それについて何かが奇妙に思えます。より良い方法はありますか?学生テーブルについても同様です。どちらも基本的に他のテーブルの接続です。高速検索の主キーは使用できませんか?

元の投稿:

これを再現して MySQL の機能を利用する最も効率的な方法は何ですか?

現在、新しいコースが作成されると、そのコースの新しいテーブルが作成され ( c_$id)、次に各課題のテーブルとそのコースの成績リストが作成されますg_$id。次に、課題を作成するときに新しいa_$idテーブルを作成し、そのコースと課題のペアを に追加しc_aます。

*ほとんどのselectステートメントから「」を削除しLIMIT 1、主キーを選択しているステートメントに「」を追加しました。次は、このOOPの問題を解決することです。

4

1 に答える 1

2

一般に、可能であれば、静的スキーム (テーブルと列の固定セット) に固執することをお勧めします。そのため、接続をテーブル名にエンコードする代わりに、別の列を使用して他のテーブルを参照します。たとえば、各コースのテストを保持する個別のc_$id テーブルの代わりに、列を持つtests テーブルを作成します。テストに入るときに、このテストが属するコースを示す値を入力します。データを取得するときに、次のことができます。course_id course_id

SELECT …
FROM courses, tests
WHERE courses.id = tests.course_id

テーブル名の固定セットのみを使用する利点の 1 つは、実際の値の代わりにプレースホルダー (通常は ) を使用して、PHP コードで準備済みステートメントを使用できることです。クエリを実行するときに値を渡す?ことができ、サーバーはそれらが適切にエスケープされることを保証します。これにより、ほとんどのSQL インジェクション攻撃の問題が回避されます。さらに、同じ準備済みステートメントを異なる値で繰り返し実行すると、クエリを解析、分析、および最適化する必要があるのは 1 回だけであるため、パフォーマンスが向上する可能性があります。

LIMIT 11 つの行しか返さないクエリに追加しても、パフォーマンスが向上する可能性はほとんどありません。MySQL オプティマイザーは主キーを認識しているため、この事実も同様に伝えることができます。これらの行により、クエリの読み取りと保守が少し難しくなる可能性があるため、再度省略することを検討してください。

于 2012-11-06T06:21:07.273 に答える