【问题标题】:How to implement deletion of user?如何实现删除用户?
【发布时间】:2018-11-09 18:28:37
【问题描述】:

我正在开发展示库的测试项目。就我的开发而言,我不断地遇到问题。

你能帮我做一个吗?

我的模型设计包括 User 和 LeasingHistory 实体,所以当用户借书时,LeasingHistory 表会填入相应的记录。

create table USER
(
 ID BIGINT not null serial primary key,
 ADDRESS VARCHAR(255) not null,
 DOCUMENT_ID VARCHAR(255) not null,
 FIRST_NAME VARCHAR(255) not null,
 SUR_NAME VARCHAR(255) not null
);

create table LEASING_HISTORY
(
 ID BIGINT not null serial primary key,
 BOOK_INSTANCE_ID BIGINT not null,
 USER_ID BIGINT not null,
 START_DATE DATE(10),
 ARRANGED_END_DATE DATE(10),
 ACTUAL_END_DATE DATE(10),
 foreign key (BOOK_INSTANCE_ID) references BOOK_INSTANCE,
 foreign key (USER_ID) references USER
);

现在我必须实现用户删除。我该怎么做?它是如何在 Google、Facebook 或 StackOverFlow 中实现的?

我认为在这种情况下删除孤儿是不合适的策略,因为不应该清理历史记录。

我想我可以将 isActive 字段添加到 User 表中。在这种情况下,当用户按下“删除帐户”按钮时,我可以清除个人信息并分配isActive = false

你怎么看?

更新: 我认为用户应该有可能恢复他的帐户,因此在这种情况下@killjoy 选项更好。你能检查我,我理解正确吗?我引入了额外的表UserInternalData,如果删除用户,我将清除User实体中的所有数据(除了id)并将isDeleted设置为true,dateStamp设置为'UserInternalData'中的当前日期

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@EqualsAndHashCode
@ToString
class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String firstName;

    private String surName;

    @JsonFormat(pattern="yyyy-MM-dd")
    private LocalDate dateOfBirth;

}

@Entity
@NoArgsConstructor
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class User extends Person {

    @Builder
    public User(Long id, String firstName, String surName, LocalDate dateOfBirth, String documentId, String address) {
        super(id, firstName, surName, dateOfBirth);
        this.documentId = documentId;
        this.address = address;
    }

    private String documentId;

    private String address;

}

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@EqualsAndHashCode
@ToString
public final class UserInternalData {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne
    private User user;

    boolean isDeleted;

    @JsonFormat(pattern="yyyy-MM-dd")
    private LocalDate dateStamp;

}

我说的对吗?

【问题讨论】:

  • 根据法律,您可能需要实际删除数据。了解 GDPR。
  • 我可以将所有包含个人信息的列设置为空,只保留 id 和 isActive
  • 我会将所有个人信息以一对一的关系分隔到一个单独的表中,然后您可以删除这些行。您可以将登录信息(SALTED HASH!)和用户 ID 等内容保存在另一个表中
  • 它是如何在 Google、Facebook 或 StackOverFlow 中实现的? 祝你在 Google、Facebook StackOverflow 中找到一个可以回答这个问题的人。
  • 登录信息?如果我删除用户,我应该释放电子邮件和昵称,并让用户再次使用同一电子邮件注册。所以登录信息也是个人信息

标签: java sql database-design


【解决方案1】:

需要考虑的几种方法。

  1. isActive 列(或等效的isDeleted 列)添加到USER 表。删除用户时清除(或设置)该位。您可能还想清除其他敏感信息。这为将来重新激活已删除用户提供了可能性。

  2. LEASING_HISTORY 中所有受影响行中的USER_ID 字段替换为代表已删除用户的特殊保留ID(可能名称类似于"Deleted User")。

  3. 按照@killjoy,通过添加与USER_IDBOOK_INSTANCE_ID 相关的第三个表来规范这两个表,并从LEASING_HISTORY 中删除USER_ID 列。然后,您可以简单地从第三个表中删除受影响的行,而不会丢失图书租赁历史记录。

附录

再想一想,(3)可能不是一个好方法。想法是将USER_ID 外键分离到一个单独的表中,但这并不能解决悬空删除外键问题。

也许更可行的方法是:

  1. 不要将USER_ID 限制为外键。这样,您就可以安全地删除 USER 行,而无需进行任何清理。当然,您仍然需要在创建每个新的 LEASING_HISTORY 行时(以编程方式)确保引用完整性。

我更喜欢 (1),因为您没有删除任何用户历史记录,只是删除了敏感的用户信息。

【讨论】:

  • 感谢您的回答!我可以请您延长第 3 点吗?
  • 谢谢!我想注意到第 4 点使 hibernate 的易用性复杂化
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多