5

クライアントが自分で使用するデータベース管理ツールを構築していますが、主キー/一意キーの更新の可能性に対処するのに問題があります。したがって、更新用のデータが行ごとに PHP スクリプトによって渡されることを考えると、ここに私が思いついたものがあります (「すぐに」から「しばらくしてから」まで):

  1. UPDATEの代わりにDELETE / INSERT(ひどい、私は今...):

    DELETE FROM table WHERE unique_key=x;
    DELETE FROM table WHERE unique_key=y;
    INSERT INTO table VALUES (unique_key=y, field=record1), (unique_key=x, field=record2);
    
  2. プライマリ/一意のキーを変更してから、変更した値に置き換えます。

    UPDATE table SET unique_key=x* WHERE unique_key=x;
    UPDATE table SET unique_key=y* WHERE unique_key=y;
    UPDATE table SET unique_key=y WHERE unique_key=x*;
    UPDATE table SET unique_key=x WHERE unique_key=y*;
    
  3. 変更不可能な auto_increment フィールド「id」をすべてのテーブルに追加します。これは代理主キーとして機能します

今と同じように、すべてに「id」フィールドを追加しようとしています。その他のオプション?

4

2 に答える 2

1

主キーの更新は問題ではありません。SQL (およびリレーショナル モデル) のすべての値は更新可能であると想定されています。

問題は主キーの交換にあるようです。

  • 代理キーを使用している場合は意味がありません (意味がないため、更新は必要ないため)。
  • 自然キーを使用する場合、私には意味がありません。これは、私のStackOverflow ユーザー ID をあなたのものと交換するようなものだからです。

すべてのテーブルに「ID」列を追加しても役に立ちません。「unique_key」列は引き続き一意であると宣言する必要があります。「ID」列を追加しても、そのビジネス要件は変わりません。

MySQL が遅延制約をサポートしている場合、主キーの値を交換できます。(遅延制約は標準 SQL の機能です。) しかし、MySQL はその機能をサポートしていません。たとえば、PostgreSQL では、これを行うことができます。

create table test (
  unique_key char(1) primary key deferrable initially immediate,
  other_column varchar(15) not null
);

insert into test values 
('x', 'record2'),
('y', 'record1');

begin;
set constraints test_pkey deferred;
update test set unique_key = 'y' where other_column = 'record2';
update test set unique_key = 'x' where other_column = 'record1';
commit;

select * from test;

unique_key  other_column
--
y           record2
x           record1
于 2013-05-08T22:53:50.740 に答える
0

この種の更新を行うには、CASE 式を使用できるはずです。例えば:

UPDATE tbl SET col =
    CASE    WHEN col = 1 THEN 2
            WHEN col = 2 THEN 1
    END
WHERE col IN (1,2);

(未テストのコード)

于 2013-05-09T19:47:51.797 に答える