我认为你可以保持你的基本结构,你只需要一种方法,使删除的不为空。这意味着你需要给它一个默认值。使用的良好默认值是0或0000-00-00 00:00:00。
我的建议是添加一个新列来标记行是否在逻辑上被删除。你可以称之为“已删除”。然后添加deleted_at的默认值并使其非空,并在唯一索引中包含is_deleted。
下面是一个非常简单的例子:
mysql> create table merchant(
-> id int unsigned not null auto_increment,
-> name varchar(50) not null,
-> is_deleted tinyint not null default 0,
-> deleted_at datetime not null default 0,
-> primary key (id),
-> unique key name_and_deleted_at (name,is_deleted,deleted_at)
-> ) ENGINE = InnoDB;
Query OK, 0 rows affected (0.08 sec)
mysql>
mysql> -- successful inserts
mysql> insert into merchant (name,is_deleted) values ('foo',0);
Query OK, 1 row affected (0.00 sec)
mysql> insert into merchant (name,is_deleted) values ('bar',0);
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> -- insert failure due to duplicate name
mysql> insert into merchant (name,is_deleted) values ('foo',0);
ERROR 1062 (23000): Duplicate entry 'foo-0-0000-00-00 00:00:00' for key 'name_and_deleted_at'
mysql> -- logical delete
mysql> update merchant set is_deleted = true, deleted_at = now() where name = 'foo';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> -- now the insert succeeds
mysql> insert into merchant (name,is_deleted) values ('foo',0);
Query OK, 1 row affected (0.01 sec)
mysql>
mysql> -- show data
mysql> select id,name,is_deleted,deleted_at
-> from merchant
-> order by id;
+----+------+------------+---------------------+
| id | name | is_deleted | deleted_at |
+----+------+------------+---------------------+
| 1 | foo | 1 | 2010-11-05 13:54:17 |
| 2 | bar | 0 | 0000-00-00 00:00:00 |
| 4 | foo | 0 | 0000-00-00 00:00:00 |
+----+------+------------+---------------------+
3 rows in set (0.00 sec)