키가 두 값으로 구성된 해시의 조회 요소

헥터 에르난데스

데이터베이스에서 다음 구조를 검색해야합니다.

    User ID
    User Name
    First Name
    Last Name
    Employee Number

이 필드는 빠른 액세스를 위해 메모리, 즉 캐시에 저장합니다. 평균적으로 약 300,000 개의 레코드를 이야기하고 있습니다.

내 문제는 때때로 사용자 이름과 직원 번호로 빠른 쿼리를위한 구조를 만들어야한다는 것입니다. 사용자 ID로는 절대 사용하지 말고 앞서 언급 한 두 필드 만 사용하세요.

사전에서 나는 유일한 핵심 원칙에 묶여 있으므로 ...

-사전에서 사용하기 위해 사용자 이름과 직원 번호를 결합한 키를 만드는 방법이 있습니까?

여기서 문제는 때때로 사용자가 조회를 위해 사용자 이름을 제공하고 때로는 직원 번호를 가지지 만 동시에 둘 다 가질 수 없다는 것입니다.

따라서이 키는 MyKey ( "user-name", "") 및 MyKey ( "", "employee-number")가 맵에서 동일한 레지스트리를 검색해야한다고 가정합니다.

메모리에 두 개의 사전을 만드는 것을 피하고 싶습니다. 하나는 사용자 이름으로 검색하고 다른 하나는 직원 번호로 검색합니까?

대안은 DB의 결과를 큰 목록에 저장 한 다음 Linq로 쿼리하는 것입니다. 그러나 이것은 O (n) 검색이 될 것이며 여기서 성능에 대해 이야기하고 있습니다.

헥터 에르난데스

그래서 Type과 Value로 Key 객체를 만드는 문제를 해결했습니다.

/// <summary>
/// Represents a composite key for cached objects
/// </summary>
public class MultiKey
{
    /// <summary>
    /// The type of key
    /// </summary>
    public enum Type
    {
        /// <summary>
        /// The key represents a User Name
        /// </summary>
        UserName,

        /// <summary>
        /// The key represents an Employee Number
        /// </summary>
        EmployeeNumber
    }

    /// <summary>
    /// Gets or sets the Type of the Key.
    /// </summary>
    public Type KeyType { get; set; }

    /// <summary>
    /// Gets or sets the value of the Key
    /// </summary>
    public string Key { get; set; }

    /// <summary>
    /// Compare based on hash code
    /// </summary>
    /// <param name="obj">the object to compare against</param>
    /// <returns>true if both objects are equals, false otherwise</returns>
    public override bool Equals(object obj)
    {
        if (obj is FormCacheKey)
        {
            return (obj as FormCacheKey).GetHashCode() == this.GetHashCode();
        }

        return false;
    }

    /// <summary>
    /// Compares based on hash code
    /// </summary>
    /// <param name="p1">left side of the operator</param>
    /// <param name="p2">right side of the operator</param>
    /// <returns>true if both items are equal, false otherwise</returns>
    public static bool operator ==(FormCacheKey p1, FormCacheKey p2)
    {
        if ((object)p1 == null && (object)p2 == null)
        {
            return true;
        }
        if ((object)p1 == null || (object)p2 == null)
        {
            return false;
        }
        return p1.Equals(p2);
    }

    /// <summary>
    /// Compares based on hash code
    /// </summary>
    /// <param name="p1">left side of the operator</param>
    /// <param name="p2">right side of the operator</param>
    /// <returns>true if both items are different, false otherwise</returns>
    public static bool operator !=(FormCacheKey p1, FormCacheKey p2)
    {
        return !(p1 == p2);
    }

    /// <summary>
    /// Returns a hash key code that identifies this object
    /// </summary>
    /// <returns>The hash code.</returns>
    public override int GetHashCode()
    {
        const int CoPrimeNumber = 37;
        var finalHashCode = 17;

        finalHashCode = (finalHashCode * CoPrimeNumber) + this.KeyType.GetHashCode();
        finalHashCode = (finalHashCode * CoPrimeNumber) + this.Key.GetHashCode();

        return finalHashCode;
    }
}

