区切り文字で区切られたリストをデータベース列に保存することは本当に悪いことでしょうか?
P粉020556231
2023-08-27 19:52:49
<p>一連のチェックボックス (一部またはすべてを選択可能) がある Web フォームを想像してください。データベーステーブルの列に格納される値のカンマ区切りリストにそれらを保存することにしました。 </p>
<p>これで、正しい解決策は 2 番目のテーブルを作成し、データベースを正しく正規化することであることがわかりました。シンプルなソリューションを実装する方が早いため、あまり時間をかけずにアプリケーションの概念実証を迅速に取得したいと考えています。 </p>
<p>私の場合、時間の節約とコードの簡素化にはそれだけの価値があると思いますが、これは合理的な設計選択でしょうか、それとも最初からこれを標準化すべきでしょうか? </p>
<p>詳しく説明すると、これは基本的に共有フォルダーに保存されている Excel ファイルを置き換える小さな内部アプリケーションです。また、プログラムを整理してメンテナンスを容易にしたいと考えているので、この質問をしています。あまり満足していない点がいくつかあり、そのうちの 1 つがこの質問の主題です。 </p>
「その理由の一つは怠惰です。」
これは警鐘です。このようなことをすべき唯一の理由は、それを「正しい方法」で行う方法を知っている場合ですが、それを行わない明確な理由があると結論付けている場合です。
そうは言っても、この方法で保存することを選択したデータが、クエリを実行する必要がないデータである場合は、選択した方法で保存することもできるかもしれません。
(一部のユーザーは、前段落の私の発言に異議を唱え、「将来どのような要件が追加されるか分からない」と主張します。これらのユーザーは、誤った情報を与えられているか、宗教的信念を表明しているかのどちらかです。時には、ハードワークが前に有利になることがあります。必須です。)
第一正規形に違反することに加えて、重複するグループ値列や単一の値に格納されるカンマ区切りリストには、他にも多くの実用的な問題があります:
各値が正しいデータ型であることを確認できません:- 1,2,3,banana,5 を防ぐことができません
外部キー制約を使用して値をルックアップ テーブルにリンクすることはできません。参照整合性を強制することもできません。 -
一意性を強制できません: ブロックできません- 1,2,3,3,3,5
リスト全体を取得しない限り、リストから値を削除することはできません。 -
保存されたリストの長さは、文字列列の長さを超えることはできません。 -
指定された値を持つリスト内のすべてのエンティティを検索することは困難であり、非効率的なテーブル スキャンを使用する必要があります。 MySQL などでは、正規表現を使用する必要がある場合があります: -
-
値を参照するルックアップ テーブルに接続するのは困難です。 -
リストをソート順に取得するのは困難です。 -
値に含まれないことが保証される区切り文字を選択するのは困難です-
これらの問題を解決するには、大量のアプリケーション コードを作成し、RDBMS がすでに提供しているより効率的な機能を再発明する必要があります。idlist REGEXP '[[:
:]]'<:> または MySQL 8.0 の場合:
idlist REGEXP '\\b2\\b'李>リスト内の要素を数えたり、他の集計クエリを実行したりするのは困難です。
SQL アンチパターン、第 1 巻: データベース プログラミングの落とし穴の回避。
非正規化が必要な場合もありますが、@OMG Ponies が言及したように、これらは例外です。リレーショナル以外の「最適化」は、データの他の用途を犠牲にして、あるタイプのクエリに利益をもたらすため、非正規化に値するように特別な処理が必要なクエリを必ず把握してください。