Lập chỉ mục trên nhiều cột trong Ruby on Rails


97

Tôi đang triển khai chức năng để theo dõi những bài báo mà người dùng đã đọc.

  create_table "article", :force => true do |t|
    t.string   "title"
    t.text     "content"
  end

Đây là lần di chuyển của tôi cho đến nay:

create_table :user_views do |t|
  t.integer :user_id
  t.integer :article_id
end

Bảng user_views sẽ luôn được truy vấn để tìm kiếm cả hai cột, không bao giờ chỉ một cột. Câu hỏi của tôi là chỉ số của tôi sẽ trông như thế nào. Có sự khác biệt trong thứ tự của các bảng này không, nên có thêm một số tùy chọn cho nó hay bất cứ điều gì. DB mục tiêu của tôi là Postgres.

add_index(:user_views, [:article_id, :user_id])

Cảm ơn.

CẬP NHẬT:
Bởi vì chỉ có thể tồn tại một hàng chứa các giá trị giống nhau trong cả hai cột (vì khi biết user_id ĐÃ đọc article_id), tôi nên xem xét tùy chọn: unique? Nếu tôi không nhầm thì điều đó có nghĩa là tôi không phải tự mình kiểm tra và chỉ cần thực hiện chèn mỗi khi người dùng truy cập một bài báo.


"Bảng user_views sẽ luôn được truy vấn để tìm kiếm cả hai cột, không bao giờ chỉ một". - sẽ không bao giờ có truy vấn "tìm tất cả các bài viết mà người dùng này đã xem", hoặc "tìm tất cả người dùng đã xem bài viết này"? Tôi thấy điều đó thật ngạc nhiên.
David Aldridge

Câu trả lời:


212

Thứ tự có ý nghĩa trong việc lập chỉ mục.

  1. Đặt trường chọn lọc nhất trước, tức là trường thu hẹp số hàng nhanh nhất.
  2. Chỉ mục sẽ chỉ được sử dụng trong chừng mực bạn sử dụng các cột của nó theo trình tự bắt đầu từ đầu . tức là nếu bạn lập chỉ mục trên [:user_id, :article_id], bạn có thể thực hiện truy vấn nhanh trên user_idhoặc user_id AND article_id, nhưng KHÔNG được bật article_id.

add_indexDòng di chuyển của bạn sẽ trông giống như sau:

add_index :user_views, [:user_id, :article_id]

Câu hỏi liên quan đến tùy chọn 'duy nhất'

Một cách dễ dàng để thực hiện điều này trong Rails là sử dụng validatestrong mô hình của bạn với phạm vi uniquenessnhư sau ( tài liệu ):

validates :user, uniqueness: { scope: :article }

7
Thứ tự rất quan trọng trong việc lập chỉ mục. Đặt mệnh đề where ở bên trái và hoàn thành chỉ mục với các cột thứ tự ở bên phải. stackoverflow.com/questions/6098616/dos-and-donts-for-indexes
Denis de Bernardy

1
Lưu ý rằng validates_uniqueness_of(và anh em họ của nó, validates uniqueness:) dễ bị điều kiện chủng tộc
Bến Aubin

1
Như đã đề cập trong các nhận xét ở trên và stackoverflow.com/a/1449466/5157706stackoverflow.com/a/22816105/5157706 , hãy cân nhắc thêm chỉ mục duy nhất trên cơ sở dữ liệu.
Akash Agarwal

25

Chỉ là một cảnh báo về việc kiểm tra tính duy nhất tại thời điểm xác thực so với trên chỉ mục: phần sau được thực hiện bởi cơ sở dữ liệu trong khi phần mồi được thực hiện bởi mô hình. Vì có thể có một số trường hợp đồng thời của một mô hình chạy cùng một lúc, việc xác thực phải tuân theo các điều kiện về chủng tộc, có nghĩa là nó có thể không phát hiện được các bản sao trong một số trường hợp (ví dụ: gửi hai lần cùng một biểu mẫu cùng một lúc).


Vậy cái nào tốt hơn? Cơ sở dữ liệu phía hoặc validates_uniqueness_of?
WM

9
Cả hai. validates_uniqueness_of có thể được sử dụng để hiển thị thông báo lỗi một cách duyên dáng trong ứng dụng, chẳng hạn như khi một biểu mẫu được lưu. Ràng buộc cơ sở dữ liệu sẽ đảm bảo rằng bạn không kết thúc với các bản ghi trùng lặp thậm chí biết rằng bạn đã xác nhận hợp lệ được chỉ định trong mô hình. Ngoài ra, bạn có thể giải cứu ngoại lệ ActiveRecord và cũng hiển thị một thông báo tốt đẹp cho người dùng.
Uģis Ozols

5
@WM Nếu bạn phải chọn một, hãy đi với ràng buộc cơ sở dữ liệu. Điều này sẽ hoạt động ngay cả khi các ứng dụng khác nhau, không phải RoR tương tác với dữ liệu của bạn và đảm bảo tính nhất quán trong thời gian dài.
mooreds
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.