web-dev-qa-db-ja.com

距離の計算とデータの正規化

私は郵便番号間の基本的な距離を報告する必要があるシステムを設計しています。 Google Distance Matrix APIを使用しますが、同じデータポイントに対する複数のリクエストによってAPI呼び出しが重複しないように、結果をデータベースにキャッシュします。

基本的なDistanceクラスは次のようになります。

YUML Distance thingy

キャッシュの基本的なデータ構造は次のようになります。

YUML DB table

一方通行や分割された高速道路、インターチェンジなどによる変更に関する詳細な詳細は使用していないため、A地点からB地点まで、またはB地点までのデータを取得するかどうかは関係ありません。ポイントBからポイントAへ。ただし、これをデータベースで完全に正規化して表現する方法はわかりません。この主キーを使用すると、同じ距離が2つの別々の行に存在することは完全に合法です。

var row1 = new Distance("00001", "00002");
var row2 = new Distance("00002", "00001");

コンストラクターでSortedListパラメーターを要求することはおそらく良い考えですが、完全な正規化を実施するためにデータベース側から設計できる方法はありますか?

6
lorddev

Google+のTonyから、非常に役立つ回答がありました。重要なのは、正規化の概念を完全に捨てることではなく、主キーとして2つの列(Zip1 + Zip2)の概念を単純に乗り越えることです。これは、何らかの理由で、私が始めた概念でした。代わりに、2つの場所がどのような順序で来るかを気にせずに、2つの場所を関連付けるリレーショナルテーブルを使用します。

YUML solution

リレーショナルテーブルは、2つのzipを1つのRouteIdにマップし、Routesテーブルには距離データとキャッシュされた日付が含まれます。

1
lorddev

場所が郵便番号で表されている場合(ほとんどの距離推定値が同じ郵便番号の許容範囲内にある場合は問題ありません)、フィールドZip1およびZip2に チェック制約 を課します。 Zip1 = <Zip2。

もちろん、これはミドルウェアロジックに対応する負担を課し、1つのレコードのみを保証する規則が小さい郵便番号をZip1に配置することを理解します。クエリは最初のフィールド、つまりWHERE(Zip1 = myZip1およびZip2 = myZip2)OR(Zip1 = myZip2およびZip2 = myZip1))に依存しない可能性があるため、これは主に行の挿入に関する懸念事項です。 。

ただし、両方の注文を複合キーに格納しても、正規化に違反することはありません。レコード数の2倍未満のものを使用しますが、これらはかなり小さい行のように見えるため、効率の観点からロジックの複雑さを正当化できるかどうかはわかりません(速度の点で最も少ない)。

7
hardmath

この郵便番号FAQ によると、米国には約43,000の郵便番号があります。この数値は年間数千変動します。 distance(Zip1, Zip2)によって返される値は、新しい道路の建設、郵便番号の境界の変更などが原因で、時間とともに変化する可能性があります。

戻り値を無期限に保存すると、43,000 ^ 2(約18億)の値になる可能性があります。その場合、逆(Zip2、Zip1)を回避することには意味があります。

キャッシュレコードの有効期限が切れた場合(1日、1週間、1か月など)、逆のことを気にしない方が理にかなっている場合があります。

モバイルデバイスや組み込みデバイス用にコーディングしていない限り、ディスク容量は非常に安価です。

2
Dan Pichelman

正規化から逸脱することを検討してください。通常の形式の1つから逸脱するたびに、克服すべき対応する異常があります。 2NFから5NFの場合、異常は一般に有害な冗長性の領域にあります。

この種の冗長性を有害にするのは、データベースに相互に矛盾する事実が含まれている可能性があるため、結果が不安定になる可能性があることです。これらの矛盾が発生しないようにプログラムする必要があります。

日常的なデータベース作業の場合、通常は正規化する方が適切であり、更新に注意するよりも矛盾を回避できます。

しかし、この一連の推論を論理的な結論に導くとしたら、キャッシュを行うことは決してありません。キャッシュには、キャッシュする基になるデータと重複するデータが常に含まれています。キャッシュを構築するときは常に、キャッシュが無効になっている結果を提供しないように保護する必要があります。有害な冗長性に対処するためのプログラミングには、同じような規律のある考え方が関係しています。

結局のところ、あなたは結局正常化することを決めるかもしれません。ただし、正規化をある種の聖杯として扱わないでください。そうではありません。

別の方法があります。キャッシュにデータポイントを追加するときは常に、Zip1.lt.Zip2になるようにデータを配置します。ルックアップを行うときは常に、2つのzipを同じように配置します。これは少し余分な計算ですが、すべてのポイントを2回追加するよりも優れている場合があります。

0
Walter Mitty