设计难题:如果已使用的电子邮件地址,发送电子邮件“已经被注册的电子邮件地址”,但不能因为不能添加重复

2019-10-30 08:16发布

登记表询问用户名电子邮件地址 。 数据通过验证后它添加到accounts表。 它存储如用户名,密码和电子邮件地址数据。 如果用户名已被占用,用户将被告知,没有数据将被添加到表中。 它被看作是一个安全问题 ,如果用户立即通知该E-mail地址已经在表中。 建议的解决方案,这是总是发送验证电子邮件,如果输入的用户名已经存在的电子邮件会说:“ 这个E-mail地址已经使用 ”(没有激活链接将被赋予当然)。

问题是,因为现在的工作,如果INSERT查询失败将数据插入到表中的信息“用户名采取”所示。 因为这样,如果输入了相同的E-mail地址查询失败的E-mail地址被设置为唯一的表,这可能是错误的。 我不能再发送验证电子邮件说:“ 这个E-mail地址已被使用 ”,因为在包含该表中没有记录的所述e-mail地址。

我怎样才能重新设计系统,所以它的工作原理?

我使用MySQL和表accounts中有主键username唯一键e-mail和属性, passwordactivation

if(mysqli_stmt_execute($createAccount))
    echo 'Username available!';
else
    echo 'Username unavailable!';

在SQL是有一些方法来检查,看看为什么查询不能被插入到表? 例如,它可以告诉哪个属性有重复值?

请让我知道,如果我的问题是不清楚。

Answer 1:

首先运行SELECT查询来识别重复。 如果没有发现重复的,那么您就可以执行INSERT。



Answer 2:

如果你想在DB, 同时将数据进行必要的检查,并且希望能够一个失败的尝试添加一个电子邮件地址和一个失败的尝试添加一个用户名来区分,最直接的解决方案是同时具有email表和username表。 您的实际account表将只保留外键,这两个表。 下面是一个例子http://sqlfiddle.com/#!2/a24df :

CREATE TABLE username (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, value CHAR(80) UNIQUE NOT NULL);
CREATE TABLE email (id  INT AUTO_INCREMENT PRIMARY KEY NOT NULL, value CHAR(80) UNIQUE NOT NULL);

CREATE TABLE account(id  INT AUTO_INCREMENT PRIMARY KEY NOT NULL,
                     username_id  INT NOT NULL,
                     email_id INT NOT NULL,
                     FOREIGN KEY (username_id) REFERENCES username(id),
                     FOREIGN KEY (email_id) REFERENCES email(id) );

添加新用户将在一个事务几个步骤来执行,现在。 现在,您就可以知道哪些步骤失败如果有的话。 而在交易,这将节省帐户创建的原子是:

START TRANSACTION;
INSERT INTO email(value) VALUES ("x@y.com");
INSERT INTO username(value) VALUES ("Sylvain");

-- you could obtain the ID programmatically by "last_insert_id"-like function 
INSERT INTO account(username_id, email_id) VALUES (1,1); 
COMMIT;

和查询某个帐户的用户名和电子邮件,现在需要一个连接:

SELECT username.value AS username, email.value AS email 
FROM username JOIN account ON username.id = account.username_id
JOIN email ON email.id = account.email_id
WHERE account.id = 1;

我不会说这是必要的最佳解决方案,但它的工作原理,如你所愿,我想。



文章来源: Design dilemma: If e-mail address already used, send e-mail “e-mail address already registered”, but can't because can't add duplicate to table