1

これは、多対多の関係の私のテーブルです。

Related:
-id
-id_postA
-id_postB

これ欲しい:

たとえば、 を含む行がある場合、 をid_postA = 32 and id_postB = 67 含む行の挿入を無視する必要がありid_postA = 67 AND id_postB = 32ます。

4

3 に答える 3

1

1 つのオプションは、両方の列に一意のインデックスを作成することです。

CREATE UNIQUE INDEX uk_related ON related (id_postA, id_postB);

そして、トリガー、順序付け、およびonを使用して「順序反転による重複」を防止します。id_postAid_postBINSERTUPDATE

CREATE TRIGGER order_uk_related
BEFORE INSERT     -- Duplicate this trigger also for UPDATE
ON related        -- As MySQL doesn't support INSERT OR UPDATE triggers
FOR EACH ROW
BEGIN
    DECLARE low INT;
    DECLARE high INT;

    SET low = LEAST(NEW.id_postA, NEW.id_postB);
    SET high = GREATEST(NEW.id_postA, NEW.id_postB);

    SET NEW.id_postA = low;
    SET NEW.id_postB = high;
END;

このSQLFiddleでわかるように、トリガーによって(2, 1)既に切り替えられているため、4 番目の挿入は失敗します。(1, 2)

INSERT INTO relation VALUES (1, null, null)
INSERT INTO relation VALUES (2, null, null)
INSERT INTO relation VALUES (3, 2, 1)
INSERT INTO relation VALUES (4, 1, 2)

関数索引

他の一部のデータベースでは、関数ベースのインデックスを使用できる場合があります。残念ながら、これは MySQL では不可能です (MySQLで関数ベースのインデックスを作成することは可能ですか? )。これがオラクルの質問なら、次のように書きます。

CREATE UNIQUE INDEX uk_related ON related (
    LEAST(id_postA, id_postB), 
    GREATEST(id_postA, id_postB)
);
于 2013-05-10T17:01:58.573 に答える
0

次のようなものを含めることができますwhere

例えば

insert into table_name
(id_postA 
,id_postB
select 
col1,
col2
from table_1
where where (cast(col1 as varchar)+'~'+cast(col2 as varchar))
    not in (select cast(id_postB as varchar)+'~'+cast(id_postA as varchar) from table_name)
于 2013-05-10T16:58:56.943 に答える