MySQL のテーブル内のレコード数を制限する方法

MySQL のテーブル内のレコード数を制限する方法

MySQL のテーブル内のレコード数を制限する方法に対する簡単な答えはありません。たとえば、コマンドを実行したり、単にパラメータを設定したりしても、問題を完全に解決することはできません。次に、いくつかのオプションのソリューションを紹介します。

データベースの場合、問題に対する解決策は一般に 2 つあります。1一種是在應用端另外一種是在數據庫端

まず、データベース側では (假設表硬性限制為1W條記錄)、

1. トリガーソリューション

トリガーの考え方は非常にシンプルです。毎回新しいレコードを挿入する前に、テーブル内のレコード数が制限数に達しているかどうかを確認します。達していない場合は挿入を続行し、達している場合は最初に新しいレコードを挿入してから最も古いレコードを削除するか、その逆を行います。テーブル内のレコードの総数を確認するために毎回テーブル全体をスキャンするのを避けるために、別のテーブルを現在のテーブルのカウンターとして使用することを計画しています。挿入する前に、カウンター テーブルを確認するだけで済みます。この要件を満たすには、2 つのトリガーとカウンター テーブルが必要です。
t1 はレコード数を制限する必要があるテーブルであり、 t1_count はカウンター テーブルです。

mysql:ytt_new>テーブルt1を作成します(id int auto_increment主キー、r1 int);
クエリは正常、影響を受けた行は 0 行 (0.06 秒)
   
mysql:ytt_new>テーブルt1_count(cnt smallint unsigned);を作成します。
クエリは正常、影響を受けた行は 0 行 (0.04 秒)
   
mysql:ytt_new>t1_count を挿入し、cnt=0 を設定します。
クエリは正常、1 行が影響を受けました (0.11 秒)

挿入アクション用のトリガーを 1 つ、合計 2 つ記述する必要があります。

区切り文字 $$

`ytt_new`$$ を使用します

DROP TRIGGER /*!50032 が存在する場合 */ `tr_t1_insert`$$

作成する
    /*!50017 定義者 = 'ytt'@'%' */
    `t1` の INSERT 後に `tr_t1_insert` をトリガーする 
    各行の開始
       t1_count を更新し、cnt= cnt+1 に設定します。
    終わり;
$$

区切り文字 ;

もう 1 つは削除アクション トリガーです。

区切り文字 $$

`ytt_new`$$ を使用します

DROP TRIGGER /*!50032 が存在する場合 */ `tr_t1_delete`$$

作成する
    /*!50017 定義者 = 'ytt'@'%' */
    `t1` の削除後に `tr_t1_delete` をトリガーする 
    各行の開始
       t1_count を更新し、cnt= cnt-1 を設定します。
    終わり;
$$

区切り文字 ;

テーブル t1 に 10,000 件のレコードを作成し、上限に達します。

mysql:ytt_new> t1 (r1) を再帰的に tmp(a,b) として挿入します (select 1,1 union all select a+1,ceil(rand()*20) from tmp where a<10000 ) select b from tmp;
クエリは正常、10000 行が影響を受けました (0.68 秒)
レコード: 10000 重複: 0 警告: 0

カウンターテーブルt1_countは1Wを記録します。

mysql:ytt_new>t1_countからcntを選択します。
+-------+
|件数|
+-------+
| 10000 |
+-------+
セット内の 1 行 (0.00 秒)

挿入する前に、カウンター テーブルが制限に達しているかどうかを確認する必要があります。制限に達している場合は、まず古いレコードを削除します。ロジックを簡単に整理するためにストアド プロシージャを作成しました。

区切り文字 $$

`ytt_new`$$ を使用します

存在する場合はプロシージャを削除します `sp_insert_t1`$$

CREATE DEFINER=`ytt`@`%` PROCEDURE `sp_insert_t1`(
    f_r1 で
    )
始める
      v_cnt INT をデフォルト 0 として宣言します。
      t1_count から cnt を v_cnt に選択します。
      v_cnt >=10000の場合
        t1 から id で ORDER BY し、ASC LIMIT 1 で削除します。
      終了の場合;
      t1(r1) に値 (f_r1) を挿入します。          
    終わり$$

区切り文字 ;

この時点で、ストアド プロシージャの呼び出しが可能になります。

mysql:ytt_new>sp_insert_t1(9999)を呼び出します。
クエリは正常、1 行が影響を受けました (0.02 秒)

mysql:ytt_new>t1からcount(*)を選択します。
+----------+
| カウント(*) |
+----------+
| 10000 |
+----------+
セット内の1行(0.01秒)

