導入開発では、ツリー構造のシナリオによく遭遇します。この記事では、部門テーブルを例に、いくつかの設計の長所と短所を比較します。 質問需要背景:部門別に人材を検索します。 再帰?再帰はこの問題を解決できるが、パフォーマンスは必然的に低下する。 設計 1: 隣接リスト注: (共通の親IDデザイン) テーブルデザインテーブル `dept_info01` を作成します ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自動増分主キー', `dept_id` int(10) NOT NULL COMMENT '部門ID', `dept_name` varchar(100) NOT NULL COMMENT '部門名', `dept_parent_id` int(11) NOT NULL COMMENT '親部門ID', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '作成時刻', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '変更時刻', BTREE を使用した主キー (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 デフォルト CHARSET=utf8; これは最も一般的な設計であり、冗長なデータなしでメニューのツリー構造を正しく表現できますが、レベル間のクエリには再帰処理が必要です。 SQL の例1. ノードの直接のサブセットをクエリする dept_info01 から * を選択、dept_parent_id = 1001 とする アドバンテージ シンプルな構造。 欠点 1.再帰なしでノードのすべての親とすべての子を照会することは不可能である デザイン 2: パスの列挙デザイン 1 に基づいて、すべての親セットを格納するための親部門 ID セット フィールドが追加され、複数のセットはコンマなどの固定区切り文字で区切られます。 テーブルデザインテーブル `dept_info02` を作成します ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自動増分主キー', `dept_id` int(10) NOT NULL COMMENT '部門ID', `dept_name` varchar(100) NOT NULL COMMENT '部門名', `dept_parent_id` int(11) NOT NULL COMMENT '親部門ID', `dept_parent_ids` varchar(255) NOT NULL DEFAULT '' COMMENT '親部門IDセット', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '作成時刻', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '変更時刻', BTREE を使用した主キー (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 デフォルト CHARSET=utf8; SQL の例1. すべてのサブセットをクエリする 選択 * から 部門情報02 どこ dept_parent_ids は '%1001%' のようになります 2) FIND_IN_SET関数を使用することをお勧めします。 選択 * から 部門情報02 どこ FIND_IN_SET( '1001', 部門の親ID ) アドバンテージ
欠点
デザイン3: クロージャーテーブル
テーブルデザインメインテーブル テーブル `dept_info03` を作成します ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自動増分主キー', `dept_id` int(10) NOT NULL COMMENT '部門ID', `dept_name` varchar(100) NOT NULL COMMENT '部門名', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '作成時刻', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '変更時刻', BTREE を使用した主キー (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 デフォルト CHARSET=utf8; 祖先と子孫の関係表 テーブル `dept_tree_path_info` を作成します ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自動増分主キー', `ancestor` int(10) NOT NULL COMMENT 'ancestor id', `子孫` int(10) NOT NULL COMMENT '子孫ID', `depth` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'レベル深度', BTREE を使用した主キー (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 デフォルト CHARSET=utf8; 注: depth はレベルの深さフィールドです。自己参照は 1、直接の子ノードは 2、次のレベルは 3 などです。レベルはレベルと同じです。 SQL の例新しいノードの挿入 dept_tree_path_info (祖先、子孫、深さ) に INSERT INTO dept_tree_path_info から t.ancestor、3001、t.depth+1 を選択 ここで、t.descendant = 2001 ユニオンオール 3001,3001,1 を選択 すべての祖先を照会する 選択 年 から dept_info03 AS c 内部結合 dept_tree_path_info t ON c.dept_id = t.ancestor どこ t.子孫 = 3001 すべての子孫を照会する 選択 年 から dept_info03 AS c 内部結合 dept_tree_path_info t ON c.dept_id = t.descendant どこ 先祖 = 1001 すべてのサブツリーを削除 消去 から 部門ツリーパス情報 どこ 子孫 IN ( 選択 部門ID から ( SELECT 子孫 dept_id FROM dept_tree_path_info WHERE 祖先 = 1001 ) a ) リーフノードを削除する 消去 から 部門ツリーパス情報 どこ 子孫 = 2001 モバイルノード
アドバンテージ
欠点
組み合わせて使う隣接リスト方式は、閉包テーブル方式と組み合わせることができます。実際、親 ID はメイン テーブルに重複して追加されます。直接的な関係のみをクエリする必要があるビジネスでは、2 つのテーブルをリンクせずにメイン テーブルを直接クエリできます。先祖-子孫関係テーブルは、レベル間のクエリが必要な場合に特に重要です。 テーブルデザインメインテーブル テーブル `dept_info04` を作成します ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自動増分主キー', `dept_id` int(10) NOT NULL COMMENT '部門ID', `dept_name` varchar(100) NOT NULL COMMENT '部門名', `dept_parent_id` int(11) NOT NULL COMMENT '親部門ID', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '作成時刻', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '変更時刻', BTREE を使用した主キー (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 デフォルト CHARSET=utf8; 祖先と子孫の関係表 テーブル `dept_tree_path_info` を作成します ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自動増分主キー', `ancestor` int(10) NOT NULL COMMENT 'ancestor id', `子孫` int(10) NOT NULL COMMENT '子孫ID', `depth` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'レベル深度', BTREE を使用した主キー (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 デフォルト CHARSET=utf8; 要約する実際、私の以前の仕事では、隣接リスト、パス列挙、隣接リストとパス列挙を組み合わせたものなど、さまざまな種類の設計を見てきました。それぞれの設計には長所と短所があり、選択する設計は、アプリケーション内のどの操作に最もパフォーマンスの最適化が必要かによって異なります。
要約すれば
これで、MYSQL のツリー構造テーブルの 3 つの設計の長所と短所の分析と共有に関するこの記事は終了です。MYSQL ツリー構造テーブルに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
>>: Nginx ストリーム構成プロキシ (Nginx TCP/UDP ロード バランシング)
目次共通キーエイリアスエイリアスが指定されていないキーシステム修飾キーカスタムキーエイリアス要約する...
導入Dockerfile ビルドの実行は、単一のコンテナの手動操作です。マイクロサービス アーキテク...
データベースの読み取りと書き込みの分離は、トラフィック量の多い大規模システムやインターネット アプリ...
ダウンロードリンク:動作環境VMware 仮想マシンの CentOS 7.6セキュアCRT Xftp...
この記事では、無限ループスクロールを実現するためのReactの具体的なコードを参考までに紹介します。...
時刻、文字列、タイムスタンプ間の変換は、日常生活でよく使用されます。よく使用されますが、私は使用する...
この記事では、CSS ワープ シャドウの実装コードを紹介し、皆さんと共有します。詳細は以下の通りです...
Vue を使用してプロジェクトを開発する過程で、次のような問題によく遭遇します。Vue のデータでオ...
Node.js はクライアントリクエストデータ内の中国語文字化けの問題を解決しますコード例: var...
この記事では、いくつかの基本的なページ要素の実装方法をまとめており、後で更新される予定です。まず、私...
inode番号でファイルを削除するまずls -iを使用して、削除するファイルのinode番号を見つけ...
CentOS の紹介CentOS は、Red Hat Linux が提供する無料で利用できるソースコ...
会社の基準により、特定のユーザーだけに Linux システムへのアクセスを許可することができます。あ...
質問があります。Dreamweaver で、3 行 1 列のログイン フォーム (ログイン、登録、パ...
エフェクト表示組み込みのブートインターフェースがあまりにも醜いので、テーマをダウンロードして美しくし...