一 創建
- JavaScript Shell
db.room.ensureIndex({'floor':1,'num':1})
- Spring Data
@Data // lombok
@Document(collection = "room")
@CompoundIndexes({
// 唯一復合索引:樓層和房號不能相同,不然就是同一個房間了
@CompoundIndex(name = "floor_num", def = "{'floor' : 1, 'num': 1}",unique=true)
})
public class Room {
@Id
private String id;
// 樓層
private int floor;
// 房號
private int num;
// 建造時間
private Date createAt;
}
二 疑問
(1)日期字段能與其他字段復合為唯一索引嗎?
可以,mongodb存儲的是時間戳,實際上轉換成數字進行復合比較的。
(2)插入重復數據會發生什么?
- JavaSript Shell:重復key值異常
> [Error] index 0: 11000 - E11000 duplicate key error collection: ...
- Spring:重復key值異常
org.springframework.dao.DuplicateKeyException: Write failed with error code 11000 and error message 'E11000 duplicate key error collection:...'
Caused by: com.mongodb.DuplicateKeyException: Write failed with error code 11000 and error message 'E11000 duplicate key error collection:
(3)批量插入時,發生重復key值異常,數據存儲狀態是怎樣的?
- 猜測1:所有數據回滾,發生異常,所有數據不保存
- 猜測2:插入成功的數據入庫,發生異常后,后面的數據不入庫。
- 猜測3:發生異常的數據跳過,正常數據入庫。
- 猜測4:重復key值的文檔用新的數據覆蓋。
答案:猜測2是對的。mongodb不支持事務,所以猜測1不正常,mongodb不會回滾;跳過異常數據繼續入庫,什么鬼,哪有這么強大的數據庫,猜測3不成立;猜測4是源於insert和save操作的對比,save遇到主鍵重復時,會使用新的值進行覆蓋,但是復合唯一索引不支持這個操作。