2010-07-30 26 views

Trả lời

185

add_index :people, [:firstname, :lastname, :dob], :unique => true

+7

Tôi nghĩ rằng đó là thêm một chỉ mục duy nhất, * không * một ràng buộc. Hay chỉ số cũng thêm ràng buộc? –

+13

Không, tất cả đều tốt. Lỗi của tôi! Ràng buộc duy nhất đi kèm với chỉ mục duy nhất. –

+5

Tôi đồng ý với @ paul-cantrell: không có cách nào để chỉ thêm ràng buộc, không phải chỉ mục (có ảnh hưởng lưu trữ db) –

5

Hi Bạn có thể thêm chỉ số duy nhất trong di chuyển sang các cột ví dụ

add_index(:accounts, [:branch_id, :party_id], :unique => true) 

hoặc chỉ số độc đáo riêng biệt cho mỗi cột

+0

Xin lỗi, nó làm việc, đầu tiên tôi đã cố gắng bằng cách chỉnh sửa và di cư đang tồn tại mà không làm việc, sau đó thêm một cái mới và nó hoạt động, cảm ơn. – rangalo

12

Bạn có thể muốn thêm một hạn chế mà không có một mục lục. Điều này sẽ phụ thuộc vào cơ sở dữ liệu bạn đang sử dụng. Dưới đây là mã di chuyển mẫu cho Postgres. (tracking_number, carrier) là danh sách các cột bạn muốn sử dụng cho ràng buộc.

class AddUniqeConstraintToShipments < ActiveRecord::Migration 
    def up 
    execute <<-SQL 
     alter table shipments 
     add constraint shipment_tracking_number unique (tracking_number, carrier); 
    SQL 
    end 

    def down 
    execute <<-SQL 
     alter table shipments 
     drop constraint if exists shipment_tracking_number; 
    SQL 
    end 
end 

Có những hạn chế khác nhau mà bạn có thể thêm. Read the docs

+9

[Tài liệu cho PostgreSQL 9.4] (http://www.postgresql.org/docs/9.4/static/ddl-constraints.html#DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS) nói: _Thêm ràng buộc duy nhất sẽ tự động tạo một btree duy nhất chỉ mục trên cột hoặc nhóm cột được sử dụng trong ràng buộc. Một ràng buộc duy nhất về chỉ một số hàng có thể được thực thi bằng cách tạo một chỉ mục một phần._ Vì vậy IMHO không cần phải thả xuống SQL thô khi kết quả về cơ bản giống như sử dụng phương thức 'add_index'. ;) –

+3

Thực tế có một lý do: Đó là một chi tiết triển khai và không khuyến khích bởi [docs] (http://www.postgresql.org/docs/9.3/static/indexes-unique.html). Cũng lưu ý rằng bạn không thể tham chiếu đến ràng buộc theo tên, vì nó không được thêm vào bảng 'pg_constraint'. – kaikuchn

16

Theo howmanyofme.com, "Có 46.427 người có tên là John Smith" chỉ riêng ở Hoa Kỳ. Đó là khoảng 127 năm ngày. Vì điều này là tốt hơn tuổi thọ trung bình của một con người, điều này có nghĩa là một cuộc xung đột DOB là toán học nhất định.

Tất cả những gì tôi nói là sự kết hợp đặc biệt của các trường duy nhất có thể dẫn đến sự thất vọng cực kỳ của người dùng/khách hàng trong tương lai.

Hãy xem xét điều gì đó thực sự độc đáo, như số nhận dạng quốc gia, nếu thích hợp.

(Tôi nhận ra tôi rất muộn để đảng với thế này, nhưng nó có thể giúp người đọc trong tương lai.)

+1

hrm ... bạn chắc chắn đúng. nhưng có lẽ nó chỉ là một ví dụ về những gì Ian muốn làm chỉ để làm cho câu hỏi rõ ràng. – eritiro

+0

Có thể. Câu trả lời không dành cho Ian. Hay đúng là Rangalo. –

1

Trong ví dụ điển hình của một bảng tham gia giữa người sử dụng và các bài viết:

create_table :users 
create_table :posts 

create_table :ownerships do |t| 
    t.belongs_to :user, foreign_key: true, null: false 
    t.belongs_to :post, foreign_key: true, null: false 
end 

add_index :ownerships, [:user_id, :post_id], unique: true 

Cố gắng tạo hai bản ghi tương tự sẽ ném một lỗi cơ sở dữ liệu (Postgres trong trường hợp của tôi):

ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_ownerships_on_user_id_and_post_id" 
DETAIL: Key (user_id, post_id)=(1, 1) already exists. 
: INSERT INTO "ownerships" ("user_id", "post_id") VALUES ($1, $2) RETURNING "id" 

ví dụ làm điều đó:

Ownership.create!(user_id: user_id, post_id: post_id) 
Ownership.create!(user_id: user_id, post_id: post_id) 

Hoàn toàn Runnable dụ: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced

db/schema.rb tạo: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a

Các vấn đề liên quan