我在一个数据库中有两个表,users
和users_removed
有列"id(主键(、电子邮件(唯一(、密码";以及";id、user_id(外键(user_id(引用用户(id(";分别地
当用户注册时,users
表相应地获得数据。当用户想要删除帐户时,我可以在users_removed
中获取用户的id,并考虑将其删除,例如
INSERT into users_removed (user_id)
VALUES ((SELECT id FROM users WHERE email = 'user@example.com'))
来自users
的id
被插入到具有外键约束的users_removed
中。
现在的问题是,用id
从users
中删除数据,但以某种方式保留数据的正确方法是什么。
- 完全删除不是一个选项,因为我丢失了数据,因此表
users_removed
的目的也是如此。如果我删除,我也会得到错误";无法删除或更新父行:外键约束失败"因为外键约束 - 用户应该能够重新注册以前的电子邮件,但将其视为一个全新的条目,因为
users
中的email
是唯一的
sql中是否有方法使某些数据无法使用,不允许对其执行查询,例如当我在后台执行查询时,它会被忽略。
或者可能的解决方案是什么?
我有一种方法可以限制users_removed
登录,但我应该如何进行注册。
由于mysql不允许在INSERT中使用select并从同一个表中删除,因此您必须在mysql之外的编程语言中进行优化。
我在这里使用了一个单独的SELCT和一个用户定义的变量,以首先获得user_id
CREATE TABLE users (id int AUTO_INCREMENT PRIMARY key, email varchar(100) UNIQUE)
CREATE TABLE users_removed (id int AUTO_INCREMENT PRIMARY key,user_id int)
INSERT INTO users (email) VALUES ('user@example.com')
CREATE TRIGGER after_users_removed_insert
AFTER INSERT
ON users_removed FOR EACH ROW
BEGIN
IF NEW.user_id IS NOT NULL THEN
DELETE FROM users WHERE id = new.user_id;
END IF;
END
SELECT id INTO @user_id FROM users WHERE email = 'user@example.com' ;
INSERT into users_removed (user_id)
VALUES (@user_id)
SELECT * FROM users
id | 电子邮件 |
---|
IMHO最好在users表中添加两个字段(IsDeleted、DeletedAt(。
CREATE TABLE usersss (
id int unsigned NOT NULL auto_increment,
email varchar(100),
IsDeleted tinyInt default 0,
DeletedAt datetime,
PRIMARY KEY (id),
UNIQUE KEY uk_email (email, IsDeleted),
KEY email (email),
KEY IsDeleted (IsDeleted)
);
在处理用户的每个查询中,您将在条件中包含(IsDeleted=0(。
当用户想要删除帐户时,您将IsDeleted设置为1,DeletedAt设置为NOW((。
UPDATE users SET IsDeleted=1 AND DeletedAt = NOW() WHERE id=$ID;
为了让用户能够使用以前的电子邮件重新注册,您将在(电子邮件(上的字段(电子邮件,IsDeleted(上检查唯一索引。
SELECT COUNT(id) FROM users WHERE (IsDeleted=0) AND (email = '$email');
如果查询返回(0(,则用户可以使用该电子邮件。从删除日期(DeletedAt(起经过指定的时间段后,您可以删除IsDeleted=1的用户的数据。示例:
如果您想在一年后删除用户及其数据,要获得您将删除的用户:
SELECT id FROM users WHERE TO_DAYS(NOW()) >= (TO_DAYS(DeletedAt) + 365) ;
然后您将从这些用户的相关表中删除数据。