>  기사  >  데이터 베이스  >  Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

PHPz
PHPz앞으로
2023-06-02 18:53:231151검색

1. Background

인덱싱을 하면 첫인상은 데이터베이스라는 단어인데 Gaussian Redis도 2차 인덱싱을 구현할 수 있어요! ! ! Gaussian Redis의 보조 인덱스는 일반적으로 zset을 사용하여 구현됩니다. Gaussian Redis는 오픈 소스 Redis보다 더 높은 안정성과 비용 이점을 제공합니다. Gaussian Redis zset을 사용하여 비즈니스 보조 인덱스를 구현하면 성능과 비용 측면에서 윈윈(win-win) 상황을 달성할 수 있습니다.

인덱싱의 핵심은 순서화된 구조를 사용하여 쿼리 속도를 높이는 것이므로 Zset 구조 Gaussian Redis를 통해 숫자 및 문자 유형 인덱스를 쉽게 구현할 수 있습니다.

• 숫자 유형 색인(zset은 점수별로 정렬됨):

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

• 문자 유형 색인(점수가 동일한 경우 zset는 사전순으로 정렬됨):

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

두 가지 유형의 고전적인 비즈니스 시나리오를 살펴보고 Gaussian Redis를 사용하여 안정적이고 신뢰할 수 있는 보조 인덱스 시스템을 구축하는 방법을 살펴보겠습니다.

2. 시나리오 1: 사전 완성

브라우저에 쿼리를 입력하면 브라우저는 일반적으로 가능성을 기준으로 동일한 접두어를 사용하여 검색을 추천합니다. 이 시나리오는 Gaussian Redis 보조 인덱스 기능을 사용하여 실현할 수 있습니다.

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

2.1 기본 솔루션

가장 간단한 방법은 사용자의 모든 쿼리를 인덱스에 추가하는 것입니다. 사용자에게 완료 프롬프트를 제공해야 하는 경우 ZRANGEBYLEX를 사용하여 범위 쿼리를 수행할 수 있습니다. 결과 수를 줄이기 위해 LIMIT 옵션을 사용하는 것이 Gaussian Redis에서 지원하는 방법입니다.

• 색인에 사용자 검색 바나나 추가:

ZADD myindex 0 banana:1

• 사용자가 검색 양식에 "bit"를 입력하고 "bit"로 시작할 수 있는 검색 키워드를 제공한다고 가정합니다.

ZRANGEBYLEX myindex "[bit" "[bit\xff"

즉, ZRANGEBYLEX를 사용하여 범위 쿼리를 수행합니다. 쿼리 범위는 사용자가 지금 입력한 문자열과 동일한 문자열에 후행 바이트 255(xff)를 더한 것입니다. 이 방법을 사용하여 사용자가 입력한 문자열이 앞에 붙은 모든 문자열을 가져올 수 있습니다.

2.2 빈도 관련 사전 완성

실제 응용에서 사람들은 일반적으로 발생 빈도에 맞게 완성 용어를 자동으로 정렬하고, 향후 입력에 적응하면서 더 이상 인기가 없는 용어를 제거하기를 원합니다. 이 목표를 달성하기 위해 Gaussian Redis의 ZSet 구조를 계속 사용할 수 있지만 인덱스 구조에서는 검색어뿐만 아니라 검색어와 관련된 빈도도 저장해야 합니다.

• 사용자 검색 바나나를 인덱스에 추가

• 바나나가 존재하지 않는다고 가정하고 바나나를 추가합니다. 여기서 1은 빈도입니다.

ZRANGEBYLEX myindex "[banana:" + LIMIT 0 1

• 빈도를 높이려면

ZRANGEBYLEX myindex "[banana:" + LIMIT 0 1에서 반환된 빈도가 1인 경우

1) 이전 항목 삭제:

ZADD myindex 0 banana:1

2) 빈도를 1씩 추가하고 다시 참여하세요:

ZREM myindex 0 banana:1

제발 동시 업데이트 가능성으로 인해 위의 세 가지 명령은 Lua 스크립트를 통해 전송되어야 합니다. Lua 스크립트는 자동으로 이전 카운트를 얻고 점수를 올린 후 항목을 다시 추가합니다.

사용자가 검색창에 "바나나"를 입력하면 관련 검색어가 제공되기를 바랍니다. ZRANGEBYLEX를 통해 결과를 얻은 후 빈도별로 정렬합니다.

ZADD myindex 0 banana:2

• 스트리밍 알고리즘을 사용하여 자주 사용되지 않는 입력을 정리합니다. 반환된 항목을 무작위로 선택하고 점수에서 하나를 뺀 다음 업데이트된 점수로 다시 추가합니다. 그러나 새 점수가 0이면 목록에서 해당 항목을 제거해야 합니다.

