PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Rails có gì khác biệt trong chỉ mục duy nhất và validates_uniqueness_of

Dưới đây là sự khác biệt giữa chỉ mục duy nhất và validates_uniqueness_of

Đây là một bản vá để cho phép ActiveRecord xác định các lỗi do db tạo ra đối với các vi phạm ràng buộc duy nhất. Ví dụ:nó làm cho công việc sau hoạt động mà không cần khai báo validates_uniqueness_of:

create_table "users" do |t|
  t.string   "email",   null: false
end
add_index "users", ["email"], unique: true

class User < ActiveRecord::Base
end

User.create!(email: '[email protected]')
u = User.create(email: '[email protected]')
u.errors[:email]
=> "has already been taken"

Các lợi ích là tốc độ, dễ sử dụng và đầy đủ -

Tốc độ

Với cách tiếp cận này, bạn không cần phải thực hiện tra cứu db để kiểm tra tính duy nhất khi lưu (đôi khi có thể khá chậm khi chỉ mục bị bỏ lỡ - https://rails.lighthoosystempp.com/projects/8994/tickets/2503-validate .. . ). Nếu bạn thực sự quan tâm đến việc xác thực tính duy nhất, bạn sẽ phải sử dụng các ràng buộc cơ sở dữ liệu để cơ sở dữ liệu sẽ xác nhận tính duy nhất bất kể điều gì và cách tiếp cận này loại bỏ một truy vấn bổ sung. Kiểm tra chỉ mục hai lần không phải là vấn đề đối với DB (nó được lưu vào bộ nhớ cache lần thứ hai), nhưng việc lưu một chuyến khứ hồi DB khỏi ứng dụng là một chiến thắng lớn.

Tính dễ sử dụng

Cho rằng dù sao thì bạn cũng phải có các ràng buộc db để có tính duy nhất thực sự, cách tiếp cận này sẽ cho phép mọi thứ tự động diễn ra khi các ràng buộc db được đặt ra. Bạn vẫn có thể sử dụng validates_uniqueness_of nếu muốn.

Tính hoàn chỉnh

validates_uniqueness_of luôn là một sự cố - nó không thể xử lý các điều kiện cuộc đua một cách chính xác và dẫn đến các trường hợp ngoại lệ phải được xử lý bằng cách sử dụng logic xử lý lỗi hơi thừa. (Xem phần "Đồng thời và tính toàn vẹn" trong http://api.rubyonrails .org / class / ActiveRecord / Validations / ClassMe ... )

validates_uniqueness_of không đủ để đảm bảo tính duy nhất của một giá trị. Lý do cho điều này là trong quá trình sản xuất, nhiều quy trình của công nhân có thể gây ra tình trạng chạy đua:

  1. Hai yêu cầu đồng thời cố gắng tạo một người dùng có cùng tên (và chúng tôi muốn tên người dùng là duy nhất)

  2. Các yêu cầu được chấp nhận trên máy chủ bởi hai quy trình công nhân hiện sẽ xử lý chúng song song

  3. Cả hai yêu cầu đều quét bảng người dùng và thấy rằng tên có sẵn

  4. Cả hai yêu cầu đều vượt qua xác thực và tạo người dùng có tên dường như khả dụng

Để hiểu rõ hơn, vui lòng kiểm tra điều này

Nếu bạn tạo một chỉ mục duy nhất cho một cột, điều đó có nghĩa là bạn được đảm bảo rằng bảng sẽ không có nhiều hơn một hàng có cùng giá trị cho cột đó. Chỉ sử dụng xác thực validates_uniqueness_of trong mô hình của bạn là không đủ để thực thi tính duy nhất vì có thể có những người dùng đồng thời đang cố gắng tạo cùng một dữ liệu.

Hãy tưởng tượng rằng hai người dùng cố gắng đăng ký một tài khoản với cùng một email mà bạn đã thêm validates_uniqueness_of:email trong mô hình người dùng của mình. Nếu họ nhấn nút “Đăng ký” cùng lúc, Rails sẽ tìm email đó trong bảng người dùng và phản hồi lại rằng mọi thứ đều ổn và bạn có thể lưu bản ghi vào bảng. Sau đó, Rails sẽ lưu hai bản ghi vào bảng người dùng với cùng một email và bây giờ bạn có một vấn đề thực sự tồi tệ cần giải quyết.

Để tránh điều này, bạn cũng cần tạo một ràng buộc duy nhất ở cấp cơ sở dữ liệu:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :email
      ...
    end
    
    add_index :users, :email, unique: true
  end
end

Vì vậy, bằng cách tạo chỉ mục duy nhất index_users_on_email, bạn nhận được hai lợi ích rất tốt. Tính toàn vẹn của dữ liệu và hiệu suất tốt vì các chỉ mục duy nhất có xu hướng rất nhanh.

Nếu bạn đặt unique:true trong bảng bài đăng của mình cho user_id thì nó sẽ không cho phép nhập các bản ghi trùng lặp với cùng một user_id.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres SAO CHÉP SANG NULL số nguyên

  2. Chọn chỉ mục phù hợp cho truy vấn PostgreSQL

  3. Postgres:CHỌN tên cột dựa trên giá trị Boolean

  4. Điều đó có nghĩa là gì khi một quy trình PostgreSQL không hoạt động trong giao dịch?

  5. CẬP NHẬT nguyên tử để tăng số nguyên trong Postgresql