2012-05-29 109 views
0

我的web应用程序允许用户定义从1到30封电子邮件(可能是其他任何东西)。 以下哪个选项最好?MySQL列组织

1)...用的隔板,这样存储该数据只有一列内:

  • [COLUMN电子邮件]彼得@ example.com,玛丽@ example.com,约翰@例子。 COM

结构:

emails VARCHAR(1829)

 

2)...或保存使用不同的栏目,像这样的数据:

结构:

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

预先感谢您。

回答

1

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

使数据库中的数据仍具有多个用户同时访问的优点。

1

第二个是更好的选择,没有问题。如果你做第一个(逗号分隔),那么它会否定使用RDBMS的优点(在这种情况下,你不能对你的电子邮件进行有效的查询,因此它可能是一个平面文件)。

+0

我会强烈反对,第二个是一个很好的选择,甚至可能不是比第一个更好的选择。从应用程序设计的角度来看,甚至从性能的角度来看,为一个值检查30个不同的列是一场噩梦。 – futureal

0

2号比1号好。

但是,你应该在哪里你有一个foreign key一个单独的电子邮件表格您的用户记录考虑让normalized结构的另一种选择。如果您想通过电子邮件搜索以找到用户并将constraint确保没有注册重复的电子邮件 - 如果您想这样做,这将允许您定义index

0

两者都不是很好的选择。

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

选项2实际上是一个WORSE的想法,海事组织,因为它使任何周围的代码写一个巨大的痛苦。再次假设您需要查找所有具有值X的用户。现在需要枚举30列并检查每列,以确定该值是否存在。痛苦!以这种方式

存储数据 - 1或更多的数据的一些元件的 - 是在数据库设计很常见的,并且如先前亚当提到,最好是在大多数情况下,通过使用归一化的数据结构解决。

正确的表结构,写在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_emailuser_id为10,则必须有对应的user记录,其中user_id为10,否则查询将失败。 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; 

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

最后,在某些情况下,您不希望进行标准化的数据库设计,并且带有分隔文本的单列设计可能更合适,但这些情况很少。对于大多数正常的应用,这种标准化设计是一种方法,可以帮助它更好地执行和扩展。