그 후 나는 다음과 같은 사전을 만들었습니다.

var cache = new Dictionary<MultiKey, User>();

마지막으로 다음과 같이 사전에 키와 값을 추가했습니다.

foreach (var user in users)
{
    var userNameKey = new MultiKey { KeyType = MultiKey.Type.UserName, Key = user.UserName };
    cache.Add(userNameKey, user);
    var employeeNumberKey = new MultiKey { KeyType = MultiKey.Type.EmployeeNumber, Key = user.EmployeeNumber };
    cache.Add(employeeNumberKey, user);
}

성능에 대한 메모 동료에게 말하면서 그는 내가 MultiKey에서 사용한 접근 방식 대신 두 개의 해시 테이블 기술을 옹호하고있었습니다. 그는 두 개의 창 모양 해시에서 문자열 키를 사용하는 검색 (액세스) 중 성능이 복잡한 키가있는 단일 캐시보다 '빠르거나' '성능이 높다'고 주장했습니다. 그의 주장은 캐시가 더 크고 복잡 할 때 충돌이 더 많이 발생하는 경향이 있다는 것입니다. 여러분의 의견을 듣고 싶습니다. 결국 나는이 접근 방식을 사용했고 작동합니다.

cahe의 항목에 액세스하려면 MultiKey 개체 또는이를 재생성하는 수단을 제공해야합니다. 그런 의미에서 다음 도우미 메서드를 만들었습니다.

private T GetFromCache<T>(CacheKey.Type type, string key)
{
    var cKey = new MultiKey { KeyType = type, Key = key };
    T item;
    cache.TryGetValue(cKey, out item);

    return item;
}

그리고 나는 이것을 다음과 같이 사용합니다.

public User GetUserByUserName(string userName)
{
    return this.GetFromDictionary<User>(MultiKey.Type.UserName, userName);
}

