1

私が持っている日付スタンプに基づいて、アプリケーションがどのDBシャードに移動する必要があるかを調べるために、ある種のテーブルを使用するPHP関数を書いています。

シャード構成は次のようなものです (疑似コード): 最初の列は探しているイベントの日付で、2 番目の列はイベントが存在するシャードです。

pre-2008 -> shard1
2008-2009 -> shard2
2009_01-2009_06 -> shard3
2009_07 -> shard4
2009_08 -> shard5
2009_09 and up -> shard6

ご覧のとおり、私が望む構成は非常に柔軟です。任意の日付範囲を取り、大小を問わず、シャードにマップできます。

特定の日付に基づいてルックアップを行う最も簡単な方法を探しています。

たとえば、日付が 2009-05-02 の場合、対象のシャードは shard3 です。日付が 2007-08-01 の場合、それは shard1 です。

アプリケーションは PHP であるため、実際の PHP コードのボーナス ポイント。

ありがとうございました。

4

3 に答える 3

2

日付範囲に穴が開きたくないので、各シャードの終了日を指定し、 新しいものをすべて保持するデフォルト シャードを1 つ明示的に指定することをお勧めします。他の破片。

// configure shards
$SHARDS = array(
        // <end date>   => <shard number>
        '2007-12-31'    => 'shard1', // shard1 - up to end of 2007
        '2008-12-31'    => 'shard2', // shard2 - up to end of 2008
        '2009-06-30'    => 'shard3', // shard3 - up to end of June 09
        '2009-07-31'    => 'shard4', // shard4 - up to end of July 2009
        '2009-08-31'    => 'shard5', // shard4 - up to end of August 2009
        'DEFAULT'       => 'shard6', // everything else in shard 6
        );

これにより、日付を正しく取得することが容易になり、日付に基づいてシャードを見つけるためのコードは単純になります。

function findShardByDate($date) {
    static $default = false;
    static $sorted = false;
    if($sorted === false) {
        // copy of global $SHARDS
        $SHARDS = $GLOBALS['SHARDS'];
        $default = $SHARDS['DEFAULT'];
        unset($SHARDS['DEFAULT']);
        // make sure $SHARDS is sorted
        ksort($SHARDS);
        $sorted = $SHARDS;
        unset($SHARDS);
    }
    // find the first shard which would contain that date
    foreach($sorted as $endDate => $shardName)
        if($endDate >= $date)
            return $shardName;
    // no shard found - use the default shard
    return $default;
}

編集:並べ替えが一度だけ行われるように静的変数を使用しました。

于 2009-08-18T00:11:49.860 に答える
2
<?php

function get_shard($datetime)
{
    $timestamp = strtotime($datetime);

    $shards = array(array('start' => null, 'end' => '2007-12-31'),
                    array('start' => '2008-01-01', 'end' => '2008-12-31'),
                    array('start' => '2009-01-01', 'end' => '2009-06-30'),
                    array('start' => '2009-07-01', 'end' => '2009-07-31'),
                    array('start' => '2009-08-01', 'end' => '2009-08-31'),
                    array('start' => '2009-09-01', 'end' => null),
                    );
    foreach ($shards as $key => $range) {
        $start = strtotime($range['start']);
        $end = strtotime($range['end']);
        if ($timestamp >= $start && $timestamp <= $end) {
            return $key + 1;
        }
        if ($timestamp >= $start && $end === false) {
            return $key + 1;
        }
    }
}


$datetime = '2007-08-01';
echo 'shard' . get_shard($datetime) . "\n";

$datetime = '2009-05-02';
echo 'shard' . get_shard($datetime) . "\n";

$datetime = '2010-01-01';
echo 'shard' . get_shard($datetime) . "\n";

?>

出力:

shard1
shard3
shard6
于 2009-08-17T23:55:47.287 に答える
0

シャードは厳密に順序付けできるため、シャードをバイナリ ツリーに格納し、そのツリーでバイナリ検索を実行するだけで最速の結果が得られるようです。

于 2009-08-17T23:37:01.740 に答える