0

これが私が理解しようとしているものです。次のデータベーステーブルがあります

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `Field0` int(11) NOT NULL,
  `Field1` int(11) NOT NULL,
  `Field2` enum('a','b','c') COLLATE latin2_czech_cs NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_czech_cs;

INSERT INTO `test` (`Field0`, `Field1`, `Field2`) VALUES
(10,    11, 'a'),
(10,    13, 'b'),
(10,    13, 'a');

インデックス、一意のキーがないことに注意してください... . 誰かが私に「それは良い考えではない」と言う前に、私は正当な理由でこの例をつなぎ合わせました。

ここで、Adminer (phpMyAdmin などを簡単に読み取ることができます) を使用して行 2 を編集するとします。

(10,13,b)

編集後、発行されたSQLが

UPDATE `test` SET Field2 = 'c' WHERE Field0 = '10' AND Field1 = '13';

MySQL は2 つの行を更新し、テーブルは読み取ります

(10,11,a)
(10,13,c)
(10,13,c)

これは望ましい結果ではなく、管理者が行うことでもありません。どの行を更新するかを知っているようで、まさにそれを行います。これがどのように行われるかは私には明らかではありません。他の多くのステートメントでは、たとえばCREATE TABLE、意図的に無効な割り当てを使用することができます (たとえば、フィールドに長さを割り当ててから、エラーで SQL を調べようとTEXTします。ただし、管理者がアクティブに停止するため、そのオプションは行編集には存在しません)。無効な編集 (整数列に char を入力するなど)。

私が考えることができる唯一の方法LIMIT 1は、ステートメントの最後に a をタグ付けすることです-これはうまくいくでしょう。ただし、多数のフィールドを持つテーブルでは、MySQL が変更する正しい行を識別できるようにするために、その行の 1 つまたは 2 つのフィールドのみが変更された場合に、非常に長い WHERE 句を挿入する必要があります。

おそらく、私が気づいていないほど粗雑ではない、これを達成するための他の手法があるのでしょうか? 助けてくれる人には誰にでも感謝します。

この投稿を終了するには、行 一意である必要があり、インデックスを使用する必要があるとは言わないでください。私はそれをよく知っています。これは、私が解決しようとしている最悪のシナリオです。


この質問は MySQL について述べていますが、実際には MariaDB 10 を使用しています。

4

1 に答える 1

0

行を更新するように要求しましたが、使用できる一意の識別子がありません。したがって、ソフトウェアは、データベースを更新するために必要な定数データを取得しました。そのデータ、およびの値はField0一意Field1ではなかったため、一致したすべての行が変更されました。( Field0, Field1) が一意のキーであった場合、または (一意の) 主キーがあった場合は、単一の行のみが変更された可能性があります。

( Field0, Field1) が一意ではなく、 を追加した場合でも、一致した別のLIMIT 1行を変更するオプションがあった可能性があります。

すべての個別の行を参照する独自の方法がなければ (そしてそれは NULL のない主キーを使用することになります)、Codd の 12 のルール、特にルール #2 を効果的に破ることになります。「完璧な」リレーショナル データベースはほとんどが理論的なものであり、日常的な使用には実用的ではないため、DB は厳密なコンプライアンスがなくても問題なく存在できますが、この場合に一意のキーがないと、自分自身の生活が困難になります。

于 2015-06-05T10:18:39.847 に答える