2016-06-03 4 views
0

나는 아래와 같은 개인 인스턴스 사용자 모델 방법이 안타 -리팩토링 코드는

def generate_authentication_token 
    loop do 
    token = Devise.friendly_token 
    break token unless self.class.unscoped.where(authentication_token: token).first 
    end 
end 

우리가 아니, 그 가정하자. 사용자 레코드는 100 조입니다. 위의 스크립트를 실행하고 각 반복에서 생성 된 토큰이 레코드와 일치하면 루프는 100 조 회 반복됩니다. 레코드를 검색하기 위해 DBMS에서도 마찬가지입니다. 반복을 줄이고 db-hits를 줄임으로써 (각 반복마다 일치하는 레코드가 제공됨)이 문제를 신속하게 해결할 수있는 솔루션이 있습니까? 그리고 진지하게, 미안 해요! 질문이 이해가 안되면 알려주세요. 최대한 빨리 삭제하겠습니다. 감사. 해피 코딩.

+1

을 목표로하는 100 조 사용자를 위해 비효율적 인 것인가? – mlovic

+0

예, 색인 생성은 authentication_token 필드에 적용됩니다. – codemilan

답변

1

코드가 정상적으로 보입니다. find_by(authentication_token: token)은 일반적으로 단일 레코드를 검색하는 데 선호됩니다.

authentication_token 열에 대한 색인을 추가했는지 확인하십시오. 많은 레코드가 있으면 쿼리 속도가 크게 빨라집니다. 데이터베이스 색인 생성에 대해 잘 모르는 경우 this 답변을 참조하십시오.

첫 번째 시도에서조차 일치하는 토큰을 발견 할 수있는 가능성이 희박하므로 반복 횟수 나 db 히트 수를 최적화하는 것에 대해 걱정하지 않겠습니다.

1

왜 이런 식으로 사용합니까? 여기

token = Digest::MD5.hexdigest (rand.to_s << Time.now.to_i.to_s)

나는 임의의 숫자를 생성하고 그것으로 현재 시간 스탬프를 추가하고 문자열 값에 대한 MD5 해시를 얻고있다. 그것은 꽤 좋은 비밀 토큰이 될 것이고 그것은 유일 할 것이다.

여전히 고유성 기준에 만족하지 않으면 시작 부분에 ID을 추가하기 만하면됩니다.

관련된 쿼리가 없습니다.

+1

고유 한 것은 아닙니다. 다른 입력 문자열을 동일한 출력으로 다이제스트 할 수 있습니다. –

1

임의의 아직 고유 한 토큰을 만들려고합니다. 나에게 UUID처럼 들린다. 당신은 https://github.com/assaf/uuid

당신의 접근 방식은 작동 시도 할 수 있지만, 당신은 당신이 이미`authentication_token` 컬럼의 인덱스가 있습니까 :-)