數據庫中唯一索引和邏輯刪除字段的互斥

以下內容首發於我的個人博客網站:
http://riun.xyz


表中的唯一索引會和邏輯刪除字段互斥,導致邏輯刪除後的數據和要插入的數據出現重複索引時無法插入。

有如下表:

CREATE TABLE `pata_biz` (
  `ID` bigint(32) NOT NULL AUTO_INCREMENT COMMENT 'ID主鍵',
  `NAME` varchar(128) DEFAULT NULL COMMENT '業務線名稱',
  `CODE` varchar(128) UNIQUE DEFAULT NULL COMMENT '業務線code',
  `BIZ_DESC` varchar(1024) DEFAULT NULL COMMENT '業務線描述'
  ...
  `ISACTIVE` tinyint(1) NOT NULL DEFAULT '1' COMMENT '邏輯刪除',
  `INSERTTIME` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '插入時間',
  `UPDATETIME` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間'
);

其中code字段設置爲了unique唯一屬性,表中就會爲此字段添加唯一索引。而表中又有邏輯刪除字段ISACTIVE,當ISACTIVE爲0時,此條數據就被認爲已刪除,永遠不會再用到。在系統中所有條件只檢索ISACTIVE爲1的數據。

現在要求做插入操作之前,先查詢表中有無name或者code相同的(name,code均不能相同),如果有相同的就不能插入,沒有相同的,此sql會返回0表示可以插入。

查詢的sql如下:

<sql id="insertCondition">
	<where>
		ISACTIVE  = 1 AND
		(`code` = #{code} OR `name` = #{name})
	</where>
</sql>
<select id="queryBizInfoCountByCodeNameForInsert" resultType="java.lang.Long" parameterType="com.ppd.bot.dao.entity.PataBiz">
	select count(*)
	from pata_biz
	<include refid="insertCondition"></include>
</select>

在執行查詢時,如果數據庫存在某條數據:name:testname1 code:1001 ISACTIVE:0 ,這條數據是被認爲刪除了的。然後嘗試向表中插入一條數據:name:testname2 code:1001 此時使用queryBizInfoCountByCodeNameForInsert這個sql查詢返回結果是0,因爲上述數據的ISACTIVE是0查詢時不會判斷進去。但是真正執行插入sql語句時,數據庫的唯一索引不會排除掉ISACTIVE爲0的數據,就會因爲code重複而無法插入直接報錯。

這樣看來數據庫中好多限制都是理論限制,在實際應用中要根據場景分辨是否應該使用這些限制,儘量不要爲數據庫添加很強的限制條件,數據庫只是存數據的,不做數據計算和判斷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章