สิ่งที่ฉันต้องการคือการโยกย้ายเพื่อนำข้อ จำกัด ที่ไม่ซ้ำกันมาใช้กับการรวมกันของคอลัมน์ คือสำหรับpeople
ตารางการรวมกันของfirst_name
, last_Name
และDob
ต้องไม่ซ้ำกัน
สิ่งที่ฉันต้องการคือการโยกย้ายเพื่อนำข้อ จำกัด ที่ไม่ซ้ำกันมาใช้กับการรวมกันของคอลัมน์ คือสำหรับpeople
ตารางการรวมกันของfirst_name
, last_Name
และDob
ต้องไม่ซ้ำกัน
คำตอบ:
add_index :people, [:firstname, :lastname, :dob], :unique => true
อ้างอิงจาก howmanyofme.com "มีคน 46,427 คนชื่อจอห์นสมิ ธ " ในสหรัฐอเมริกาเพียงอย่างเดียว นั่นคือประมาณ 127 ปีของวัน เนื่องจากอายุการใช้งานเฉลี่ยของมนุษย์ดีกว่าซึ่งหมายความว่าการปะทะ DOB นั้นมีความแน่นอนทางคณิตศาสตร์
ทั้งหมดที่ฉันพูดคือการที่การรวมกันของเขตข้อมูลที่ไม่ซ้ำกันอาจนำไปสู่ความยุ่งยากของผู้ใช้ / ลูกค้าในอนาคต
ลองพิจารณาสิ่งที่ไม่เหมือนใครเช่นหมายเลขประจำตัวประชาชนถ้าเหมาะสม
(ฉันรู้ว่าฉันมางานปาร์ตี้สายเกินไป แต่มันจะช่วยผู้อ่านในอนาคตได้)
คุณอาจต้องการเพิ่มข้อ จำกัด โดยไม่มีดัชนี สิ่งนี้จะขึ้นอยู่กับฐานข้อมูลที่คุณใช้ ด้านล่างคือตัวอย่างโค้ดการโยกย้ายสำหรับ Postgres (tracking_number, carrier)
คือรายการของคอลัมน์ที่คุณต้องการใช้สำหรับข้อ จำกัด
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
มีข้อ จำกัด ต่าง ๆ ที่คุณสามารถเพิ่มได้ อ่านเอกสาร
add_index
วิธีการ ;)
pg_constraint
ตาราง
สวัสดีคุณสามารถเพิ่มดัชนีที่ไม่ซ้ำกันในการโยกย้ายของคุณไปยังคอลัมน์ตัวอย่างเช่น
add_index(:accounts, [:branch_id, :party_id], :unique => true)
หรือแยกดัชนีเฉพาะสำหรับแต่ละคอลัมน์
ในตัวอย่างทั่วไปของตารางการเข้าร่วมระหว่างผู้ใช้และโพสต์:
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
พยายามสร้างสองระเบียนที่คล้ายกันจะโยนข้อผิดพลาดฐานข้อมูล (Postgres ในกรณีของฉัน):
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"
เช่นการทำเช่นนั้น:
Ownership.create!(user_id: user_id, post_id: post_id)
Ownership.create!(user_id: user_id, post_id: post_id)
ตัวอย่างที่รันได้ทั้งหมด: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced
db/schema.rb
สร้าง: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a
เพื่อความสมบูรณ์และเพื่อหลีกเลี่ยงความสับสนที่นี่มี 3 วิธีในการทำสิ่งเดียวกัน: การ
เพิ่มข้อ จำกัด ที่ไม่ซ้ำกันที่มีชื่อให้กับการรวมกันของคอลัมน์ใน Rails 5.2+
สมมติว่าเรามีตารางสถานที่ตั้งซึ่งเป็นของผู้โฆษณาและมีคอลัมน์ reference_code และคุณต้องการเพียง 1 รหัสอ้างอิงต่อผู้โฆษณา ดังนั้นคุณต้องการเพิ่มข้อ จำกัด ที่ไม่ซ้ำกันในการรวมกันของคอลัมน์และตั้งชื่อ
ทำ:
rails g migration AddUniquenessConstraintToLocations
และทำให้การย้ายข้อมูลของคุณดูเป็นไปอย่างนี้
class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
def change
add_index :locations, [:reference_code, :advertiser_id], unique: true, name: 'uniq_reference_code_per_advertiser'
end
end
หรือรุ่นบล็อกนี้
class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
def change
change_table :locations do |t|
t.index ['reference_code', 'advertiser_id'], name: 'uniq_reference_code_per_advertiser', unique: true
end
end
end
หรือเวอร์ชัน SQL ดิบนี้
class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
def change
execute <<-SQL
ALTER TABLE locations
ADD CONSTRAINT uniq_reference_code_per_advertiser UNIQUE (reference_code, advertiser_id);
SQL
end
end
สิ่งเหล่านี้จะมีผลเหมือนกันตรวจสอบของคุณ schema.rb