web-dev-qa-db-ja.com

除外制約に使用する演算子クラスとアクセスメソッドを見つける方法は?

元の目標:特定のPostgresテーブルに重複しないサブネットのみが存在するように制約を作成します。

ドキュメントを注意深く読むことから、私はこれまで得ることができました:

create table subnets (
subnet cidr,
exclude (subnet with &&)
);

しかし、これは機能しません。それは不可解なメッセージを生成します:

ERROR:  operator &&(inet,inet) is not a member of operator family "network_ops"
DETAIL:  The exclusion operator must be related to the index operator class for the constraint.

演算子クラス、インデックス、およびインデックスタイプに関するドキュメントセクションを読み上げましたが、当然のことながら、説明セクション全体が欠けているような気がしました。私はまだIS演算子クラス、実際には演算子ファミリーも何も知りません。

私は メーリングリストに投稿 コードスニペットを見つけました。このコードスニペットは次の作業コードにつながりました。

create table subnets (
subnet cidr,
exclude using Gist (subnet inet_ops with &&)
);

しかし、「Gistを使用する」が何であるのか、「inet_ops」が何であるのか、本当に理解できません。

「Gistの使用」はインデックスのタイプに関連していることを知っています。 「一意の」制約に対してインデックスが自動的に作成されることを知っています。「guess」は、「除外」制約に対してもインデックスが自動的に作成される可能性があることを知っています。 「演算子クラス」に関する唯一のドキュメント すべてはindexes、に関連していますが、制約ではありません。

除外制約が必要なこのクエリまたは今後のクエリで、制約が機能するために指定する必要がある演算子クラスとアクセスメソッドを決定するにはどうすればよいですか?

動作中のコードを手元に置いても、[whyそれは「要旨」であり、他のものではなく、why「ネットワーク_ops」ではなく「inet_ops」であることに注意してください。または何もありません。 \doSと演算子クラスのドキュメントに記載されているクエリは啓発的でした。

私が生成した別のエラーも啓発的ではありませんでした:

vagrant=# create table subnets (
subnet cidr,
exclude using Gist (subnet with &&)
);
ERROR:  data type cidr has no default operator class for access method "Gist"
HINT:  You must specify an operator class for the index or define a default operator class for the data type.

(この質問は、私がすべきではないという前提に基づいています必要呪文をコピーして貼り付ける手段に頼る;ドキュメントを徹底的に検討し、エラーメッセージを注意深く読むすべき解決させてください問題。Postgresでは、これは今まで常に真実でした。)

1
Wildcard

PostgreSQLインデックスは、 インデックスへの拡張機能のインターフェース のドキュメントにある2つの部分で構成されています。

  • インデックスメソッド(アクセスメソッド)、brin、btree、gin、Gist、hash、sp-Gistについて話している場合(psqlの\dA+で確認できます。)
  • 演算子クラス

GistはIndex Methodです。 GistまたはSP-GistがEXCLUSION CONSTRAINTSで必要な理由については、この投稿を参照してください。 必要な演算子クラスinet_opsです。発生している問題はcidrinetです2つのGist演算子クラスが提供されており、間違ったものはデフォルトです

  • 演算子クラスGist_cidr_opsがデフォルトです。これは「追加提供モジュール」の一部であり、ほとんどのディストリビューションは-contribとしてパッケージ化しています。 btree_Gist extensionsource )によって提供されます
  • 演算子クラス inet_ops がコアであり、notがデフォルトです。

どうしてこれを知っていますか?あなたはおそらくそうしないでしょう。アクセスタイプに関しては、頑張ってください。 PostgreSQLと一緒に配布されている間のドキュメント自体はここでは非常に不足していますが、これについては触れていますが、

歴史的な理由により、inet_ops演算子クラスは、タイプinetおよびcidrのデフォルトクラスではありません。これを使用するには、たとえば、CREATE INDEXにクラス名を記述します。

CREATE INDEX ON my_table USING Gist (my_inet_column inet_ops);

あなたができる最善のことは、ドキュメントパッチを btree_Gist に提出することです。この場合、おそらくalsoを文書化する必要があります。

2
Evan Carroll