0

我的 Web 应用程序允许用户定义1 到 30 封电子邮件(可以是其他任何内容)。这些选项中哪个最好?

1) ...使用分隔符将数据仅存储在一列中,如下所示:

  • [列电子邮件] 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

毫无疑问,第二个是更好的选择。如果您执行第一个(逗号分隔),那么它会否定使用 RDBMS 的优势(在这种情况下,您无法对您的电子邮件运行有效的查询,因此它也可能是一个平面文件)。

于 2012-05-29T03:14:27.823 回答
1

取决于您将如何使用数据以及 30 的数量如何固定。如果快速查询第三个地址或使用 WHERE 子句过滤是一个优势,那么:使用不同的字段;否则,创建列可能不值得。

将数据保存在数据库中仍然具有多个用户同时访问的优势。

于 2012-05-29T03:16:25.970 回答
0

2号比1号好。

但是,您应该考虑获得标准化结构的另一种选择,其中您有一个单独的电子邮件表,其中包含用户记录的外键。如果您想通过电子邮件搜索以查找用户并设置约束以确保没有重复的电子邮件被注册,这将允许您定义索引- 如果您想这样做。

于 2012-05-29T03:17:20.550 回答
0

两者都不是一个很好的选择。

选项 1 是一个糟糕的主意,因为它使通过电子邮件查找用户成为一项复杂且低效的任务。您实际上需要在用户记录中的电子邮件字段上执行全文搜索才能找到一封电子邮件。

IMO,选项 2 确实是一个更糟糕的想法,因为它使任何周围的代码编写起来都非常痛苦。再次假设您需要查找具有值 X 的所有用户。您现在需要枚举 30 列并检查每一列以查看该值是否存在。痛苦!

以这种方式存储数据——一个或多个数据元素——在数据库设计中非常常见,正如 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语句是可选的——没有它,设计也可以工作,但是,该行会导致数据库强制建立关系。例如,如果您尝试插入一条user_emailauser_id为 10 的记录,则必须有一条usera 为 10 的对应记录user_id,否则查询将失败。ON DELETE CASCADE告诉数据库,如果您从表中删除一条记录,与之关联的user所有user_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 地址返回一行。如果您有 5 个用户并且每个用户有 5 个电子邮件地址,则上述查询将返回 25 行。

根据您的应用程序,您可能希望每个用户获得一行,但仍然可以访问所有电子邮件。在这种情况下,您可以尝试一个聚合函数,例如GROUP_CONCAT它将为每个用户返回一行,并带有一个逗号分隔的属于该用户的电子邮件列表:

 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 回答