3


0

データベーススキーマでドメインオブジェクトを作成しようとしていて、コード内でドメインオブジェクトがハッシュテーブル/リストメンバーを持っているとしたら、次のようになります。

パブリッククラスSpaceQuadrant:PersistentObject {

公開SpaceQuadrant(){}

公開仮想辞書スペース{get;セット; }}

ディクショナリは単なるハッシュテーブル/リストマッピングで、オブジェクトキーと値キーを組み合わせたものです。これを行うには、さまざまな結合テーブルを作成したり、テクニックをロードしたりする方法がいくつかあります。ハッシュテーブルに入ったアクセス時間。

データベーススキーマでSpaceQuadrant、SpaceCoordinate、およびSpace Objectをどのように表現しますか。 単純なスキーマコードの記述はいいでしょう。

table SpaceQuadrant {ID int null以外の主キー、EntryName varchar(255)null以外、SpaceQuadrantJoinTableId int null以外の外部キー参照...その他... }

しかし、どんな考えでも同様にいいでしょう、読んでくれてありがとう!

詳しくは:

素晴らしい答えをありがとう、すでに、私はそれらをスキムしただけなので、返答する前にそれぞれについて考えてみたいと思います。

あなたがこれらのクラスを定義するより良い方法があると思うなら、ぜひ私に例を見せてください。

4 Answer


2


関係はハッシュテーブルではありません。それらはセットです。

座標をキーとしてデータベースを整理することはしません。 オブジェクトが位置を変えるとどうなりますか? 代わりに、私はおそらく座標をオブジェクトの属性として扱うでしょう。

また、3つなど、固定数の次元があるとします。 もしそうなら、あなたは固定列にオブジェクトのこれらの属性を格納することができます:

CREATE TABLE SpaceQuadrant(quadrant_id INT NOT NULL PRIMARY KEY、quadrant_name VARCHAR(20) - その他の属性)。

CREATE TABLE SpaceObject(object_id INT NOT NULL PRIMARY KEY、x NUMERIC(9,2)NOT NULL、y NUMERIC(9,2)NOT NULL z NUMERIC(9,2)NOT NULL、object_name VARCHAR(20)NOT NULL、 - その他の属性quadrant_id INT NULL以外、外部キー(quadrant_id)関連情報SpaceQuadrant(quadrant_id))。

あなたのオブジェクト指向のクラスでは、なぜあなたのオブジェクトが辞書の中にあるのか明確ではありません。 あなたはO(1)時代にそれらにアクセスすることに言及しました、しかしなぜあなたはコーディネートによってそれをするのですか?

これを使って特定の地点(たとえば、プレイヤーの宇宙船)の近くにあるオブジェクトを見つけるのを最適化するなら、このSpaceQuadrantにその特定の地点からのすべてのオブジェクトの距離の計算を追加するSQLクエリに組み込むこともできます。距離による結果。

これらの提案が適切であるかどうかを知るのに十分なほどあなたのプログラムについて知りません。 しかし、それらは少なくとも、データを整理するさまざまな方法をあなたに考えさせているのでしょうか。


2


最も単純なケースでは、辞書はテーブルの主キーにマッピングされるキーを持っています - そのため、キーの値を指定すると、単純な検索によって即座に一致するデータを見つけることができます。

この場合、スペース四分円を記述または特徴付ける一般的な(単一値の)属性を持つテーブルSpaceQuadrantが必要になります。 SpaceQuadrantテーブルは主キー、おそらく生成されたID、そしておそらく自然な値を持つでしょう。 ハッシュテーブルは、SpaceQuadrantを相互参照するための主キー値と、位置(SpaceCoordinate)、および象限と座標の属性を持つテーブルで構成されます。

拡張可能なDBMSを使用している場合は、SpaceCoordinateにユーザー定義型を定義できます。それができない場合は、位置(SpaceCoordinate)を表すために、3つの列(x、y、z、またはr、theta、rho)を使用できます。

一般的に言って、私が説明している構造はBill Karwinのものと非常に似ています。キー(メッセージを読み直すまでは意図していません)の違いは、整理するのに最適な方法であると確信している場合は、下位のテーブルの主キーの一部として位置を設定することです。それ。 代替候補キーであるオブジェクトID列もあります。 あるいは、オブジェクトがその時点で存在しているスペース象限とは無関係に存在する場合(または複数の位置に存在する可能性があります - それらは点ではなく、宇宙ステーションまたは何かであるため)。別表 何が最善かは、私たちが利用できない情報にかかっています。

