내 사용자 테이블에 열을 추가하고 모두에 대해 슬러그를 생성하고 싶습니다. 문제는 DB에 1 백만 명이 넘는 사용자가 있다는 것입니다.레일스에서 DB 성능에 영향을주지 않으면 서 단시간에 1 백만 명의 사용자가있는 테이블에 사용자를위한 슬러그를 생성합니까?
다양한 방법을 설명하는 여러 블로그를 보았지만 제작 DB에서 위험을 감수하고 싶지 않습니다.이
아래의 방법은 이동 파일 자체에 슬러그를 생성 에 코드를 추가 제안 : 내가 찾은
방법. 나는 레이크 작업에 의해 실행되는이 방법을 쓴
class AddStatusToUser < ActiveRecord::Migration class User < ActiveRecord::Base end def up add_column :users, :status, :string User.find_each do |user| user.status = 'active' user.save! end end def down remove_column :users, :status end end
: 아래 하나의 문제는 400 000 슬러그 지금까지 생성 된있는 사일 실행 된 것입니다. 나는 그것을 빨리하고 싶었지만 어떻게해야할지 모른다.
는 배열로 찾기 옵션에 의해 발견 된 기록의 각 배치를 얻을 수 있습니다. 각 배치의 크기는 : batch_size 옵션으로 설정됩니다. 기본값은 1000입니다.
: start 옵션을 제공하여 일괄 처리의 시작점을 제어 할 수 있습니다. 이는 동일한 처리 대기열을 다루는 여러 작업자가 을 원할 때 특히 유용합니다. 작업자 1이 id 0과 10,000 사이의 모든 레코드를 처리하도록하고 작업자 2 을 10,000 이상에서 처리하도록 할 수 있습니다 (해당 작업자의 : start 옵션 설정).
주문을 설정할 수 없습니다. 이는 기본 키 ("id ASC")에서 오름차순으로 자동 설정되어 배치 순서 이 작동하게합니다. 즉,이 방법은 정수 기반 기본 키에서만 작동합니다. 제한을 설정할 수 없으므로 배치 크기를 제어하는 데 사용됩니다.
DB 성능 문제를 피하기 위해 1000 명의 사용자가 모든 슬러그 생성 후 2 초의 절전 시간을 제공했습니다. 수면 방법을 제거해야합니까? 방금 User.find_each(&:save)
또는 방법 1을 실행해야합니까?
task :add_slug_to_all_users => :environment do
i=0
batchSize = 1000
puts "started at :#{Time.now}"
# find_in_batches method provides the users in batches of 1000
# so that the update is not triggered for all the rows at once which may lock the table completely.
User.where("slug is null and email is not null").find_in_batches(batch_size: batchSize) do |users|
sleep(2)
users.each {|u| u.save!; i+=1;}
puts "updated #{i} records at: #{Time.now}"
end
puts "Completed the Task at: #{Time.now}\n"
end
업데이트 1 : 나는 굼벵이를 생성하는 friendly_id 보석을 사용하고 있습니다.
업데이트 2는 : 나는 SHOW CREATE TABLE users
를 실행하고 나는이있어 :
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`p_views` int(11) DEFAULT '0',
`p_desc` text COLLATE utf8_unicode_ci,
`p_title` text COLLATE utf8_unicode_ci,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`t_zone` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'UTC',
`college` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
`degree` text COLLATE utf8_unicode_ci,
`p_no` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
`slug` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_phone_number` (`p_no`),
UNIQUE KEY `index_users_on_phone_no` (`p_no`),
UNIQUE KEY `index_users_on_slug` (`slug`),
KEY `use_index_on_college` (`college`(255))
) ENGINE=InnoDB AUTO_INCREMENT=2194 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
내가 위의 결과에서 대부분의 필드를 제거했는지 유의하시기 바랍니다.slug
열은 first_name 및 last_name의 조합을 URL에 친숙한 방식으로 저장합니다.
예 : 사용자의 이름 인 경우 다음과 같을 것이다 생성
id first_name last_name
1 Arun Kumar
2 Arun Kumar
슬러그 :
id slug
1 arun-kumar
2 arun-kumar1
제목과 질문을 수정해야하며 lakh (= 100,000)은 인도 국외에서 사용되지 않습니다. –
@MichaelKohl 덕분에 1 백만 달러로 변경했습니다. – sahil
슬러그가 어떻게 생성됩니까? 단일 쿼리에서 사용자 배치를 업데이트하는 것이 더 좋을 것이라고 생각합니다. – unkmas