• banaooo:1

ZRANGEBYLEX myindex "[banana:" + LIMIT 0 10
1) "banana:123"
2) "banaooo:1"
3) "banned user:49"
4) "banning:89"

•과 같이 무작위로 선택된 항목의 빈도가 1인 경우 바나나:123

ZREM myindex 0 banaooo:1

과 같이 무작위로 선택된 항목의 빈도가 1보다 큰 경우 색인에는 인기 검색어가 포함되며, 시간이 지남에 따라 인기 검색어가 변경되면 자동으로 조정됩니다.

3. 시나리오 2: 다차원 인덱스

Gaussian Redis는 단일 차원의 쿼리를 지원할 뿐만 아니라 다차원 데이터에서도 검색할 수 있습니다. 예를 들어, 나이가 50~55세이고 급여가 70,000~85,000이라는 기준을 충족하는 사람을 검색합니다. 2차원 데이터 인코딩을 1차원 데이터로 변환한 후 Gaussian 분산 Redis zset 스토리지를 사용하는 것은 다차원 보조 인덱스를 구현하는 중요한 방법입니다.

시각적 관점에서 2차원 인덱스를 표현합니다. 이 공간에는 좌표(x, y)로 표현된 일부 데이터 샘플 포인트가 있으며, 이 좌표에서 x, y 변수의 최대값은 400입니다. 이미지의 파란색 상자는 쿼리를 나타냅니다. 우리는 x 좌표가 50에서 100 사이이고 y 좌표가 100에서 300 사이인 모든 점을 찾고 싶습니다.

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법3.1 데이터 인코딩

삽입된 데이터 포인트가 x = 75이고 y = 200인 경우

1) 0을 입력합니다(최대 데이터는 400이므로 3자리를 입력합니다)

x = 075

y = 200

2)交织数字,以x表示最左边的数字,以y表示最左边的数字,依此类推,以便创建一个编码

027050

若使用00和99替换最后两位,即027000 to 027099,map回x和y,即:

x = 70-79

y = 200-209

因此,针对x=70-79和y = 200-209的二维查询,可以通过编码map成027000 to 027099的一维查询,这可以通过高斯Redis的Zset结构轻松实现。

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

同理,我们可以针对后四/六/etc位数字进行相同操作,从而获得更大范围。

3)使用二进制

如果将数据表示为二进制,就可以获得更细的粒度,而在数字替换时,每次都将搜索范围扩大两倍。如果我们使用二进制表示法数字,每个变量最多需要9位(表示最多400个值),那么我们将得到:

x = 75 -> 001001011

y = 200 -> 011001000

交织后,000111000011001010

让我们看看在交错表示中用0s ad 1s替换最后的2、4、6、8,...位时我们的范围是什么:

Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법

3.2 添加新元素

若插入数据点为x = 75和y = 200

x = 75和y = 200二进制交织编码后为000111000011001010,

ZADD myindex 0 000111000011001010

3.3 查询

查询:x介于50和100之间,y介于100和300之间的所有点

从索引中替换N位会给我们边长为2^(N/2)的搜索框。因此,我们要做的是检查搜索框较小的尺寸,并检查与该数字最接近的2的幂,并不断切分剩余空间,随后用ZRANGEBYLEX进行搜索。

下面是示例代码:

def spacequery(x0,y0,x1,y1,exp)
    bits=exp*2
    x_start = x0/(2**exp)
    x_end = x1/(2**exp)
    y_start = y0/(2**exp)
    y_end = y1/(2**exp)
    (x_start..x_end).each{|x|
        (y_start..y_end).each{|y|
            x_range_start = x*(2**exp)
            x_range_end = x_range_start | ((2**exp)-1)
            y_range_start = y*(2**exp)
            y_range_end = y_range_start | ((2**exp)-1)
            puts "#{x},#{y} x from #{x_range_start} to #{x_range_end}, y from #{y_range_start} to #{y_range_end}"
            # Turn it into interleaved form for ZRANGEBYLEX query.
            # We assume we need 9 bits for each integer, so the final
            # interleaved representation will be 18 bits.
            xbin = x_range_start.to_s(2).rjust(9,'0')
            ybin = y_range_start.to_s(2).rjust(9,'0')
            s = xbin.split("").zip(ybin.split("")).flatten.compact.join("")
            # Now that we have the start of the range, calculate the end
            # by replacing the specified number of bits from 0 to 1.
            e = s[0..-(bits+1)]+("1"*bits)
            puts "ZRANGEBYLEX myindex [#{s} [#{e}"
        }
    }
end
spacequery(50,100,100,300,6)

위 내용은 Gaussian Redis를 사용하여 보조 인덱스를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제