mysql软删除唯一,具有软删除,唯一键和外键约束的MySQL

Say I have two tables, user and comment. They have table definitions that look like this:

CREATE TABLE `user` (

`id` INTEGER NOT NULL AUTO_INCREMENT,

`username` VARCHAR(255) NOT NULL,

`deleted` TINYINT(1) NOT NULL DEFAULT 0,

PRIMARY KEY (`id`),

UNIQUE KEY (`username`)

) ENGINE=InnoDB;

CREATE TABLE `comment` (

`id` INTEGER NOT NULL AUTO_INCREMENT,

`user_id` INTEGER NOT NULL,

`comment` TEXT,

`deleted` TINYINT(1) NOT NULL DEFAULT 0,

PRIMARY KEY (`id`),

CONSTRAINT `fk_comment_user_id` FOREIGN KEY (`user_id`)

REFERENCES `user` (`id`)

ON DELETE CASCADE

ON UPDATE CASCADE

) ENGINE=InnoDB;

This is great for enforcing data integrity and all that, but I want to be able to "delete" a user and keep all its comments (for reference's sake).

To this end, I've added deleted so that I can SET deleted = 1 on a record. By listing everything with deleted = 0 by default, I can hide away all the deleted records until I need them.

So far so good.

The problem comes when:

A user signs up with a username (say, "Sam"),

I soft-delete that user (for unrelated reasons), and

Someone else comes along to sign up as Sam, and suddenly we've violated the UNIQUE constraint on user.

I want users to be able to edit their own usernames, so I shouldn't make username the primary key, and we'll still have the same problem when deleting users.

Any thoughts?

Edit for clarification: Added following RedFilter's answer and comments below.

I'm concerned with the case where the "deleted" users and comments are not visible to the public, but are visible only administrators, or are kept for the purpose of calculating statistics.

This question is a thought experiment, with the user and comment tables just being examples. Still, username wasn't the best one to use; RedFilter makes valid points about user identity, particularly when the records are presented in a public context.

Regarding "Why isn't username the primary key?": this is just an example, but if I apply this to a real problem I'll be needing to work within the constraints of an existing system that assumes the existence of a surrogate primary key.

解决方案

Add unique constraint on fields(username, deleted)

Change field type for 'deleted' to INTEGER.

During delete operation (it can be done in trigger, or in part of code where you need actually delete user) copy value of id field to deleted field.

This approach allow you:

keep unique names for active users (deleted = 0)

allow delete users with same username several times

Field 'Deleted' can't have only 2 value because the following scenario will not work:

you create user 'Sam'

User Sam is deleted

You create new user witn userName 'Sam'

You try delete user with userName 'Sam' - fail. You already have record userName = 'Sam' and deleted = '1'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 外键约束可以用来保证之间的关系完整性。当我们在一个中定义了一个外,它会引用另一个中的列,这个被引用的列必须是另一个的主或者是一个唯一。在 MySQL 中,外键约束可以跨越多个列。 下面是一个例子,演示如何在 MySQL 中定义一个外键约束,跨越两个列: ``` CREATE TABLE orders ( order_id INT PRIMARY KEY, customer_id INT, order_date DATE, FOREIGN KEY (customer_id, order_date) REFERENCES customers(id, date) ); ``` 在这个例子中,orders 中的 customer_id 和 order_date 列都被用来定义外键约束,它们分别引用了 customers 中的 id 和 date 列。这个外键约束确保了 orders 中的每一行都有对应的 customers 中的行,而且这个关联是基于 customer_id 和 order_date 两列的值。 在定义外键约束时,我们还可以指定 ON DELETE 和 ON UPDATE 规则,用来控制当关联中的某一行被删除或更新时,对应的行应该怎么处理。常用的规则包括: - CASCADE:当关联中的某一行被删除或更新时,对应的行也会被删除或更新。 - RESTRICT:当关联中的某一行被删除或更新时,如果该行有对应的行,则不允许删除或更新。 - SET NULL:当关联中的某一行被删除或更新时,对应的行的外列会被设置为 NULL。 我们可以在定义外键约束时使用这些规则,例如: ``` CREATE TABLE orders ( order_id INT PRIMARY KEY, customer_id INT, order_date DATE, FOREIGN KEY (customer_id, order_date) REFERENCES customers(id, date) ON DELETE CASCADE ON UPDATE RESTRICT ); ``` 在这个例子中,我们指定了 ON DELETE CASCADE 和 ON UPDATE RESTRICT 规则,示当 customers 中的某一行被删除时,对应的 orders 中的行也会被删除;当 customers 中的某一行被更新时,只有当 orders 中的行没有被引用时,才允许更新。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值