2017-07-17 16 views
0

私は毎日何百ものデータを受け付けるPHPシステムを持っています。私はすべてのデータを格納するデータベースとしてMySQLを使用しています。一意のvarcharの自動増分が重複を引き起こす可能性があります

メインテーブルの1つで、それは 'tableData'と呼ばれ、すべてのメインデータが格納され、2つのプライマリキーがあります。第1の主キーは、自動インクリメント整数です。 2番目の主キーは、データが必要なときにこの形式(rep/yyyy/AIinteger、rep/2017/00021、rep/2017/00023、rep/2016/02345)のvarchar値を格納したsubmission_numです。

tableDataに提出するには、phpはsubmission_numの最大数を取得し、それを1つ増やして、新しいsubmission_numを使用して新しいデータをtableDataに挿入します。 (例えば、PHPが最大数としてrep/2017/00034を受け取った場合、整数部分を1だけ増やし、新しい申請件数はrep/2017/00035となります)、新しいデータを新しい申請と一緒に保存しますNUM)

PHPスクリプトのアルゴリズムは最大submission_num、
クエリを取得この

  1. 次のようになります。SUBSTR(submission_num、5,4)=「$ curYearたtableData FROM SELECT submission_numを'ORDER BY submission_num DESC LIMIT 0,1 1

  2. この方法は、問題を起こした1

  3. ストアデータ

によって整数部分を増やします。 2人以上のユーザーが適切なタイミングで「送信」ボタンを押すと、彼らは同じsubmission numを生成し、重複したsubmission num(このsubmission numは一意である必要があります)を使用してデータベースに保存します。

PHPスクリプトのSelectクエリからテーブルを一時的にロックする方法はありますか?

+0

btw、私はあなたに悪い知らせている場合は非常にごめんなさい。私は英語でかなり悪いです –

+0

使用テーブルのタイプによっては、トランザクションまたはロックを使用します。いずれにしても、1つのテーブルに2つの自動インクリメントが必要な場合は、おそらくそのうちの1つだけが必要な場合、または2つ目のテーブルを作成する必要がある場合があります。 –

答えて

0

テーブルには1つの主キー制約があり、複数の一意制約を持つことができます。 soapboxを脇に置いてください。

submission_numが表の3つの異なる属性を表すため、問題があります。行が挿入された時点で3番目の属性(指定された行セットのサブシーケンス)を計算したいので、テーブルのロックに関する質問をするための並列処理の問題があります。

代わりに、現実的なモデルを定義し、submission_numの最初のコンポーネントをコード列として保存し、2番目のコンポーネントをinsert_date列として格納します。

テーブルをクエリすると、後で3番目の "サブ属性"を計算できます。そうすれば、ではなく、というテーブルをロックする必要があります。これは、ユーザーが直面するアプリケーションでは絶対にしてはならないことです。あなたは、(追加year_submission_num列を含む)は、新しいテーブルに変更を加えることがその挿入日未満01-JAN-2017である行に対してyear_submission_numを移入し、あるビューを作成することができます

補遺1

2組のAとBの和集合

集合Aは、year_submission_numがnullでない行の集合で、投影列Cを定義しています。これは、現在の値を連結したものです。

セットBは、あなたが一日一回続いC.

を生成するために、より複雑なサブクエリを記述するyear_submission_numがnullの行のセットです、あなたはそれが現在どこyear_submission_numを更新するために、バッチジョブを実行しますヌル。そうすれば、「より複雑なサブクエリ」はそれほど高価ではありません。

とすると、ページを変更する必要はありません。

+0

素晴らしい提案に感謝します。 submission_numを使用してデータを取得するかなりの数のページが存在するため、あまりにも多くのページを再コード化する必要があるようです。あなたの説明のおかげで。大いに感謝します –

+0

@CatifyAuthent addendum 1を確認してください。 – jeff6times7

+0

ありがとうございます。それは最初は理解するのがかなり複雑ですが、今は得ました。あなたの解決策にかなりの時間がかかるようです。私はクライアント企業でコードとデータベースを変更することしかできないので、時間がかかりません。彼らはリモートを許可しません。私はソースコードとデータベースのコピーを持っています。これを私のlocalhostに実装しようとします。もしそれが良いのであれば、私は再びここに来るときにそれを実装します。それは今から1ヶ月後です。 * sigh * –

-1

いくつかのクエリでこの問題を処理できるかどうかはわかりませんが、私は単純なアプローチがあります。整数部分を1つ増やした後にもう一度チェックすることができます。結果のような2番目の主キーがない場合は、データを保存することができます。結果のように2番目のプライマリキーがある場合は、再び1にすることができます。ええ、あなたはこのチェックのループプロセスが必要です

+0

チェックと挿入の間に同じ問題が発生する可能性があります。 –

+0

編集してもうまくいかない場合でも、重複していることがあります。自動増分フィールド、ロック、またはトランザクションでのみ解決できます。 –

+0

hiis azis。答えに感謝します。はい、私は皆と同意します。それでも同じ問題が発生する可能性があります。私はリモートからアクセスすることができないのでクライアントのコードを変更することができます(そして今から1ヶ月後に再びここに来るかもしれません)、私はあなたのアイデアを実装しましたが、スクリプトがランダム1~5秒の間の時間。私はこれが重複した提出numを得るチャンスを減らすと思うが、提出プロセスを遅らせるだろう。私は今のところこの解決策を続けている –

関連する問題