Rails: การเพิ่มดัชนีหลังจากเพิ่มคอลัมน์


119

สมมติว่าฉันสร้างตารางtableในแอป Rails ในเวลาต่อมาฉันเพิ่มคอลัมน์ที่กำลังทำงาน:

rails generate migration AddUser_idColumnToTable user_id:string. 

จากนั้นฉันก็รู้ว่าฉันต้องเพิ่มuser_idเป็นดัชนี ฉันรู้เกี่ยวกับadd_indexวิธีการนี้ แต่วิธีนี้ควรเรียกว่าที่ไหน? ฉันควรจะเรียกใช้การย้ายข้อมูล (ถ้าใช่อันไหน) จากนั้นเพิ่มวิธีนี้ด้วยมือ

คำตอบ:


235

คุณสามารถเรียกใช้การย้ายข้อมูลอื่นสำหรับดัชนีเท่านั้น:

class AddIndexToTable < ActiveRecord::Migration
  def change
    add_index :table, :user_id
  end
end

4
ดังนั้นฉันเพียงแค่เรียกใช้ในคอนโซลของฉัน: ทางรถไฟสร้างการโยกย้าย AddIndexToTable?
user1611830

3
ใช่คุณสามารถทำได้ แต่คุณจะต้องแก้ไขการย้ายข้อมูลนั้นในภายหลังเพื่อให้สอดคล้องกับโค้ดด้านบน
Jaap Haagmans

Is: table ควรเป็นพหูพจน์?
สุสาน

1
@tomb ฉันใช้ตัวอย่างจากคำถามเดิม :tableเป็นชื่อตารางที่เกิดขึ้นจริงดังนั้นในกรณีของการเป็นusersตารางที่คุณต้องการทดแทนสำหรับ:users :table
Jaap Haagmans

65

หากคุณต้องการสร้างuser_idมันจะเป็นข้อสันนิษฐานที่สมเหตุสมผลว่าคุณกำลังอ้างถึงตารางผู้ใช้ ในกรณีนี้การโยกย้ายจะต้อง:

rails generate migration AddUserRefToProducts user:references

คำสั่งนี้จะสร้างการย้ายข้อมูลต่อไปนี้:

class AddUserRefToProducts < ActiveRecord::Migration
  def change
    add_reference :user, :product, index: true
  end
end

หลังจากรันrake db:migrateทั้งuser_idคอลัมน์และดัชนีจะถูกเพิ่มลงในproductsตาราง

ในกรณีที่คุณเพียงแค่ต้องเพิ่มดัชนีเพื่อคอลัมน์ที่มีอยู่เช่นnameของuserตารางเทคนิคต่อไปนี้อาจจะมีประโยชน์:

rails generate migration AddIndexToUsers name:string:index จะสร้างการย้ายข้อมูลต่อไปนี้:

class AddIndexToUsers < ActiveRecord::Migration
  def change
    add_column :users, :name, :string
    add_index :users, :name
  end
end

ลบadd_columnบรรทัดและเรียกใช้การย้ายข้อมูล

ในกรณีที่อธิบายไว้คุณสามารถออกrails generate migration AddIndexIdToTable index_id:integer:indexคำสั่งแล้วลบadd_columnบรรทัดจากการย้ายข้อมูลที่สร้างขึ้น แต่ขอแนะนำให้เลิกทำการย้ายข้อมูลครั้งแรกและเพิ่มข้อมูลอ้างอิงแทน:

rails generate migration RemoveUserIdFromProducts user_id:integer
rails generate migration AddUserRefToProducts user:references

ขอบคุณ Vadym สำหรับคำตอบที่สมบูรณ์ คำถามสุดท้าย: เหตุใดคุณจึงแนะนำให้ยกเลิกการย้ายข้อมูลครั้งแรก มีปัญหาด้านประสิทธิภาพที่เกี่ยวข้องกับการเพิ่มดัชนีในภายหลังหรือไม่
Flavio Wuensche

2
ถึง @fwuensche: ไม่มีบทลงโทษสำหรับการเพิ่มดัชนีในภายหลัง แม้ว่าตรรกะของโดเมนจะมีความชัดเจนน้อยลง เช่นในกรณีที่คุณตัดสินใจที่จะทำลาย / นามธรรม / ฯลฯ การเชื่อมโยงในภายหลังคุณจะต้องจัดการกับการย้ายข้อมูลสองรายการที่แยกจากกันซึ่งจริงๆแล้วควรเป็นแบบเดียว ...
Vadym Tyemirov

6
คำเตือน: โปรดทราบว่า index: true ใช้ได้เฉพาะในการย้ายข้อมูล create_table การย้ายข้อมูลจะทำงาน แต่จะไม่มีการสร้างดัชนี ดูmakandracards.com/makandra/…
rmcsharry

9

เพิ่มในการย้ายข้อมูลที่สร้างขึ้นหลังจากสร้างคอลัมน์ต่อไปนี้ (ตัวอย่าง)

add_index :photographers, :email, :unique => true

คุณหมายถึงสิ่งนี้ def self.up add_column ... end add_index ... ?
user1611830

6

สำหรับการอ้างอิงคุณสามารถโทร

rails generate migration AddUserIdColumnToTable user:references

หากในอนาคตคุณต้องเพิ่มดัชนีทั่วไปคุณสามารถเปิดสิ่งนี้ได้

rails g migration AddOrdinationNumberToTable ordination_number:integer:index

สร้างรหัส:

class AddOrdinationNumberToTable < ActiveRecord::Migration
  def change
   add_column :tables, :ordination_number, :integer
   add_index :tables, :ordination_number, unique: true
  end
end

0

คุณสามารถใช้สิ่งนี้เพียงแค่คิดว่า Job คือชื่อของโมเดลที่คุณกำลังเพิ่มดัชนีcader_id :

class AddCaderIdToJob < ActiveRecord::Migration[5.2]
  def change
    change_table :jobs do |t|
      t.integer :cader_id
      t.index :cader_id
    end
  end
end
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.