public User GetIndividualByEmployeeNumber(string employeeNumber)
{
    return this.GetFromDictionary<User>(MultiKey.Type.EmployeeNumber, employeeNumber);
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

사용자가 조회 한 지명이 없으면 noroom 구성 요소를 표시 할 수 없습니다.

분류에서Dev

VBA : 구성 요소별로 두 개의 범위 개체 추가

분류에서Dev

두 가지 유형의 변수로 구성된 벡터 요소를 추가하고 읽는 방법

분류에서Dev

Ruby : 두 키 값의 조합을 기반으로 해시에서 중복 감지

분류에서Dev

첫 번째 구성 요소가 이전에 실행되므로 두 구성 요소 간의 값을 공유하십시오.

분류에서Dev

mongodb, 해시 키로 조회

분류에서Dev

속성 값으로 요소를 일치시켜 두 개의 XML 파일 병합

분류에서Dev

결합 된 결과가있는 요소의 Mongodb 조회 배열

분류에서Dev

BIDS 2008-조회 테이블의 두 열에 대한 소스의 조회 값

분류에서Dev

가변 구조체 요소로 구성된 배열의 데이터에서 findmin () 사용-Julia

분류에서Dev

동적으로 생성 된 구성 요소 / 요소의 바인딩 가능한 속성에 바인딩

분류에서Dev

두 개의 React 구별되고 마운트 된 구성 요소가 소품을 사용하여 서로 통신 할 수 있습니까?

분류에서Dev

두 번째 JFrame의 구성 요소가 표시되지 않음

분류에서Dev

Pandas의 두 열 간의 일치를 기반으로 값 조회

분류에서Dev

두 구성 요소를 서로 독립적으로 추가하려면 어떻게해야합니까?

분류에서Dev

두 속성으로 구성된 기본 키에서 하나의 속성 만 외래 키로 참조하는 방법

분류에서Dev

조건으로 정의 된 가변 행 범위에서 로컬 최대 / 최소 값을 가져 오나요?

분류에서Dev

dict의 요소를 키 조건으로 다른 dict에 추가

분류에서Dev

필드 값을 기반으로 구조의 요소 찾기

분류에서Dev

기능 구성 요소의 참조를 동적으로 가져 오기-ReactJS

분류에서Dev

두 수준의 중첩 된 경로로 구성 요소를 해결하는 방법은 무엇입니까?

분류에서Dev

선택한 첫 번째 구성 요소가 두 번째 구성 요소의 내용이 동기화되지 않은 것으로 판단하는 UIPickerView

분류에서Dev

동적으로 생성 된 두 개의 Ajax 요소가 서로를 인식하지 못함

분류에서Dev

두 개의 숫자 구성 요소가있는 UIPickerVIew로 올바른 작업

분류에서Dev

하나의 요소 (Python, Selenium)에 대해 두 가지 조건으로 WebDriverWait를 사용하는 방법

분류에서Dev

공백으로 구분 된 문자열의 모든 요소에 접두사 / 접미사 추가

분류에서Dev

조인으로 두 값 사이의 시간 가져 오기

분류에서Dev

XQuery / XPath-속성의 두 요소 집합을 공통 값으로 결합

분류에서Dev

Angular2-동일한 구성 요소가 두 번 참조 됨

Related 관련 기사

  1. 1

    사용자가 조회 한 지명이 없으면 noroom 구성 요소를 표시 할 수 없습니다.

  2. 2

    VBA : 구성 요소별로 두 개의 범위 개체 추가

  3. 3

    두 가지 유형의 변수로 구성된 벡터 요소를 추가하고 읽는 방법

  4. 4

    Ruby : 두 키 값의 조합을 기반으로 해시에서 중복 감지

  5. 5

    첫 번째 구성 요소가 이전에 실행되므로 두 구성 요소 간의 값을 공유하십시오.

  6. 6

    mongodb, 해시 키로 조회

  7. 7

    속성 값으로 요소를 일치시켜 두 개의 XML 파일 병합

  8. 8

    결합 된 결과가있는 요소의 Mongodb 조회 배열

  9. 9

    BIDS 2008-조회 테이블의 두 열에 대한 소스의 조회 값

  10. 10

    가변 구조체 요소로 구성된 배열의 데이터에서 findmin () 사용-Julia

  11. 11

    동적으로 생성 된 구성 요소 / 요소의 바인딩 가능한 속성에 바인딩

  12. 12

    두 개의 React 구별되고 마운트 된 구성 요소가 소품을 사용하여 서로 통신 할 수 있습니까?

  13. 13

    두 번째 JFrame의 구성 요소가 표시되지 않음

  14. 14

    Pandas의 두 열 간의 일치를 기반으로 값 조회

  15. 15

    두 구성 요소를 서로 독립적으로 추가하려면 어떻게해야합니까?

  16. 16

    두 속성으로 구성된 기본 키에서 하나의 속성 만 외래 키로 참조하는 방법

  17. 17

    조건으로 정의 된 가변 행 범위에서 로컬 최대 / 최소 값을 가져 오나요?

  18. 18

    dict의 요소를 키 조건으로 다른 dict에 추가

  19. 19

    필드 값을 기반으로 구조의 요소 찾기

  20. 20

    기능 구성 요소의 참조를 동적으로 가져 오기-ReactJS

  21. 21

    두 수준의 중첩 된 경로로 구성 요소를 해결하는 방법은 무엇입니까?

  22. 22

    선택한 첫 번째 구성 요소가 두 번째 구성 요소의 내용이 동기화되지 않은 것으로 판단하는 UIPickerView

  23. 23

    동적으로 생성 된 두 개의 Ajax 요소가 서로를 인식하지 못함

  24. 24

    두 개의 숫자 구성 요소가있는 UIPickerVIew로 올바른 작업

  25. 25

    하나의 요소 (Python, Selenium)에 대해 두 가지 조건으로 WebDriverWait를 사용하는 방법

  26. 26

    공백으로 구분 된 문자열의 모든 요소에 접두사 / 접미사 추가

  27. 27

    조인으로 두 값 사이의 시간 가져 오기

  28. 28

    XQuery / XPath-속성의 두 요소 집합을 공통 값으로 결합

  29. 29

    Angular2-동일한 구성 요소가 두 번 참조 됨

뜨겁다태그

보관