2014-04-11 31 views
0

我在Rails應用程序中使用了validates_overlap gem(https://github.com/robinbortlik/validates_overlap)。下面是型號代碼:Rails + validates_overlap gem:何時向數據庫添加索引?

validates :start_time, :end_time, overlap: { scope: "device_id", exclude_edges: ["start_time", "end_time"] } 

,這裏是它觸發SQL:

SELECT 1 AS one FROM "bookings" WHERE 
((bookings.end_time IS NULL OR bookings.end_time > '2014-04-11 13:00:00.000000') AND 
(bookings.start_time IS NULL OR bookings.start_time < '2014-04-11 16:00:00.000000') AND 
bookings.device_id = 20) LIMIT 1 

我只是想知道我是否應該加在我的Postgres數據庫,涵蓋START_TIME,END_TIME指數和device_id或類似的東西?例如像這樣:

add_index :bookings, [:device_id, :start_time, :end_time], unique: true 

回答

1

添加上述索引以確保數據庫的一致性將是沒有意義的。畢竟你正在驗證範圍和排除實際的邊緣(唯一索引將檢查邊緣!)。

添加一個非唯一索引來加速驗證是個好主意。如果是這樣,你應該分析你的數據和應用查詢。 最簡單的方法是簡單地爲每列添加一個索引。 Postgres仍然可以將這些用於多列查詢(請參閱heroku devcenter)。 只有在真正重要的情況下(或者您不查詢其他組合中的列),多列索引纔是必需的。如果是這樣的話,device_id應該在索引Rule of thumb: index for equality first—then for ranges中首先出現。

+0

我想我同意你的回答(我絕對不是這方面的權威人士),但是出於好奇,我跑了一個測試,並且unique = true,我能夠在沒有數據庫錯誤的情況下保存相鄰的預訂。重疊錯誤完好無損,仍由ActiveRecord處理。 –

+1

我有點不清楚。索引將檢查所有三列是否相等,並強制這些列的唯一性。因此,只有當您嘗試使用相同的開始時間和相同的結束時間爲相同的device_id添加預訂時,數據庫纔會拒絕此設置。 – Michael