MySQL列组织

时间:2012-05-29 03:12:05

标签: mysql code-organization

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

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

  • [COLUMN电子邮件] peter @ example.com,mary @ example.com,john @ example.com

结构:

emails 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 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

取决于您将如何使用数据以及30的数量是多少。如果使用WHERE子句快速查询第3个地址或过滤器是有利的:使用distinct fields;否则可能不值得创建列。

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

答案 2 :(得分:0)

2号比第1号好。

但是,您应该考虑获得normalized结构的另一个选项,即您的用户记录中有一个单独的电子邮件表格foreign key。如果您希望通过电子邮件搜索以查找用户并放置index以确保没有注册重复的电子邮件 - 如果您想这样做,则可以定义constraint

答案 3 :(得分:0)

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

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

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

以这种方式存储数据 - 数据的一个或多个数据 - 在数据库设计中非常常见,正如Adam之前提到的,最好通过使用规范化数据结构解决MOST情况。 / p>

一个正确的表结构,用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_email,其中user_id为10,那么必须有一个user记录,其中user_id为10,或者查询将失败。 ON DELETE CASCADE告诉数据库,如果从user表中删除记录,则与其关联的所有user_email记录也将被删除(您可能希望也可能不希望出现此行为)。< / p>

此设计当然也意味着您需要在检索用户记录时执行连接。像这样的查询:

 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>;

将为系统中存储的EACH 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;

同样,根据您的应用程序,您可能希望在电子邮件列中添加索引。

最后,在某些情况下,您不需要标准化的数据库设计,并且带有分隔文本的单列设计可能更合适,尽管这些情况很少而且很远。对于大多数正常应用而言,这种标准化设计是可行的方式,有助于其更好地执行和扩展。