3

都市の近くのすべての場所について、Web ページに距離マトリックスを表示する必要があります。

このすべてのデータを Web サービスから取得し、事前に DB に保存したいと思います。そのようなデータを保存するための最適なリレーショナル DB 設計を見つけようとしています。

冗長なデータを避け、最適なパフォーマンスを実現する設計を行いたい。

リレーションDBがこれに最適なオプションではないことはわかっていますが、現時点ではそれを助けることはできません.

質問: では、そのような情報を格納するのに最適な DB スキーマ設計は何ですか? 1 つの都市のみを提供する DB にクエリを実行する必要があり、5 つまたは 10 の最も近い都市のマトリックスを表示する必要があります。

移動時間はそれほど重要ではなく、主に距離が気になります。

この種の行列から期間を引いたもの

4

2 に答える 2

3

パフォーマンスのために、また InnoDB を使用していると仮定すると、おそらく次のようにデータを少し非正規化します。

CREATE TABLE CITY (
    CITY_ID INT PRIMARY KEY
);

CREATE TABLE CITY_DISTANCE (
    CITY1_ID INT,
    CITY2_ID INT,
    DISTANCE NUMERIC NOT NULL,
    PRIMARY KEY (CITY1_ID, DISTANCE, CITY2_ID),
    FOREIGN KEY (CITY1_ID) REFERENCES CITY (CITY_ID),
    FOREIGN KEY (CITY2_ID) REFERENCES CITY (CITY_ID)
);

都市の各ペアには、CITY_DISTANCE に同じ DISTANCE を含む 2 つの行があります (方向ごとに 1 つ)。これは明らかに非常に大きくなり、データの不一致につながる可能性があります (データベースは、同じ都市間で一致しない DISTANCE 値からそれ自体を防御しません)。また、DISTANCE は論理的に PK に属していませんが、我慢してください...

InnoDB テーブルはクラスター化されています。つまり、この特定の方法で PK を宣言することにより、テーブル全体を B ツリーに配置します。これは、次のようなクエリに特に適しています。

SELECT CITY2_ID, DISTANCE
FROM CITY_DISTANCE
WHERE CITY1_ID = 1
ORDER BY DISTANCE
LIMIT 5

このクエリは、 で識別される都市に最も近い 5 つの都市を返します。これは、1上記の B ツリーの単純な範囲スキャンで満たすことができます。

id  select_type table           type    possible_keys   key     key_len ref     rows    Extra
1   SIMPLE      CITY_DISTANCE   ref     PRIMARY         PRIMARY 4       const   6       "Using where; Using index"

ところで、クラスター化されたテーブルのセカンダリ インデックスは PK をカバーする必要があるため、InnoDB は 2 番目の FK のために (CITY2_ID に) もう 1 つのインデックスを自動的に作成します。これには CITY1_ID と DISTANCE も含まれます。これを利用して DISTANCE の重複を回避できるかもしれません (明示的に {CITY2_ID, DISTANCE, CITY1_ID} にインデックスを作成し、FK にそれを再利用させ、CHECK (CITY1_ID < CITY2_ID))、しかし MySQL クエリ オプティマイザーはおそらく処理するほど賢くありません。そのような構造で必要となるクエリ。

于 2012-09-11T12:05:06.223 に答える
0

最も簡単な方法は、表示できるようにしたい距離やその他のデータと共に都市のペアを保存することです。都市自体を別のテーブルに保存し、2 つのキーと距離情報のみを距離テーブルに保存します。

最も近い 5 つまたは 10 件のみを表示したい場合は、それらのレコードのみを追加することから始めることができます。つまり、N 都市の場合、データベースには N*10 レコードしか取得できず、非常にスケーラブルなはずです。

レコード数が多い場合でも、適切なインデックスを追加すると、パフォーマンスが向上するはずです。

于 2012-09-11T05:43:57.910 に答える