MySQLはconnect_by_isleaf MySQLメソッドまたはストアドプロシージャに似た機能を実装します

MySQLはconnect_by_isleaf MySQLメソッドまたはストアドプロシージャに似た機能を実装します

最近、特に異常なビジネス需要があり、テーブルがあります

テーブル「デモ」を作成します(
 `id` int(11) 符号なし NOT NULL AUTO_INCREMENT,
 `tid` int(11) デフォルト '0',
 `pid` int(11) デフォルト '1',
 主キー (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3000124 デフォルトCHARSET=utf8;

以上です。レコードの行数は 300 万行を超えます。各 pid はこの ID の最上位カテゴリを記録し、tid はその親カテゴリです。
ここでの要件は、ID を指定してそのサブセット メンバーをすべて見つけ、この pid の値を新しく指定した値に変更することです。 !
PHP で実行したところ、実行に約 50 秒以上かかり、非常に苦痛でした。 ! !
すべてのサブセットを再帰的に検索し、その PID を変更する必要があり、これは非常に手間のかかる作業です。

Oracle には connect_by_isleaf というメソッドがあり、すべてのサブセットを簡単に見つけることができますが、私は MySQL を使用しています...

そこで、ここではMySQLメソッドやストアドプロシージャを使用して実装した経験について簡単に書きます。

1つ目: MySQL方式

CREATE DEFINER=`root`@`localhost` FUNCTION `lvtao_demo_a`(rootId int) 戻り値 text CHARSET utf8
  SQLデータの読み取り
  コメント「デモ」
始める

sTemp テキストを宣言します。
sTempChd テキストを宣言します。

SET sTempChd =cast(rootId を CHAR として)。
sTemp を '' に設定します。

sTempChdがnullではない場合
  SET sTemp = concat(sTemp,',',sTempChd);
  SELECT group_concat(id) INTO sTempChd FROM demo where FIND_IN_SET(tid,sTempChd)>0;
終了しながら;

sTemp を返します。

終わり;

使用方法は

lvtao_demo_a(5)を選択します。

しかし、テストしていたところ、300 万個のデータがクラッシュしてしまいました。 ! !

行 1 の列 'sTemp' のデータが長すぎます

利点: シンプル、便利、再帰呼び出しレベルの深さに制限なし (max_sp_recursion_depth、最大 255)。
デメリット: 長さが限られている。

2番目のタイプ: ストアドプロシージャ + 中間テーブル

区切り文字 ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `sss`(IN pid int, IN rootid int)
始める
   
done INT DEFAULT FALSE を宣言します。
id TEXT を宣言します。
DECLARE cur1 CURSOR FOR SELECT id FROM demo WHERE tid=pid;
NOT FOUND SET done = TRUE の継続ハンドラーを宣言します。

max_sp_recursion_depth を 200 に設定します。
 
オープンcur1;
  read_loop: ループ
    cur1 を id にフェッチします。
    完了したら
      read_loop を終了します。
    終了の場合;
    INSERT INTO temp (rootid,zid) values ​​(rootid, id);
    sss(id,rootid) を呼び出します。
  ループを終了;
cur1 を閉じます。

終わり;;
区切り文字 ;

ハハハ、300万のデータもボールの中に詰まってるよ〜〜〜

別の方法を考えよう~~~~もうこれ以上は気にしない

以下もご興味があるかもしれません:
  • Linux 上の MySQL でストアド プロシージャを使用してレコードをバッチで生成する方法
  • Mybatis 呼び出し MySQL ストアド プロシージャのシンプルな実装
  • MySQL と Oracle の違いの比較: 5: ストアド プロシージャと関数
  • mysqlストアドプロシージャは重複データを判定し、挿入しません
  • Java で MySQL ストアド プロシージャを呼び出す方法の詳細な説明
  • MySQL データベースのストアド プロシージャによるツリー トラバーサルの実装
  • MySQL ストアド プロシージャの最適化の例
  • MySQL のストアド プロシージャの分析例とストアド プロシージャの呼び出し方法
  • MySQL ストアド プロシージャ、カーソル、トランザクションの例の詳細な説明

<<:  Vue の計算プロパティとリスナーの使用の概要

>>:  Docker で ElasticSearch をデプロイする方法

推薦する

チェックボックスの選択またはキャンセルを実装するJavaScript

この記事では、すべてのチェックボックスを選択または解除するためのJavaScriptの具体的なコード...

mysqlのデータディレクトリ内のファイルを直接コピーしてデータを復元する実装

mysqlはデータディレクトリ内のファイルをコピーしてデータを復元します背景: MySQL がクラッ...

CSS における重要なカスケード概念の詳細な説明

最近、プロジェクトの過程で問題に遭遇しました。メニューバーを常に上部に表示し、後続の要素をその下に表...

Ckeditor + Ckfinderを使用したJavaScriptファイルアップロードケースの詳細な説明

目次1. 準備2. 減圧3. 統合を開始する1. 準備Ckeditor_4.5.7_full + C...

Vue のスロットの使用法と適用シナリオの詳細な分析

スロットとは何ですか? Vue では、子コンポーネント タグの中央に何もラップできないことはわかって...

CSSで検索ボックスを非表示にする機能を実装します(アニメーション順方向と逆方向のシーケンス)

上部のメニュー バーに検索ボックスを配置するのは一般的なシナリオですが、検索機能がそれほど頻繁に使用...

Nginx リバース プロキシから go-fastdfs へのケースの説明

背景go-fastdfs は、http プロトコルをサポートする分散ファイルシステムです。一般的なプ...

Ubuntu 16.04 で PostgreSQL の起動を設定する方法

PostgreSQL はコンパイルされインストールされるため、起動時に起動するように設定する必要があ...

phpstudy から Linux への MySQL の移行に関するチュートリアル

プロジェクトの目的元のWindows環境でphpstudyを使用して構築されたMySQL 5.5.5...

nacos が mysql に接続できない場合の解決策

理由nacos の pom が依存する mysql バージョンが、mysql バージョンと一致してい...

MySQL ビューの紹介と基本操作のチュートリアル

序文ビューは、データベース システム内で非常に便利なデータベース オブジェクトです。 MySQL 5...

VirtualBox+Ubuntu16でKubernetesクラスタを構築する実装

目次Kubernetesについて基本的な環境の準備VirtualBoxをインストールするUbuntu...

MySQLインデックスに関する重要な面接の質問をいくつか共有します

序文インデックスは、データベース内の 1 つ以上の列の値を並べ替え、データベースが効率的にデータを取...

CSS トップに戻る コード例

最近のウェブサイトのほとんどはページが長く、4 画面または 5 画面の長さのものもあれば、2 画面ま...

SecureCRT に基づくリモート Linux ホストへのファイルのアップロードとダウンロードのグラフィカルな手順

wget や curl ツールを使用して、Linux サーバーで大規模なネットワーク ファイルを直接...