5

次のようなテーブルの 2 つのフィールドに一意のインデックスを効率的に作成するにはどうすればよいですか? create table t (a integer, b integer);

ここで、2 つの異なる数値の一意の組み合わせは、表の同じ行に複数回出現することはできません。

つまり、a=1 かつ b=2 であるような行が存在する場合、a=2 で b=1、または a=1 で b=2 である別の行は存在できません。言い換えれば、2 つの数字はどのような順序でも 2 回以上一緒に現れることはありません。

そのような制約が何と呼ばれているのかわからないため、タイトルに「両面一意インデックス」という名前が付けられています。

更新:列 (a、b) に複合キーがあり、行 (1,2) がデータベースに存在する場合、別の行 (2,1) をエラーなしで挿入できます。私が探しているのは、同じ数字のペアが任意の順序で複数回使用されるのを防ぐ方法です...

4

4 に答える 4

6

常に最小の数値を最初の列に格納し、最大の数値を 2 番目の列に格納するように、テーブルに入れるものを制御するのはどうですか? もちろん、それが同じことを「意味する」限り。データベースに到達する前に行う方がおそらく安価です。

これが不可能な場合は、フィールドをそのまま保存することもできますが、それらを番号順に 2 つの OTHER フィールドに複製し、そこで主キーを作成します (疑似コードっぽい):

COLUMN A : 2
COLUMN B : 1

COLUMN A_PK : 1  ( if new.a < new.b then new.a else new.b )
COLUMN B_PK : 2  ( if new.b > new.a then new.b else new.a )

これは、(Ronald の応答のように) トリガーを使用して簡単に実行したり、アプリケーションで上位で処理したりできます。

于 2008-10-23T13:56:26.527 に答える
3

これは、FOR INSERT トリガーを使用してのみ実行できると思います (2 つの列に対する一意の制約と組み合わせて)。私はMySql構文にあまり精通していません(私のT-SQLの方が優れています)ので、以下にはいくつかのエラーが含まれていると思います:

編集: MySQL で機能するように構文をクリーンアップしました。BEFORE UPDATEまた、おそらくこれもトリガーとして配置する必要があることに注意してください(もちろん別の名前で)。

また、このメソッドは、2 つのフィールドに主キーまたは一意のキーがあることに依存しています (つまり、このトリガーは、リバースがまだ存在しないことを確認するだけです)。トリガーからエラーをスローする方法はないようです。だから私はこれが得られるのと同じくらい良いとあえて言います.

CREATE TRIGGER tr_CheckDuplicates_insert
BEFORE INSERT ON t
FOR EACH ROW
BEGIN
    DECLARE rowCount INT;
    SELECT COUNT(*) INTO rowCount
                   FROM t
                   WHERE a = NEW.b AND b = NEW.a;

    IF rowCount > 0 THEN
        -- Oops, we need a temporary variable here. Oh well.
        -- Switch the values so that the key will cause the insert to fail.
        SET rowCount = NEW.a, NEW.a = NEW.b, NEW.b = rowCount;
    END IF;
END;
于 2008-10-23T12:21:44.923 に答える
2

Oracle では、次のような関数ベースのインデックスを使用できます。

create unique index mytab_idx on mytab (least(a,b), greatest(a,b));

私はmySQLを知りませんが、おそらく同様のことが可能ですか? たとえば、leastab と maximumab の 2 つの新しい列をテーブルに追加し、トリガーを使用してそれぞれ least(a,b) と maximum(a,b) の値を保持し、(leastab に一意のインデックスを作成します。 、最大タブ)。

于 2008-10-23T12:23:00.613 に答える
1

主キーではなく 2 つの外部キーを参照してください

于 2008-10-23T11:53:20.643 に答える