문제

안녕하세요. 9자리 고유 계좌번호를 생성해야 합니다.내 의사 코드는 다음과 같습니다.

function generateAccNo()

    generate an account number between 100,000,000 and 999,999,999

    if the account number already exists in the DB 
        call generateAccNo()    /* recursive call */
    else
        return new accout number
    end if

end function

기능은 잘 작동하는 것 같은데, 재귀호출이 좀 걱정되네요.

이로 인해 메모리 누수가 발생합니까(아파치에서 PHP 5)?

이것이 이 문제를 해결하는 데 허용되는 방법입니까?

귀하의 의견에 감사드립니다.

도움이 되었습니까?

해결책

이로 인해 스택 오버플로가 발생할 수 있다는 사실을 알고 계셨나요?고객 수가 증가할수록 적합한 계좌 번호를 찾지 못할 확률도 높아집니다.

그리고 왜 계좌번호를 순차적으로 만들고 매번 1씩 늘리면 안되나요?이 접근 방식을 사용하면 현재 데이터베이스에 있는 최대 ID를 읽고 이를 증가시키기만 하면 됩니다.

너무 무뚝뚝해서 미안하지만 귀하의 솔루션은 문제를 해결하는 끔찍한 방법입니다.스택이 무한히 커질 수 있으므로 엄청난 양의 메모리를 사용하고 데이터베이스에 대해 엄청난 양의 값비싼 호출을 수행하게 됩니다.

실제로 다른 접근 방식을 고려해야 합니다.
고객을 생성할 때마다 고객 번호를 늘리는 것이 좋습니다.실제로 DB를 올바르게 설정하면(id 열에 자동 증가 포함) ID를 설정할 필요조차 없습니다.새로운 고객을 추가할 때마다 ID가 설정됩니다.

다른 팁

나는 그것이 재귀 대 재귀로 귀결되지 않는다고 생각합니다.루핑의 경우 데이터 세트가 증가하고 난수 생성이 올바르게 구현되지 않으면 둘 다 문제가 발생하기 쉽습니다.두 가지 아이디어가 떠오릅니다.

.GUID

가능한 한 적은 노력으로 고유한 ID가 필요한 경우 GUID를 고려하십시오. 코드에서 ID를 생성하지 않더라도 DB는 삽입 시 할당할 수 있습니다.사용자 친화적이지는 않지만 고유성이 보장됩니다.그러나 삽입 시 DB에서 생성된 순차적 AccountRecordId와 결합하면 견고한 조합이 됩니다.

.복합 키:무작위 + 순차

모든 요구 사항을 해결하는 한 가지 방법은 표면적으로는 다소 복잡해 보이지만 5자리(또는 그 이상)의 연속 DB 키와 또 다른 5자리 무작위로 복합 계좌 번호를 만드는 것입니다.난수가 중복된 경우 순차적 ID가 전체 계좌 번호의 고유성을 보장하므로 문제가 되지 않습니다.

여기서는 재귀 호출을 사용할 필요가 없습니다.조건부로 존재하지 않는지 테스트하는 함수에서 간단한 while 루프를 실행합니다.

function generateAccNo()

    generate an account number between 100,000,000 and 999,999,999

    while ( the account number already exists in the DB ) {
         generate new account number;
    }
    return new account number

end function

하지만 이 코드가 장난감이 아닌 다른 용도인 경우 무작위 생성 및 테스트는 고유 계정 번호를 생성하는 데 최적이 아닌 접근 방식입니다.

괜찮은 것 같지만, 일종의 주사위 조건이 필요한 것 같습니다. 포기하기 전에 이것을 몇 번이나 실행하시겠습니까?

나는 이것이 엄청난 숫자 범위에서는 불가능해 보인다는 것을 알고 있지만 뭔가 잘못되어 이전 통화로 돌아가게 되고 다시 구역질이 날 수도 있습니다.

계좌 번호를 순차적으로 생성하는 것은 보안 위험이 있습니다. 이를 수행하려면 다른 알고리즘을 찾아야 합니다.

또는 고유한 계좌 번호로 알려진 생성된 버퍼가 포함된 별도의 테이블을 유지 관리할 수 있습니다.이 테이블에는 자동 증가 정수 ID가 있어야 합니다.계좌 번호를 원할 경우 버퍼에서 가장 낮은 인덱스를 가진 레코드를 가져와서 해당 테이블에서 제거하면 됩니다.버퍼를 보충하고 용량 >> 정상적인 사용량을 보장하는 정기적으로 실행되는 일부 프로세스가 있습니다.장점은 최종 사용자가 계정 번호를 생성하는 데 소요되는 시간이 본질적으로 일정하다는 것입니다.

또한 처리 오버헤드나 재귀 또는 반복의 위험, 실제 문제는 결정론과 데이터베이스 쿼리 반복으로 인한 오버헤드라는 점에 유의해야 합니다.나는 TheZenker의 무작위 + 순차 솔루션을 좋아합니다.불필요한 오버헤드를 추가하지 않고 고유한 ID를 생성하는 것이 보장됩니다.

여기서는 재귀를 사용할 필요가 없습니다.간단한 루프도 마찬가지로 빠르고 스택 공간을 덜 소모합니다.

while 루프에 넣을 수 있습니다.

function generateAccNo()

    while (true) {    

      generate an account number between 100,000,000 and 999,999,999

      if the account number already exists in the DB 
          /* do nothing */
      else
          return new accout number
      end if
    }

end function

왜 안 돼:

lock_db
do
    account_num <= generate number
while account_num in db

put row with account_num in db

unlock_db

데이터베이스에서 이를 처리하지 않는 이유는 무엇입니까?SQL Server에서는 100000000에서 시작하는 ID 열만 가질 수 있습니다.또는 가지고 있는 모든 DB에서 SQL을 사용할 수 있습니다.최대 ID에 1을 더하면 됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top