元の目標:特定の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では、これは今まで常に真実でした。)
PostgreSQLインデックスは、 インデックスへの拡張機能のインターフェース のドキュメントにある2つの部分で構成されています。
\dA+
で確認できます。)GistはIndex Methodです。 GistまたはSP-GistがEXCLUSION CONSTRAINTS
で必要な理由については、この投稿を参照してください。 必要な演算子クラスはinet_ops
です。発生している問題はcidr
とinet
です2つのGist演算子クラスが提供されており、間違ったものはデフォルトです、
Gist_cidr_ops
がデフォルトです。これは「追加提供モジュール」の一部であり、ほとんどのディストリビューションは-contrib
としてパッケージ化しています。 btree_Gist
extension ( source )によって提供されます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を文書化する必要があります。