两者都不是很好的选择。
选项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_email
且user_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;
同样,根据您的应用程序,你可能希望向电子邮件列添加索引。
最后,在某些情况下,您不希望进行标准化的数据库设计,并且带有分隔文本的单列设计可能更合适,但这些情况很少。对于大多数正常的应用,这种标准化设计是一种方法,可以帮助它更好地执行和扩展。
我会强烈反对,第二个是一个很好的选择,甚至可能不是比第一个更好的选择。从应用程序设计的角度来看,甚至从性能的角度来看,为一个值检查30个不同的列是一场噩梦。 – futureal