php-データベース情報を配列として保存
どちらが良い習慣ですか?データをコンマ区切りのリストとしてデータベースに保存するには、または複数の行を使用するには?
アカウント、クラス、登録のテーブルがあります。 登録テーブルにID、AccountID、ClassIDの3つのフィールドがある場合、ClassIDは、「24,21,182,12」のようにコンマ区切りのリストを含むvarcharにするか、単なるintで1つ持つ方がよいでしょう。登録ごとのエントリ?
答え :
解決策:
tldr:これを行わないでください。つまり、ここでは「パック配列」を使用しないでください。
「複数行」で正しく正規化された設計を使用します。これは、多対多の関係の良い候補となる可能性があります。この構造を検討してください:
Classes 1:M Enrollments(Class,Student) M:1 Students
適切に正規化された設計に従うと、痛みが軽減されます。さらに、他にもいくつかの利点があります。
- 参照整合性(InnoDBを使用)
- 関係で記述された一貫性のあるモデル
- タイプエンフォースメント(
"foo,,"
を使用することはできません) - カスタムコードを必要とせずに結合してクエリを実行する
- 「クラスAの生徒の名前は何ですか?」
- 「複数のクラスを受講しているのは誰ですか?」
- 列はインデックス付けに役立ちます(クエリパフォーマンス)
- 一般的に、コードでローカルに処理するよりも高速です
- より柔軟で一貫性のある
- ステータスなどの属性を登録に添付できます
- アクセスサイトでシリアル化を処理するためのコードは必要ありません
- プレースホルダーとORMの収容の強化
答え :
解決策:
コンマや固定長の部分文字列などのある種の区切り文字と組み合わせて、複数の値を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_idreferencesclass」と言うことができ、データベースエンジンは不正な値を入力しないことを保証します。マッシュでは、そのような無料の検証はありません。
答え :
解決策:
両方を実行しましたが、情報をコンマで区切ってデータベースに保存する代わりに、 |
などの別の区切り文字を使用します。 (データベースに挿入する際のフォーマットについて心配する必要がないように)。データをクエリする頻度についての詳細
答え :
解決策:
完全なリストのみが必要な場合は、コンマ区切りの値として保存することをお勧めします。ただし、リストをクエリする必要がある場合は、個別に保存する必要があります。
同様の質問
私たちのウェブサイトで同様の質問で答えを見つけてください。