0

注册表要求提供 用户名电子邮件地址。数据通过验证后,它被添加到accounts表中。它存储用户名、密码和电子邮件地址等数据。如果用户名已被使用,用户将收到通知,并且不会将任何数据添加到表中。如果立即通知用户电子邮件地址已在表中,则将其视为安全问题。建议的解决方案是始终发送验证电子邮件,如果输入的用户名已经存在,则电子邮件将显示“此电子邮件地址已被使用”(当然不会提供激活链接)。

问题是,当它现在工作时,如果INSERT查询未能将数据插入表中,则会显示消息“用户名已采用”。这可能是错误的,因为电子邮件地址在表中设置为唯一,因此如果输入相同的电子邮件地址,查询将失败。我不能再发送一封验证邮件说“这个邮箱地址已经被使用了”,因为在包含该邮箱地址的表格中没有记录。

如何重新设计系统以使其正常工作?

我正在使用 MySQL,该表accounts具有主键username唯一键e-mail和属性passwordactivation.

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

在 SQL 中是否有某种方法可以检查为什么无法将查询插入到表中?例如,它可以判断哪个属性具有重复值吗?

如果我的问题不清楚,请告诉我。

4

2 回答 2

1

首先运行 SELECT 查询以识别重复项。如果没有找到重复项,则可以执行 INSERT。

于 2013-08-09T19:56:09.270 回答
0

如果您希望数据库在插入数据时执行所需的检查,并且您希望能够区分添加电子邮件的失败尝试和添加用户名的失败尝试,最直接的解决方案是同时拥有一个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;

我不会说这是最好的解决方案,但我认为它可以按您的意愿工作。

于 2013-08-09T19:59:05.277 回答