この質問が以前に何度か尋ねられたことは知っていますが、私の質問は私の状況に固有のものです。
通知マイクロサービスを実装しています。 email
テーブルとqueue
テーブルがあります。サービスはREST APIを使用して公開されます。各メールには複数のto
アドレスとcc
アドレスを含めることができます。キューにはメールIDがあります。メールが送信されると送信されると、行はキューから削除されます。
現時点では、誰がどのメールを送信したか、または特定のユーザーのメールアドレスが指定されたメールが送信されたかどうかを問い合わせるno要件があります。メールアドレスをどのように/ ccで保存できるかについては、いくつかのアイデアがあります。
{
toList: ['h@h','g@g'],
ccList: ['a@b','c@d']
}
MySQL 5.7のJSONデータ型の使用を検討しましたが、統合テストに使用するh2dbではサポートされていません。
toList
テーブルのccList
、email
列にカンマ区切り値として格納します。
それらをemail
、emailaddress
、emailaddresstype
などのリレーショナルテーブルに保存します。emailaddress
テーブルにはemailid
、メールアドレス、 emailaddressstypeid
。これにより、emailaddress
テーブルに複数のレコードが作成され、複数の結合も作成されます。
この場合、実装する最適なソリューションは何ですか?私は一般的にFNFに違反することに反対しており、emailaddress
テーブルに非常に多くのレコード(たとえば、2〜3人に送信されるすべての電子メールのレコード)があることの意味がわかりません。重要な場合、このシステムにはuser
テーブルはありません。
それは本当にあなたがデータをどうするつもりかによって決まると思います。電子メールアドレスが文字列のリストにすぎない場合は、別の場所で取得して操作します。別の列( "to"、 "cc"、 "bcc")のコンマ区切りの文字列はおそらく問題ありません。
ある時点でクエリを実行し、「メール#1234でCCされたが、返信メッセージ(#5678)ではCCされなかったのは誰ですか?」単純なコンマ区切りのリストでそれを行うのは難しいかもしれません。その場合、電子メールアドレスを適切に格納するために、別のテーブルを使用する必要があります。
単一の列にカンマ区切り値を格納するのは良いですか
一般的に言えば、いいえ。
より大きなフィールドに埋め込まれた区切られたデータ値にアクセスすると、一般にアプリケーションのパフォーマンスが[非常に]低下します。インデックスを有効に使用できないため、ほとんどの場合「テーブルスキャン」になります。
現時点では、誰がどのメールを送信したか、または特定のユーザーのメールアドレスが指定されたメールが送信されたかどうかを照会する必要はありません。
あなたはラッキーです。
[クレーム]から送信された電子メールを受信していないと主張するユーザーとの論争が始まるまで待ちます。その時点で、クエリを開始しますhave。さて、それらのクエリがテーブルスキャンである場合、それらのいくつかを実行するだけで世界の終わりではありませんが、この種のことが一般的になるとすぐに、より賢明なデータ構造に移行する必要があります。
OK、この種の使用法への準備は開発者の「YAGNI」のマントラに直面していますが、DBAが頻繁にhavingを見つけて、はるかに長期間のビューを取得し、データ構造を確認します彼らが実装することは可能な限り柔軟です。賢明な正規化は、その方向への大きな一歩です。
説得力のある理由でない限り、データは正規化された形式(オプション3)で保存する必要があります。オプション1と2のような非正規化データには、いくつかの欠点があります。矛盾のリスク、解析とクエリの難しさなどです。
あなたはシステムをより複雑でもろくしているので、そうするための十分な理由が必要です。正当な理由としては、パフォーマンス上の理由で複雑なデータ構造をキャッシュしたり、アプリケーションから見えない任意のデータを保存したりすることが考えられます。
ただし、正規化されていないデータを正当化する特定の理由については言及しないので、3に進んでください。
(オプション3の欠点は、テーブルと結合の数が増えることです。ただし、他のオプションと同じ量のデータと基礎となる構造があるため、これはあまり便利でなく最適化された方法で格納されるだけです。 )
Bill Karwinが彼の本 "SQL Antipatterns" で論じている最初のアンチパターンはJaywalkingです(交差が回避されるため)。アンチパターンは、コンマ区切り値を個別に使用する必要がある場合(たとえば、テーブルのクエリが複雑になるなど)に、コンマ区切り値を格納することに関連する問題を具体的に示しています。本の章で提供される解決策は簡単です。交差点テーブルを作成します。