このストアド プロシージャの処理ロジックは、バッチ処理にさらに最適化することもできます。 たとえば、テーブルレコードを毎回 2 倍ずつキャッシュする場合、判断ロジックは、20,000 レコードまでは只插入新記錄,并不刪除老記錄になります。20,000當到達2W條后,一次性刪除舊的1W條記錄

このソリューションには次の欠点があります。

  1. カウンター テーブルのレコード更新は、挿入/削除によってトリガーされます。テーブルが切り捨てられると、カウンター テーブルは更新されず、データの不整合が発生します。
  2. テーブルを削除すると、トリガーも削除されます。トリガーを再構築し、カウンター テーブルをリセットする必要があります。
  3. テーブルは、ストアド プロシージャなどの単一のエントリを通じてのみ書き込むことができ、他のエントリは使用できません。

2. パーティションテーブルソリューション

rangeパーティションを作成します。最初のパーティションには 10,000 件のレコードがあります。2 番目のパーティションはデフォルトのパーティションです。テーブル レコードの数が制限に達したら、最初のパーティションを削除し、パーティション定義を再調整します。

パーティションテーブルの初期定義:

mysql:ytt_new>create table t1(id int auto_increment primary key, r1 int)partition by range(id) (partition p1 values ​​less than(10001),partition p_max values ​​less than(maxvalue));
クエリは正常、影響を受けた行は 0 行 (0.45 秒)


最初のパーティションがいっぱいかどうかを確認します。

mysql:ytt_new>t1パーティション(p1)からcount(*)を選択します。
+----------+
| カウント(*) |
+----------+
| 10000 |
+----------+
セット内の 1 行 (0.00 秒)


最初のパーティションを削除し、パーティション テーブルのサイズを変更します。

mysql:ytt_new>テーブル t1 を変更してパーティション p1 を削除します。
クエリは正常、影響を受けた行は 0 行 (0.06 秒)
レコード: 0 重複: 0 警告: 0

mysql:ytt_new>テーブルt1を変更して、パーティションp_maxを(パーティションp1の値が(20001)未満、パーティションp_maxの値が(maxvalue)未満)に再編成します。
クエリは正常、影響を受けた行は 0 行 (0.60 秒)
レコード: 0 重複: 0 警告: 0

このアプローチの利点は明らかです。

  1. テーブル挿入エントリは、ランダム、INSERT ステートメント、ストアド プロシージャ、またはインポート ファイルになります。
  2. 最初のパーティションを削除するのは DROP 操作であり、非常に高速です。

しかし、欠点もあります。テーブル レコードにギャップがあってはなりません。ギャップがある場合は、パーティション テーブルの定義を変更する必要があります。たとえば、パーティション p1 の最大値を 20001 に変更した場合、このパーティション内のレコードの半分が不連続であっても、取得パーティション内のレコードの合計数には影響しません。

3. 一般的な表領域ソリューション

このテーブルの 10,000 レコードに必要なディスク容量を事前に計算し、このテーブルのデータを格納するためにディスク上にゾーンを割り当てます。
パーティションをマウントし、 InnoDBテーブルスペースの代替ディレクトリ(/tmp/mysql/)。

mysql:ytt_new>テーブルスペース ts1 を作成し、データファイル '/tmp/mysql/ts1.ibd' を追加します。エンジンは innodb です。
クエリは正常、影響を受けた行は 0 行 (0.11 秒)
mysql:ytt_new>テーブル t1 のテーブルスペース ts1 を変更します。
クエリは正常、影響を受けた行は 0 行 (0.12 秒)
レコード: 0 重複: 0 警告: 0


大まかな計算をしましたが、あまり正確ではないので、記録に多少の誤りがあるかもしれませんが、意味は非常に明確です。テーブルに「TABLE IS FULL」と表示されるまで待ちます。

mysql:ytt_new>t1(r1)の値を挿入します(200);
エラー 1114 (HY000): テーブル 't1' がいっぱいです

mysql:ytt_new>t1からcount(*)を選択します。
+----------+
| カウント(*) |
+----------+
|10384|
+----------+
セット内の1行(0.20秒)

テーブルがいっぱいになったら、テーブルスペースを削除し、テーブルをクリアしてから、新しいレコードを挿入します

mysql:ytt_new>テーブル t1 のテーブルスペース innodb_file_per_table を変更します。
クエリは正常、影響を受けた行は 0 行 (0.18 秒)
レコード: 0 重複: 0 警告: 0

mysql:ytt_new>テーブルスペースts1を削除します。
クエリは正常、影響を受けた行は 0 行 (0.13 秒)

