自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

數(shù)據(jù)軟刪除時保持字段值唯一性的問題

數(shù)據(jù)庫
在數(shù)據(jù)庫做數(shù)據(jù)軟刪除操作時,怎么保證該行數(shù)據(jù)中要求具有唯一性的字段數(shù)據(jù)的唯一性。也就是說,軟刪除狀態(tài)下要求具有唯一性的字段數(shù)據(jù)可以出現(xiàn)多次,未刪除狀態(tài)下要求具有唯一性的字段數(shù)據(jù)只能出現(xiàn)一次。

俗話說:脫離了業(yè)務(wù)場景的技術(shù)面試就是耍流氓。筆者今天(2021-05-19)面試一家做安全公司的 “科學(xué)家” 崗位時,被問到關(guān)于數(shù)據(jù)庫的一道題,感覺很有代表性,特此記錄下來分享給大家。

1. 問題

在數(shù)據(jù)庫做數(shù)據(jù)軟刪除操作時,怎么保證該行數(shù)據(jù)中要求具有唯一性的字段數(shù)據(jù)的唯一性。也就是說,軟刪除狀態(tài)下要求具有唯一性的字段數(shù)據(jù)可以出現(xiàn)多次,未刪除狀態(tài)下要求具有唯一性的字段數(shù)據(jù)只能出現(xiàn)一次。

不要告訴我你不知道什么是軟刪除?

軟刪除就是該行數(shù)據(jù)不會真正的從數(shù)據(jù)表中被delete掉,會有狀態(tài)字段記錄該行數(shù)據(jù)已經(jīng)刪掉

  1. CREATETABLE `userinfo1` ( 
  2.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
  3.   `namevarchar(50) DEFAULT ""
  4.   `status` bigint(20) DEFAULT 0 COMMENT "刪除狀態(tài)(默認0)表示未刪除"
  5.   PRIMARY KEY (`id`) 
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

 假設(shè)現(xiàn)在存在userinfo1表,要求:在status為非刪除狀態(tài)下name字段值唯一,在刪除狀態(tài)下相同的name字段可以出現(xiàn)多次。對于上面的表結(jié)構(gòu)可以進行索引改造等操作,但是不允許添加新的字段。

我給出的解決方案

針對這個問題,當(dāng)時我的腦海中閃現(xiàn)出兩套方案。

方案1:

對userinfo1表的name字段設(shè)置為唯一索引。同時,創(chuàng)建另外一張相同的表結(jié)構(gòu)userinfo2,表中name字段不設(shè)置為唯一索引。在數(shù)據(jù)刪除時,把userinfo1表中的數(shù)據(jù)真實的刪除掉,同時把刪除的數(shù)據(jù)存儲到userinfo2中一份。

優(yōu)點:

  1. 未刪除數(shù)據(jù)、刪除數(shù)據(jù)分開存儲
  2. 可以解決name字段在未被刪除時唯一存在,刪除之后可以重復(fù)的問題

缺陷:

  1. 不符合題目軟刪除要求
  2. 多創(chuàng)建了一張表,增加了維護成本
  3. userinfo1表中刪除,userinfo2表插入被刪除數(shù)據(jù),兩個操作動作對應(yīng)2條不同SQL,需要在同一個事物中操作
  4. 操作比較復(fù)雜

當(dāng)然,方案被面試官否決了。面試官說:“你面試的可是科學(xué)家崗位呀,再想想。”

方案2:

對userinfo1表的name、status兩個字段設(shè)置聯(lián)合的唯一索引,在刪除數(shù)據(jù)時對status、name字段同時進行更新,status字段更新為非0(比如1)、name字段加上一個當(dāng)前毫秒時間戳作為后綴(方案參考雪花算法實現(xiàn)的 分布式系統(tǒng)唯一ID,只要保證要求的字段唯一存在即可)。

優(yōu)點:

  1. 沒有使用新的數(shù)據(jù)表、新的字段
  2. 軟刪除只需要更新兩個字段即可滿足題目要求

缺點:

  1. 更新數(shù)據(jù)時對原name字段添加后綴,數(shù)據(jù)造成了污染(改變了原數(shù)據(jù))

面試官聽了聽,說道:“跟理想的答案很接近了,雖然可以解決問題,但是添加后綴后原數(shù)據(jù)被污染了。作為想成為'科學(xué)家'的男人,還有新的方案嗎?”

我想了想說:“暫時沒想到新的方案,可以提示一下嗎?”

面試官說:“name、status創(chuàng)建聯(lián)合的唯一索引沒問題,關(guān)鍵在于status怎么處理?再想想。”

3分鐘后,我說:“我盡力了,還是你來當(dāng)科學(xué)家吧。”

2. 理想方案

面試官怕打消我的積極性,說道:“年輕人,不要這么浮躁,我給你指點一下。”

方案3

對userinfo1表的name、status兩個字段設(shè)置聯(lián)合的唯一索引,在更新數(shù)據(jù)時把被軟刪除的數(shù)據(jù)行對應(yīng)的id值,賦值給status字段(status等于0表示未刪除,非0表示已刪除)。

最終的表結(jié)構(gòu)為:

  1. CREATETABLE `userinfo1` ( 
  2.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
  3.   `namevarchar(50) DEFAULT ""
  4.   `status` bigint(20) DEFAULT 0 COMMENT "刪除狀態(tài)(默認0)表示未刪除 非0表示刪除"
  5.   PRIMARY KEY (`id`), 
  6.   UNIQUE KEY `name_status` (`name`, `status`)   
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

 聽完之后,我是猛地一拍腦門,說道:“哎呀,距離成為科學(xué)家僅有一步之遙,可惜了。”

總結(jié)

脫離了實際場景的問題大部分都是耍流氓,只有結(jié)合具體場景才能有針對性的對問題進行分析,從而得到一個可行的最優(yōu)案。

解決本文開頭的問題可能有很多方案,但是最優(yōu)的也就兩點:

① 對需要保持唯一的數(shù)據(jù)創(chuàng)建聯(lián)合唯一索引

② 軟刪除時status字段更新為該行數(shù)據(jù)的唯一值(也就是主鍵id)

 

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2024-05-24 09:29:28

2011-10-20 10:07:03

LightSwitch

2022-01-27 11:02:04

索引數(shù)據(jù)存儲

2021-07-02 06:54:43

分布式環(huán)境ID

2024-03-11 05:00:00

Python集合開發(fā)

2017-06-27 09:40:28

MYSQL數(shù)據(jù)備份

2009-03-30 11:27:59

中文域名

2024-11-28 09:47:53

C#互斥鎖Mutex

2011-02-24 13:55:12

SQL Server可空字段非空值

2021-06-15 06:50:08

索引字段數(shù)據(jù)

2010-10-19 16:34:10

SqlServer唯一

2010-11-12 14:45:19

Sql Server唯

2022-02-17 21:04:27

數(shù)據(jù)庫MysqlRedis

2024-08-29 09:27:44

LuceneES字段

2024-09-05 16:55:41

2023-09-21 09:25:53

Python方法

2023-01-03 07:44:53

MySQL查詢重復(fù)

2018-07-19 06:17:09

數(shù)據(jù)完整性數(shù)據(jù)安全網(wǎng)絡(luò)安全

2011-08-18 11:18:25

Oracle唯一約束唯一索引
點贊
收藏

51CTO技術(shù)棧公眾號