2011-08-12 7 views
0

私がしたいのは、特定のmysqlエントリを選択してテーブルの一番上に移動するPHPスクリプトを実行することです(または挿入するときと同じようにidカラムを自動的にインクリメントします)。select、delete、insertではなくidを更新しますか?

説明:100エントリのテーブルがあります。エントリn。エントリ49は削除され、すべてのデータはまだテーブルに/挿入されているが、IDは101である。

エントリ88と同じ:idカラムを持つ行値88のデータが削除/更新されると、新しいエントリ/同じエントリが更新され、IDは102ですが同じデータが表示されます。

また、スクリプトが実行された後に、mysqlに優しい解決策を求める重複IDのような問題は発生しません。

ご理解いただけましたか?

私の質問は、どのようにすれば最も効果的で簡単な方法ですか?

私は心の中で持っている唯一のオプションは本当に長いですし、不必要に複雑なようだ:、行全体を選択し、それを削除し、すべてのデータを新しい行を挿入し、IDの自動インクリメント自体を聞かせて...

今誰かがこの問題について私の考えを分かち合う気があれば、私は最も感謝しています!

その他の情報:スクリプトは1日に1回、強力なapache専用サーバーが実行されます。最適化は必要ありません。単純な解決策を求める質問は、実際には非常に難しい作業をすることなく、問題を処理する簡単な方法を求めています。


ありがとうございました!私はあなたの答えとコメントのすべての最後の部分をありがとう!私は、この問題を上記のよりも簡単には解決できないと思うので、PHPを使用して、この問題を今閉じています。もう一度答えました皆様に感謝します。 PHPを使うよりも、問題の解決策について考えているなら、ここで答えてください。私はそれを読むでしょう。もしかしたら、2012年にはまだこのスレッドを読んでいない人を助けるでしょう。世界の終わり...その場合、誰もこのスレッドをもう読んでくれないかもしれません。でも、私は未来が私たちの決断だと思っています。 !乾杯!

+10

このようにIDを使用しないでください。別の列を作成し、その列を放棄して喜ばせる。 – Marvo

+3

更新ID ?? **決して** IDを変更することはありません! – TMS

+4

@Marvo。もっと同意できませんでした。 IDは参照や外部キーなどのためのものです。並べ替えのために変更したり、リサイクルしたりしないでください。 – GolezTrol

答えて

1

私はA Point In Time database designを説明する記事に出くわしました。この記事では、triggersを使用してデザインを実装する方法について説明します。このソリューションを使用して、削除する代わりにIDを更新するトリガーを作成できます。

前述したように、あなたのID-sを混乱させるのは本当に危険で、遅かれ早かれあなたのデータを破損させるでしょう。

1

あなたがそれを必要となぜ私は本当に知りませんが、これは私が考える最高のクエリのようになります。あなたはDBがめちゃくちゃを取得しないことを確認したい場合は

UPDATE %table% SET id = (SELECT Auto_increment FROM information_schema.tables WHERE table_schema = DATABASE() && table_name = '%table%') WHERE id = %id%

使用トランザクション(InnoDBの)またはLOCK(MyISAMテーブル)

のInnoDB

START TRANSACTION; 
UPDATE %table% SET id = (SELECT Auto_increment FROM information_schema.tables 

TABLE_SCHEMA = DATABASE()& & table_name = '%table%')WHERE id =%id%; COMMIT; TABLE_SCHEMA = DATABASE()

のMyISAM

LOCK TABLES %table% WRITE; 
UPDATE %table% SET id = (SELECT Auto_increment FROM information_schema.tables 

& & TABLE_NAME = '%テーブル%')WHERE ID =%識別%; UNLOCK TABLES;

+0

あなたが投稿した最後のスニペットを並べ替えることを望む理由があります。新しい行を挿入するのと同じように動作します。つまり、mysqlの内部 'インクリメンタ'は最後に使用されたIDが101以前のように?また、テーブルがロックされているときに何が起こるか簡単に教えてください。そこに書かれたり読まれたりできないのですか?あなたの答えをありがとうと、次のコメントのために私はすべてこれを説明するために事前に感謝します。乾杯! –

+0

こんにちは、これは完全な解決策です。これは本当にシンプルです - トランザクション/ロックのクエリが実行されている間、テーブルを更新するトランザクション/ロック防止の他のスレッド。これは、テーブルの破損の可能性がないことを意味します。あなたが行っている間誰もテーブルに書き込むことができないからです。はい、それは簡単です。そして今、それはどのように動作するのですか?単純な更新ステートメント 'UPDATE ***** SET id = xx WHERE id = yy'、ここでxxはmysqlからテーブル*****の実際の(次の)自動インクリメント値を取得するselectクエリです内部テーブル(このクエリのようなものは各挿入物で内部的に行われます) – grongor

+0

ユーザはロック時にテーブル内のデータを読み取ることができますか? (これは純粋に好奇心で、クエリは誰にも気を遣うのに必要以上に少なくて済むからです)。また、クエリを使用することによって、mysqlは自動インクリメントされたIDの新しい値に注意します。あなたの答えをありがとう、私はこれがかなり良い解決することを願っています!乾杯! –

2

UPDATEタイプのクエリが適切すぎることは知っていますか?

警告!純粋な悪!

UPDATE `table` 
SET `field1`='value1', `field2` = 'value2', `id`=LAST_INSERTED_ID()+1 
WHERE `id` = 49; 

なぜ純粋な悪の警告ですか?それが台無しにあなたのテーブルにバインドされているとして、あなたはNEVER EVER EVEREVER変更は、既存のエントリのID必要があります。最後のコードは純粋な理論であり、使用することはお勧めしません。

Manual Reference

+0

ああ、もちろん!私の質問を読んで始めましたか? –

+1

もちろん私は持っています。あなたの質問は100%明確ではありません。あなたの問題を精緻化し、明確にしてください。 –

+0

大丈夫です:私は55のIDが55のデータベースに挿入されたレコードを持っています。今はそれをレコード101にしたいのですが、データを再挿入しない(重複データなし)ようにしてください。このレコードは挿入する新しいレコードで、mysqlはidフィールド自体を自動的にインクリメントします。これはもっと明確ですか?とにかく、あなたの答えをお寄せいただきありがとうございます。 :) –

関連する問題