mysql:ytt_new>テーブルt1を切り捨てます。
クエリは正常、影響を受けた行は 0 行 (0.04 秒)

もう 1 つは、アプリケーション側で処理することです。

アプリケーション側でテーブルデータを事前にキャッシュしておき、一定件数に達したらデータベース側に一括で書き込むことができます。データベースに書き込む前に、テーブルをクリアするだけです。
たとえば、テーブルt1のデータはファイルt1.csvにキャッシュされます。 t1.csv1W行に達すると、データベースはテーブル データをクリアし、 t1.csvをインポートします。

結論:

MySQL の MyISAM 時代には、テーブル属性max_rowsを使用してテーブル内のレコード数を見積もっていましたが、これは厳格なルールではありませんでした。これは、一般的なテーブルスペースを使用してテーブル内のレコード数を制限することについて上で書いたことと似ています。InnoDB InnoDBには直感的な方法はなく、上記の方法によって問題が解決されることが多くなっています。選択する具体的なソリューションは、ニーズによって異なります。

これで、MySQL のテーブル内のレコード数を制限する方法についての記事は終了です。MySQL のテーブル内のレコード数を制限する方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQLは最も近いレコードデータのクエリを実装します
  • レコード数0のMySQL pscファイルを復元するソリューションの詳細な説明
  • ライブラリ内の各テーブルのレコード数をカウントし、降順に並べるPHP + MySQLメソッド
  • MySQLデータベース内のデータテーブルが占めるスペースとレコード数を表示する方法
  • MYSQL データベース ステートメントの記録速度が遅い問題
  • MySQLはトリガーを使用してデータベース内のテーブルの行制限を解決します。詳細な説明と例
  • MySQL パーティションテーブルの制限と制約の詳細な説明

<<:  CSS でショートカット プロパティを記述する際は、トラブルの順序に注意してください (落とし穴を避けるため)

>>:  ウェブ開発者やデザイナーにとって欠かせないオンラインウェブツールとアプリケーション

推薦する

win10 での mysql 8.0.16 winx64 インストールの最新グラフィック チュートリアル

このデータベースをダウンロードするには、多くの時間とトラフィックがかかります。踏み込んだ落とし穴で時...

mysql スケジュールタスク (イベント イベント) の詳細な説明

1. イベントの簡単な紹介イベントは、MySQL が特定の時間に呼び出す手続き型データベース オブジ...

Nginx がフロントエンド リソースへのクロスドメイン アクセスの問題をどのように解決するかの詳細な説明

フロントエンドのクロスドメイン問題に2日間近く悩まされましたが、ようやくngnxを使って解決したので...

経験豊富な人が、プロフェッショナルで標準化されたMySQL起動スクリプトの開発方法を紹介します。

シェル スクリプト言語は、すべてのプログラミング言語の中で最も単純な言語であるため、資格のある Li...

Windows 7 64 ビットに最新バージョンの MySQL サーバーをインストールする方法のグラフィック チュートリアル

最近、MySQL データベースを勉強していて、設定ファイルを頻繁に変更したため、MySQL データベ...

CSS3 のフィルタプロパティの使用に関する詳細な説明

最近、イントラネットポータルを修正していたときに、フィルターを使用する必要がある箇所に遭遇しました。...

2列の水平タイムラインを実装するためのVueサンプルコード

目次1.コンポーネントtimelineH.vueを実装する2. コンポーネントの呼び出しこの記事では...

MySQL マスタースレーブレプリケーションの実践の詳細説明 - ログポイントに基づくレプリケーション

ログポイントベースのレプリケーション1. マスターデータベースとスレーブデータベースに専用のレプリケ...

HTML でのアンカーポイントの適用

アンカーポイントの設定<a name="トップ"></a>...

iframeフレームはIEブラウザで白い背景を透明に設定します

最近、プロジェクトを進める過程で、ページの階層構造を描画するために iframe を頻繁に使用する必...

CSS マルチカラムレイアウトソリューション

1. 固定幅+適応型期待される効果: 左側は固定幅、右側は適応幅 共通コード: html: <...

モバイル端末での Vue2.x Picker のグローバル呼び出し実装

目次ピッカーコンポーネントとはピッカーコンポーネントの問題解決オプションの説明解決ディレクトリ部門P...

Windows 10 システムに mysql-8.0.13 (zip インストール) をインストールする詳細なチュートリアル

インストール環境の説明•システムバージョン: windows10 •MySQL バージョン: mys...

HTML 選択タグにリンクを追加する 3 つの方法

最初のもの:コードをコピーコードは次のとおりです。 <html> <ヘッド>...