Trong Ruby On Rails cung cấp nhiều cách để giúp chúng ta làm việc trên cơ sở dữ liệu một cách dễ dàng. Nhưng đôi khi, chúng ta sẽ cần phải chèn một lượng lớn dữ liệu vào cơ sở dữ liệu. Đối với cách đơn giản, nếu chúng ta chèn từng bản ghi sẽ mất rất nhiều thời gian để hoàn thành và nó không tốt cho hiệu suất. Trong bài viết này, tôi sẽ giới thiệu về cách sử dụng gem activerecord-import
để tăng tốc độ chèn nhiều dữ liệu bằng cách chỉ sử dụng một câu lệnh INSERT.
Activerecord
Bây giờ chúng tôi có một bảng gọi Company
như dưới đây:
1 2 3 4 5 6 | create_table :companies do |t| t.column :name, :string t.column :description, :text t.column :address, :string end |
Chúng tôi muốn chèn 200 000 công ty và mã bên dưới, chúng tôi sử dụng ActiveRecord để chèn dữ liệu:
1 2 3 4 | 200_000.times do |n| Company.create name: "#company_#{n}", description: "description_#{n}", address: "address_#{n}" end |
Như đoạn mã trên, bạn có thể thấy mỗi khi tạo bản ghi với ActiveRecord, một câu lệnh INSERT được tạo và gửi đến cơ sở dữ liệu. Nếu bạn có 200 000 bản ghi như trên, nó sẽ được tạo 200 000 câu lệnh INSERT cần được tạo và bạn cần gọi 200 000 lần tới db. Cách này làm cho chức năng của bạn tốn thời gian và làm giảm hiệu suất của ứng dụng vì phải mất nhiều lệnh SQL để ghi dữ liệu.
Bây giờ chúng ta học cách sử dụng gem "activerecord-import" để có cách chèn dữ liệu tốt hơn.
Nhập Gem ActiveRecord
Gem activerecord-import
là thư viện được sử dụng để chèn một số lượng lớn các bản ghi vào cơ sở dữ liệu sử dụng ActiveRecord. Bằng cách sử dụng gem này, nó cho phép chúng ta sử dụng một lệnh chèn với rất nhiều dữ liệu. Và những cách này có thể giúp bạn cải thiện hiệu suất trong ứng dụng của mình.
Thêm nhập Gem ActiveRecord vào Gemfile
của bạn:
1 2 | gem "activerecord-import", "1.0.4" |
Thêm mã như bên dưới vào tệp application.rb
1 2 3 | require "activerecord-import/base" ActiveRecord::Import.require_adapter("mysql2") |
Nếu bạn sử dụng mã postgres sẽ như dưới đây:
1 2 3 | require "activerecord-import/base" ActiveRecord::Import.require_adapter("postgres") |
Bây giờ chúng ta có thể sử dụng gem activerecord-import
để nhập dữ liệu và chúng ta vẫn cần chèn 200 000 công ty như trên.
Chèn dữ liệu và xác thực mô hình
Để import
hàm, chúng ta có thể sử dụng một mảng các đối tượng mô hình để chèn dữ liệu.
1 2 3 4 5 6 7 8 | companies = [] 200_000.times do |n| companies << Company.new name: "#company_#{n}", description: "description_#{n}", address: "address_#{n}" end # with validations Comppany.import companies, validate: true |
Nếu bạn muốn dữ liệu chèn của mình nhanh hơn, bạn có thể chèn mà không cần xác thực.
1 2 3 4 5 6 7 8 | companies = [] 200_000.times do |n| companies << Company.new name: "#company_#{n}", description: "description_#{n}", address: "address_#{n}" end # without validations Comppany.import companies, validate: false |
Chèn dữ liệu với cột và mô hình
Chúng ta cũng có thể sử dụng một mảng các đối tượng mô hình với chức năng import
. Tên cột được sử dụng để chỉ định các trường được nhập vào cơ sở dữ liệu.
1 2 3 4 5 6 7 8 | companies = [] columns = [:name, :description, :address] 200_000.times do |n| companies << Company.new name: "#company_#{n}", description: "description_#{n}", address: "address_#{n}" end Comppany.import columns, companies |
Chèn dữ liệu bằng Hash
Phương thức import
có thể sử dụng với mảng các đối tượng băm và dữ liệu sẽ được chèn vào cơ sở dữ liệu bằng khóa đến trường cụ thể trong db.
1 2 3 4 5 6 7 | companies = [] 200_000.times do |n| companies << {name: "#company_#{n}", description: "description_#{n}", address: "address_#{n}"} end Comppany.import companies |
Chèn dữ liệu với dữ liệu cột và mảng
Với chức năng import
, chúng ta có thể chèn một mảng tên cột và một mảng các mảng khác. Mỗi mảng con đại diện cho một bản ghi và liệt kê các giá trị theo thứ tự như các cột được chỉ định.
1 2 3 4 5 6 7 8 | columns = [:name, :description, :address] companies = [] 200_000.times do |n| companies << ["#company_#{n}", "description_#{n}", "address_#{n}"] end Comppany.import columns, companies |
Chèn dữ liệu với các cột và dữ liệu băm
Chúng ta cũng có thể sử dụng với một mảng tên cột và một mảng các đối tượng băm. Tên cột được sử dụng để chỉ định các trường được nhập vào cơ sở dữ liệu.
1 2 3 4 5 6 7 8 | columns = [:name, :description, :address] companies = [] 200_000.times do |n| companies << {name: "#company_#{n}", description: "description_#{n}", address: "address_#{n}"} end Comppany.import columns, companies |
Phần kết luận
nó không phải là một giải pháp tốt để chèn nhiều dữ liệu vào cơ sở dữ liệu theo vòng lặp và tạo cho từng bản ghi một vì nó mất thời gian và làm cho ứng dụng trở nên kém hiệu quả. Nắm bắt được điều này, bạn có thể sử dụng gem activerecord-import
tối ưu hóa tốc độ và hiệu suất, đồng thời cung cấp các tùy chọn validate
. Nguồn tham khảo: https://github.com/zdennis/activerecord-import