0

私のWebアプリケーションでは、ユーザーは1〜30通の電子メールを定義できます(他の電子メールでもかまいません)。これらのオプションのどれが最適ですか?

1)...次のように、セパレータを使用して1つの列のみにデータを格納します。

  • [COLUMNメール] peter@ example.com、mary @ example.com、john @ example.com

構造:

メールVARCHAR(1829)

 

2)...または、次のように個別の列を使用してデータを保存します。

  • [COLUMN email1] peter@example.com
  • [COLUMN email2] mary@example.com
  • [COLUMN email3] john@example.com
  • [...]

構造:

email1 VARCHAR(60)
email2 VARCHAR(60)
email3 VARCHAR(60)
[...]
email30 VARCHAR(60)

前もって感謝します。

4

4 に答える 4

1

間違いなく、2番目の方が良い選択肢です。最初の1つ(コンマ区切り)を実行すると、RDBMSを使用する利点が無効になります(この場合、電子メールに対して効率的なクエリを実行できないため、フラットファイルである可能性があります)。

于 2012-05-29T03:14:27.823 に答える
1

データをどのように使用するか、および 30 という量がどの程度固定されているかによって異なります。WHERE 句などを使用して 3 番目のアドレスまたはフィルターをすばやくクエリすることが利点である場合: 個別のフィールドを使用します。そうしないと、列を作成する価値がない可能性があります。

データベースにデータを保持することには、複数のユーザーが同時にアクセスできるという利点があります。

于 2012-05-29T03:16:25.970 に答える
0

ナンバー2はナンバー1よりも優れています。

ただし、ユーザー レコードへの外部キーを持つ別のメール テーブルがある、正規化された構造を取得する別のオプションを検討する必要があります。これにより、電子メールで検索してユーザーを見つけ、重複した電子メールが登録されないように制約を設定したい場合に、インデックスを定義できます。

于 2012-05-29T03:17:20.550 に答える
0

どちらもあまり良い選択肢ではありません。

オプション 1 は、電子メールでユーザーを検索するのが複雑で非効率的な作業になるため、お勧めできません。1 つの電子メールを見つけるには、ユーザー レコードの電子メール フィールドで全文検索を実行する必要があります。

オプション2は、周囲のコードを書くのが非常に面倒になるため、実際には最悪のアイデアです。もう一度、値 X を持つすべてのユーザーを検索する必要があるとします。ここで、30 列を列挙し、それぞれをチェックして、その値が存在するかどうかを確認する必要があります。痛い!

このようにデータを保存する方法 (データの一部の要素の 1 つ以上) は、データベース設計では非常に一般的であり、Adam が以前に述べたように、ほとんどの場合、正規化されたデータ構造を使用して解決するのが最善です。

これはそのようにタグ付けされているため、MySQL で記述された正しいテーブル構造は次のようになります。

ユーザー テーブル:

CREATE TABLE user (
 user_id int auto_increment,
 ...
 PRIMARY KEY (user_id)
);

メールテーブル:

CREATE TABLE user_email (
 user_id int,
 email char(60) not null default '',
 FOREIGN KEY (user_id) REFERENCES user (user_id) ON DELETE CASCADE
);

ステートメントはオプションです。FOREIGN KEY設計はそれがなくても機能しますが、その行により、データベースは関係を強制します。たとえば、a が 10 のレコードを に挿入しようとするuser_emailと、aが 10 の対応するレコードuser_idがなければ、クエリは失敗します。は、テーブルからレコードを削除すると、それに関連付けられているすべてのレコードも削除されることをデータベースに伝えます(この動作が必要な場合とそうでない場合があります)。useruser_idON DELETE CASCADEuseruser_email

もちろん、この設計は、ユーザー レコードを取得するときに結合を実行する必要があることも意味します。次のようなクエリ:

 SELECT user.user_id, user_email.email FROM user LEFT JOIN user_email ON user.user_id = user_email.user_id WHERE <your where clause>;

システムに保存されている user_email アドレスごとに 1 行を返します。5 人のユーザーがいて、各ユーザーが 5 つの電子メール アドレスを持っている場合、上記のクエリは 25 行を返します。

アプリケーションによっては、ユーザーごとに 1 つの行を取得したい場合がありますが、それでもすべてのメールにアクセスできます。その場合、GROUP_CONCATユーザーごとに 1 つの行を返し、そのユーザーに属する電子メールのカンマ区切りのリストを返すような集計関数を試すことができます。

 SELECT user.user_id, GROUP_CONCAT(user_email.email) AS user_emails FROM user LEFT JOIN user_email ON user.user_id = user_email.user_id WHERE <your where clause> GROUP BY user.user_id;

繰り返しますが、アプリケーションによっては、電子メール列にインデックスを追加したい場合があります。

最後に、正規化されたデータベース設計が望ましくない状況がいくつかあります。そのような状況はほとんどありませんが、区切りテキストを使用した単一列の設計がより適切な場合があります。ほとんどの通常のアプリケーションでは、このタイプの正規化された設計が最適であり、パフォーマンスと拡張性を向上させるのに役立ちます。

于 2012-05-29T04:59:00.297 に答える