主キーの一部としてSpaceCoordinateを使用する場合の制限事項に注意する必要があります。

  • 2つのオブジェクトが同じ位置を占めることはできません(これは、ハッシュテーブルと3D空間の衝突と呼ばれます)。

  • 位置が変わった場合は、キーデータを更新する必要があります。これは、非キーデータを更新するよりもコストがかかります。

  • 近接検索は難しいでしょう - 正確な検索は十分に簡単です。

メモリ内の辞書についても同じことが言えます。座標を変更した場合は、古い場所からレコードを削除して辞書の新しい場所に配置する必要があります(または、言語の裏側でそれを実行する必要があります)。


2


辞書はテーブルです。 ハッシュはどのような種類のインデックスが使用されているかの問題です。 ほとんどのRDBMSは、テーブルは大きくて密集していると仮定しているため、ハッシュインデックスは適切ではありません。

table SpaceQuadrant {ID主キー、 - その他の関連属性に関係なく}

表スペース{SpaceCoordinate主キー、四分円外部キーSpaceQuadrant(ID)、SpaceObject  - オブジェクトは何でも}

あなたのSpaceオブジェクトは、それらが配置されている象限へのFK参照を持っています。

RDBMSによっては、希望するパフォーマンスを得るためのハッシュベースのインデックスを見つけることができるかもしれません。 たとえばMySQLでは、HEAPストレージエンジンを使用してHASHインデックスをサポートしています。


1


まず、地理的に特定されたデータに対する専用のサポートが多くのデータベースに存在します - 異なるアルゴリズムを使用することができ(例えばB-Treeの空間バージョンが存在します)、近接検索のサポートもおそらく存在するでしょう。

SpaceQuadrantごとに異なるハッシュテーブルがあるので、(S.Lottの投稿を編集したもの)のようなものが必要です。

table Space {
    SpaceCoordinate,
    Quadrant Foreign Key SpaceQuadrant(ID),
    SpaceObject -- whatever the object is (by ID)
    Primary Key(SpaceCoordinate, Quadrant)
}

これは `(SpaceCoordinate、Quadrant) - > SpaceObjectId`辞書です。

さて、O(1)のパフォーマンスの懸念については、間違って対処されている理由がたくさんあります。

誰かがあなたに言ったように、あなたは多くのDBでメモリベースのテーブルのためのハッシュインデックスを使うことができます。 しかし、永続的な記憶域が必要な場合は、1つではなく2つの表(メモリ1つと永続1つ)を更新する必要があります(これに対するサポートが組み込まれていない場合)。 それが価値があるかどうかを発見するためには、実際のデータ(実際のデータサイズ)をベンチマークする必要があります。

また、テーブルを強制的にメモリに入れると、さらに悪い影響を与える可能性があります。

何かが入れ替わったら、あなたは死んでいます - B-Treeを使ったことがあるなら(つまり 通常のディスクベースのインデックス)では、そのアルゴリズムによって必要なI / Oが最小限に抑えられます。 そうでなければ、すべてのDBMSはB-Treeの代わりにハッシュテーブルを使い、スワッピングに頼ります。 あなたはメモリに収まるかどうかを予測しようとすることができますが…​

さらに、B-TreeはO(1)ではなくO(log_512(N))、またはそのようなものです(私はO(log N)に崩壊することを知っていますが、これを理解してください)。 それを4にするには(2 ^ 9)^ 4 = 2 ^ 36 = 64ギガバイトが必要です。大量のデータがある場合は、それをメモリに収めるためには大きな鉄のサーバーが必要です。 それで、それはほとんどO(1)であり、そして定数要素は実際に重要なものです。 漸近的複雑性が大きく、定数定数が大きいアルゴリズムについて聞いたことがありますが、これは実際的でないデータサイズでは単純なものよりも速いでしょうか。

最後に、DB作成者は私とあなたよりも賢いと思います。 特にSQLの宣言的な性質を考えると、このように手作業で最適化するのは無駄です。 インデックスがメモリに収まる場合は、必要に応じて、ハッシュテーブルバージョンのディスクインデックスを作成して使用することを選択できます。 そのためにあなたのドキュメントを調べてください。

しかし、肝心なのは、時期尚早な最適化は、特にこの種のもの(標準のSQL最適化とは対照的に、私たちが独自に考えている奇妙な最適化)と宣言型言語による場合には厄介です。