2

シナリオ:WAMPサーバー、InnoDBテーブル、一意のIDフィールドの自動インクリメント[ INT(10)]、100以上の同時SQLリクエスト。必要に応じて、VB.Netも使用する必要があります。

私のデータベースには自動インクリメントフィールドがあり、保存された新しい情報(サービスオーダー)ごとに一意のチケット/プロトコル番号を生成するために使用されます。

問題は、この番号を毎年リセットする必要があることです。000001/12 つまり、2012年1月1日00:00:00に最大値まで開始し、2013年1月1日999999/1200:00:00に最初からやり直す必要があります000001/13

明らかに、ある種のアルゴリズムを使用して簡単に達成できるはずですが、私はそれを行うためのより効率的な方法を見つけようとしています。検討:

  1. データベースにはある程度の同時実行性(+100)があるため、自動インクリメントを使用する必要があります(?)。

  2. 各チケットは一意である必要があります。したがって、2012年は2013年000001と同じではありません。000001

  3. 自動である必要があります。(リセットなどを行うために人間の操作は必要ありません)

  4. かなり効率的である必要があります。(監視プログラムはデータベースを毎日チェックする必要がありますが(?)、1回だけ成功するために364回失敗するため、最善の解決策ではないようです)。

私が考えることができる「最良の」アプローチは、次のように年を使用してチケット番号を保存することです。

12000001- 12999999(とにかく、999.999に達することはありません)

次に、監視プログラムは自動増分フィールドを2013年1月1日に設定する必要があります13000000

助言がありますか?

PS:読んでくれてありがとう...;)

4

3 に答える 3

1

したがって、今後の参考のために、次のソリューションを採用しました。

私はデータベース上にn個のテーブル(各年に1つ)を作成し、各年の一意のIDを生成する自動インクリメントフィールドを1つだけ作成します。

そのため、イベントの日付を考慮して、対応するテーブルに新しい挿入が行われます。その後、アルゴリズムはlast_inseted_id()を取得し、その値を000001/12の形式でメインテーブルに格納します。(チケット/年)

これは、現在の日付がすでに2013年であっても、2012年のイベントが挿入されるため、毎年独自のカウンターが必要になるためです。

そうすれば、イベントはさかのぼって実行でき、リセットは不要で、実装も簡単です。

挿入用のサンプルコード:

$eventdate="2012-11-30";
$eventyear="2012";
$sql = "INSERT INTO tbl$eventyear VALUES (NULL)";
mysql_query ($sql);
$sql = "LAST_INSERT_ID()";
$row = mysql_fetch_assoc(mysql_query($sql));
$eventID = $row(0)
$sql = "INSERT INTO tblMain VALUES ('$eventID/$eventYear', ... ";
mysql_query($sql)
于 2012-06-26T19:35:33.260 に答える
0

MongoDBは、これに非常によく似たものを使用して、IDを生成した日付、プロセスID、ホストをランダムなエントロピーとともにエンコードしてUUIDを作成します。単調増加の要件を満たすものではありませんが、アプローチに関するいくつかのアイデアを探すのに興味深いものです。

それを実装する場合は、日付にロジック処理を実行し、説明したようにIDに一意のスラッグを作成する単純なIDブローカーサーバーを作成します。それがどのように構築されているかを知っている限り、ソート/グループ化を機能させるためのネイティブのMySqlに相当するものがあり、表現は正常にシリアル化されます。UTC日付文字列と、文字列として追加された単調なシリアルを持つもの。

Twitterは、カスタムIDサーバーSnowflakeを実装したため、ここでカスタムインデックスの設計について興味深い洞察を得ました。

単純な整数であるだけでなく、いくつかのビジネスロジックを含むUUIDを生成するブローカーエンドポイントのアイデアは、ますます普及しています。

于 2012-06-19T15:53:32.013 に答える
0

PRIMARY KEY2つの列IDYEAR;の両方に結合を設定できます。このようにすると、ID1年に1つしかありません。

MySQL:

CREATE TABLE IF NOT EXISTS `ticket` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `year` YEAR NOT NULL DEFAULT '2012',
    `data` TEXT NOT NULL DEFAULT '',
    PRIMARY KEY (`id`, `year`)
)
ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_unicode_ci

更新: (@Paulo Buenoからのコメントへ)auto-increment-valueをリセットする方法は、MySQLのドキュメントに記載されています:mysql> ALTER TABLE ticket AUTO_INCREMENT = 1;。auto-increment-valueをリセットするときにyear-columnのデフォルト値も増やすと、連続した2列の主キーが得られます。しかし、リセットを実行するには、まだ何らかのトリガープログラムが必要だと思います。たぶん、毎年1月の最初にバッチスクリプトを起動するcronジョブです。

更新2: OK、今テストしましたが、auto-increment-valueをその特定の列の既存のIDよりも小さい数値に設定することはできません。私の間違い–組み合わせた主キーで機能すると思いました…</ del>

INSERT INTO `ticket` (`id`, `year`, `data`) VALUES
    (NULL , '2012', 'dtg htg het'),
    -- some more rows in 2012
);

-- this works of course
ALTER TABLE `ticket` CHANGE `year` `year` YEAR( 4 ) NOT NULL DEFAULT '2013';

-- this does not reset the auto-increment
ALTER TABLE `ticket` AUTO_INCREMENT = 1;

INSERT INTO `ticket` (`id`, `year`, `data`) VALUES
    (NULL , '2013', 'sadfadf asdf a'),
    -- some more rows in 2013
);
-- this will result in continously counted ID's

更新3: MySQLドキュメントページには、MyISAMテーブルでグループ化された主キーを使用する実用的な例があります。上記と同様のテーブルを使用していますが、最初の列として自動インクリメントを使用してはならないため、列の順序が逆になっています。これは、InnoDBではなくMyISAMを使用した場合にのみ機能するようです。MyISAMがまだニーズに合っている場合は、IDをリセットする必要はありませんが、年を増やすだけで、質問した結果が得られます。

参照:http ://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html (2番目の例、「MyISAMおよびBDBテーブルの場合、複数の2番目の列にAUTO_INCREMENTを指定できます-列インデックス。")

于 2012-06-19T16:07:42.523 に答える