良い習慣はどれですか?データをデータベースにカンマ区切りのリストとして保存するか、複数の行を含めるには?
アカウント、クラス、および登録のテーブルがあります。登録テーブルに ID、AccountID、ClassID の 3 つのフィールドがある場合、ClassID は "24,21,182,12" のようなコンマ区切りのリストを含む varchar にするか、単に int にして 1 つ持つほうがよいですか?登録ごとのエントリー?
複数の値をコンマや固定長の部分文字列などの区切り文字と組み合わせて、1 つのデータベース フィールドに詰め込むことは絶対にしないでください。これがストレージ要件またはパフォーマンスに明らかにメリットをもたらすまれなケースでは...ルール#1を参照してください。これまで。
複数の値を 1 つのフィールドに詰め込むと、値の取得と操作を支援するためにデータベース エンジンに組み込まれているすべての優れた機能が無効になります。
たとえば、あなたがこれを持っているとしましょう -- ある種の学生データベースだと思います。
Plan A
student (student_id, account_id, class_id_mash)
Plan B
student (student_id, account_id)
student_class (student_id, class_id)
さて、クラス #27 を受講しているすべての生徒のリストが必要だとしましょう。プランBであなたが書く
select student_id
from student join student_class on student.student_id=student_class.student_id
where class_id=27
簡単。
プランAでどうする?あなたが考えるかもしれません
select student_id
from student
where class_id_mash like '%27%'
しかし、これはクラス 27 のすべての生徒だけでなく、クラス 127 または 272 のすべての生徒も検出します。
さて、どうですか:
select student_id
from student
where class_id_mash like '%,27,%'
127 も 272 も見つかりません。しかし、おっと、27 がたまたまリストの最初または最後のものである場合、両側にコンマがないため、それも見つかりません。
区切り文字に関するルールを追加するか、より複雑な一致式を使用して、これを回避できるかもしれません。しかし、それは不必要に複雑で苦痛を伴います。
そして、それを行ったとしても、クラス ID のすべての検索は、完全な順次検索でなければなりません。フィールドごとに 1 つの値と複数のレコードを使用して、class_id フィールドにインデックスを作成し、高速で効率的な検索を行うことができます。(一部のデータベース エンジンには、テキスト フィールドの途中にインデックスを作成する方法がありますが、簡単な解決策があるのに、なぜ複雑な解決策を検討するのでしょうか?)
class_id を検証するにはどうすればよいですか? 個別のフィールドを使用すると、「class_id はクラスを参照する」と言うことができ、データベース エンジンは不正な値を入力しないことを保証します。マッシュでは、そのような無料の検証はありません。
tldr:これをしないでください。つまり、ここでは「パック配列」を使用しないでください。
「複数行」で正しく正規化された設計を使用します。これは、多対多の関係に適している可能性があります。次の構造を検討してください。
Classes 1:M Enrollments(Class,Student) M:1 Students
適切に正規化された設計に従うと、痛みが軽減されます。さらに、次のような利点もあります。
"foo,,"
)私は両方を実行しましたが、データベースに情報をコンマ区切りで保存する代わりに、次のような別の区切り文字を使用します|
(データベースへの挿入時のフォーマットについて心配しません)。データをクエリする頻度についての詳細
完全なリストのみが必要な場合は、カンマ区切りの値として保存しても問題ありません。ただし、リストを照会する必要がある場合は、それらを別々に保存する必要があります。