จัดทำดัชนีหลายคอลัมน์ใน Ruby on Rails


98

ฉันกำลังใช้ฟังก์ชันเพื่อติดตามว่าผู้ใช้อ่านบทความใดบ้าง

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

นี่คือการย้ายข้อมูลของฉันจนถึงตอนนี้:

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

ตาราง user_views จะถูกสอบถามเพื่อค้นหาทั้งสองคอลัมน์เสมอไม่ใช่เพียงคอลัมน์เดียว คำถามของฉันคือดัชนีของฉันควรมีลักษณะอย่างไร ลำดับของตารางเหล่านี้มีความแตกต่างกันหรือไม่ควรมีตัวเลือกมากกว่านี้หรืออะไรก็ตาม ฐานข้อมูลเป้าหมายของฉันคือ Postgres

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

ขอบคุณ.

อัปเดต:
เนื่องจากมีเพียงแถวเดียวที่มีค่าเดียวกันในทั้งสองคอลัมน์ (เนื่องจากทราบว่า user_id HAS อ่าน article_id หรือไม่) ฉันควรพิจารณาตัวเลือก: unique หรือไม่ หากฉันไม่เข้าใจผิดนั่นหมายความว่าฉันไม่ต้องทำการตรวจสอบใด ๆ ด้วยตัวเองและเพียงแค่ทำการแทรกทุกครั้งที่ผู้ใช้เข้าชมบทความ


"ตาราง user_views จะถูกสอบถามเพื่อค้นหาทั้งสองคอลัมน์เสมอไม่ใช่เพียงคอลัมน์เดียว" - จะไม่มีการค้นหา "ค้นหาบทความทั้งหมดที่ผู้ใช้รายนี้ดู" หรือ "ค้นหาผู้ใช้ทั้งหมดที่ดูบทความนี้"? ฉันพบว่าน่าแปลกใจ
David Aldridge

คำตอบ:


219

คำสั่งมีความสำคัญในการจัดทำดัชนี

  1. ใส่ฟิลด์ที่เลือกได้มากที่สุดก่อนนั่นคือฟิลด์ที่ จำกัด จำนวนแถวให้เร็วที่สุด
  2. ดัชนีจะถูกใช้เพียงตราบเท่าที่คุณใช้คอลัมน์ในลำดับเริ่มต้นที่จุดเริ่มต้น เช่นถ้าคุณดัชนีใน[:user_id, :article_id]คุณสามารถดำเนินการสอบถามอย่างรวดเร็วบนuser_idหรือแต่ไม่ได้อยู่ในuser_id AND article_idarticle_id

add_indexบรรทัดการย้ายข้อมูลของคุณควรมีลักษณะดังนี้:

add_index :user_views, [:user_id, :article_id]

คำถามเกี่ยวกับตัวเลือก "เฉพาะ"

วิธีง่ายๆในการทำสิ่งนี้ใน Rails คือการใช้validatesในโมเดลของคุณโดยมีขอบเขตuniquenessดังนี้ ( เอกสารประกอบ ):

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

7
คำสั่งมีความสำคัญอย่างมากในการจัดทำดัชนี วางตำแหน่งที่ส่วนคำสั่งทางด้านซ้ายและกรอกดัชนีด้วยคอลัมน์ลำดับทางด้านขวา stackoverflow.com/questions/6098616/dos-and-donts-for-indexes
Denis de Bernardy

1
โปรดทราบว่าvalidates_uniqueness_of(และลูกพี่ลูกน้องvalidates uniqueness:) มีแนวโน้มที่จะติดเงื่อนไขการแข่งขัน
Ben Aubin

1
ตามที่กล่าวไว้ในความคิดเห็นด้านบนและstackoverflow.com/a/1449466/5157706และstackoverflow.com/a/22816105/5157706ให้พิจารณาเพิ่มดัชนีที่ไม่ซ้ำกันในฐานข้อมูลด้วย
Akash Agarwal

25

เพียงคำเตือนเกี่ยวกับการตรวจสอบความไม่ซ้ำกันในเวลาตรวจสอบความถูกต้องเทียบกับดัชนี: หลังทำโดยฐานข้อมูลในขณะที่สีรองพื้นทำโดยโมเดล เนื่องจากอาจมีหลายอินสแตนซ์ของโมเดลที่ทำงานในเวลาเดียวกันการตรวจสอบความถูกต้องขึ้นอยู่กับเงื่อนไขการแข่งขันซึ่งหมายความว่าอาจไม่สามารถตรวจพบรายการที่ซ้ำกันได้ในบางกรณี (เช่นส่งแบบฟอร์มเดียวกันสองครั้งในเวลาเดียวกัน)


แล้วอันไหนดีกว่ากัน? ฝั่งฐานข้อมูลหรือ validates_uniqueness_of?
WM

9
ทั้งสอง. validates_uniqueness_of สามารถใช้เพื่อแสดงข้อความแสดงข้อผิดพลาดอย่างสง่างามในแอปพลิเคชันตัวอย่างเช่นเมื่อฟอร์มได้รับการบันทึก ข้อ จำกัด ของฐานข้อมูลจะทำให้แน่ใจว่าคุณไม่ได้ลงเอยด้วยการบันทึกข้อมูลซ้ำ ๆ แม้จะรู้ว่าคุณมีการตรวจสอบที่ระบุไว้ในโมเดล นอกจากนี้คุณสามารถช่วยเหลือข้อยกเว้น ActiveRecord และแสดงข้อความที่ดีให้กับผู้ใช้
Uģis Ozols

5
@WM ถ้าคุณต้องเลือกอย่างใดอย่างหนึ่งไปกับข้อ จำกัด ของฐานข้อมูล สิ่งนี้จะทำงานได้แม้ว่าแอปพลิเคชัน RoR ที่แตกต่างกันจะไม่โต้ตอบกับข้อมูลของคุณและทำให้มั่นใจได้ว่าจะมีความสม่ำเสมอในระยะยาว
mooreds
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.