MySQL-Abfragebaumstrukturmethode

MySQL-Abfragebaumstrukturmethode

MySQL-Abfragebaumstruktur

1. Über die Baumstruktur

Bildbeschreibung hier einfügen

Daten dieser Art von Struktur erfordern normalerweise selbstassoziierende Felder wie ID und ParentId in der Tabellenstruktur. Manchmal können zur Verbesserung der Abfrageeffizienz weitere redundante Felder hinzugefügt werden, wie z. B. Index, wobei der Wert von Index die Menge der ID-Zeichenfolgen aller übergeordneten Verzeichnisse ist.

In Bezug auf die Zusammenstellung von Baumstrukturdaten besteht die übliche Schreibmethode darin, einen vollständigen Baum durch Rekursion im Programm zu konstruieren. Die Methode, einfach SQL zu verwenden, wird nicht häufig verwendet. Beispiele für die beiden Methoden finden Sie unten.

2. So definieren Sie benutzerdefinierte Funktionen in MySQL

Was ist eine benutzerdefinierte MySQL-Funktion: Aggregatfunktionen, Datumsfunktionen und dergleichen sind alles MySQL-Funktionen. Die hier definierten Funktionen können auf die gleiche Weise wie diese verwendet werden, können jedoch nur in der definierten Datenbank verwendet werden. Benutzerdefinierte Funktionen ähneln gespeicherten Prozeduren, der Unterschied besteht jedoch darin, dass Funktionen nur einen Wert zurückgeben und keinen Ergebnissatz zurückgeben dürfen.

2.1 Testdaten erstellen

CREATE TABLE `Baum` (
  `id` bigint(11) NICHT NULL,
  `pid` bigint(11) NULL DEFAULT NULL,
  `name` varchar(255) ZEICHENSATZ utf8 SORTIMENT utf8_general_ci NULL STANDARD NULL,
  PRIMÄRSCHLÜSSEL (`id`) MIT BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamisch;
INSERT INTO `tree` VALUES (1, 0, 'Baum');
INSERT INTO `tree` VALUES (2, 1, 'Provinz Sichuan');
INSERT INTO `Baum` VALUES (3, 2, 'Chengdu');
INSERT INTO `tree` VALUES (4, 3, 'Bezirk Wuhou');
INSERT INTO `Baum` VALUES (5, 4, 'Roter Torbogen');
INSERT INTO `tree` VALUES (6, 1, 'Provinz Guangdong');
INSERT INTO `tree` VALUES (7, 1, 'Provinz Zhejiang');
INSERT INTO `Baum` VALUES (8, 6, 'Guangzhou');

2.2 Alle untergeordneten Knoten unter einem Knoten abrufen

FUNKTION „GET_CHILD_NODE“ ERSTELLEN (rootId varchar(100))   
Gibt varchar(2000) zurück.  
BEGINNEN   
DECLARE str varchar(2000);  
DECLARE cid varchar(100);   
SETZEN Sie str = "$";   
SETZEN Sie cid = rootId;   
WHILE cid ist nicht null DO   
    SET str = concat(str, ',', cid);   
    Wählen Sie group_concat(id) INTO cid FROM Baum, wo FIND_IN_SET(pid, cid);   
ENDE WÄHREND;   
RETURN str;   
ENDE

Aufrufen einer benutzerdefinierten Funktion

Wählen Sie * aus dem Baum, wo FIND_IN_SET(id, GET_CHILD_NODE(2)); 

Bildbeschreibung hier einfügen

2.3 Alle übergeordneten Knoten eines Knotens abrufen

FUNKTION „GET_PARENT_NODE“ ERSTELLEN (rootId varchar(100))   
Gibt varchar(1000) zurück.   
BEGINNEN   
DECLARE fid varchar(100) default '';   
DECLARE str varchar(1000) Standard-RootId;   
  
WHILE rootId ist nicht null   
    SETZEN Sie fid = (SELECT pid FROM tree WHERE id = rootId);   
    WENN fid nicht null ist, DANN   
        SET str = concat(str, ',', fid);   
        SETZEN Sie rootId = fid;   
    ANDERS   
        SETZEN Sie rootId = fid;   
    ENDE, WENN;   
ENDE WÄHREND;   
gibt str zurück;  
ENDE

Aufrufen einer benutzerdefinierten Funktion

Wählen Sie * aus dem Baum, wo FIND_IN_SET(id, GET_PARENT_NODE(5)); 

Bildbeschreibung hier einfügen

3. Oracle-Datenbankmethode

Sie müssen nur die Anweisung „Start with Connect by Prior“ verwenden, um die rekursive Baumabfrage abzuschließen. Weitere Einzelheiten finden Sie in den entsprechenden Informationen.

4. Der Programmcode erstellt rekursiv den Baum

Ich werde hier nicht den vollständigen Code angeben. Die rekursive Methode ist sehr einfach. Suchen Sie zuerst alle Baumknoten und fügen Sie dann rekursiv alle untergeordneten Knoten über die Add-Methode in der TreeNode-Klasse hinzu. Der Kerncode lautet wie folgt:

öffentliche Klasse TreeNodeDTO {
    
    private String-ID;
    private Zeichenfolge parentId;
    privater String-Name;
    private Liste<TreeNodeDTO> untergeordnete Elemente = neue ArrayList<>();
    public void add(TreeNodeDTO-Knoten) {
        wenn ("0".equals(node.parentId)) {
            dies.Kinder.add(Knoten);
        } sonst wenn (node.parentId.equals(this.id)) {
            dies.Kinder.add(Knoten);
        } anders {
         	//Rekursiv add() aufrufen, um untergeordnete Knoten für (TreeNodeDTO tmp_node : children) { hinzuzufügen.
                tmp_node.add(Knoten);
            }
        }
    }
 }

5. Durch hashMap ist nur eine Durchquerung erforderlich

Sie können die Baumgenerierung abschließen: Fünf-Sterne-Empfehlung

Liste<TreeNodeDTO> Liste = dbMapper.getNodeList();
ArrayList<TreeNodeDTO> rootNodes = neue ArrayList<>();
Map<Integer, TreeNodeDTO> map = neue HashMap<>();
für (TreeNodeDTO-Knoten: Liste) {
    map.put(node.getId(), node);
    Integer parentId = node.getParentId();
    // Bestimmen Sie, ob ein übergeordneter Knoten vorhanden ist (wenn kein übergeordneter Knoten vorhanden ist, handelt es sich um ein übergeordnetes Menü)
    wenn (parentId.equals('0')){
        rootNodes.add(Knoten);
        //Suchen Sie das Menü, das nicht das übergeordnete Menü ist und dessen übergeordnete Menü-ID in der Sammlung enthält
    } sonst wenn (map.containsKey(parentId)){
        map.get(parentId).getChildren().add(node);
    }
}

MySQL-Abfrage mit Baumstrukturinformationen

In Oracle gibt es eine Funktionsanwendung, die die Baumstrukturinformationen direkt abfragen kann. Wenn beispielsweise eine Organisationsmitgliedsstruktur mit der folgenden Baumstruktur vorliegt, möchten wir alle Knoteninformationen unter einem der Knoten abfragen

In Oracle können Sie die folgende Syntax verwenden, um direkt abzufragen

STARTEN SIE MIT CONNECT BY PRIOR

Eine solche Syntax gibt es in MySQL jedoch nicht.

Was wäre, wenn Sie auch solche Datenstrukturinformationen abfragen möchten? Wir können unsere eigenen Funktionen definieren. Wir initialisieren die obigen Informationen in der Datenbank. Erstellen Sie zunächst eine Tabelle zum Speichern dieser Informationen. ID speichert die eigenen ID-Informationen und PARENT_ID speichert die übergeordneten ID-Informationen.

CREATE TABLE `company_inf` (
  `ID` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `NAME` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `PARENT_ID` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL
)

Initialisieren Sie dann die Informationen in der Tabelle

INSERT INTO company_inf VALUES ('1', 'Geschäftsführer Wang Damazi', '1');
INSERT INTO company_inf VALUES ('2','F&E-Manager Liu Daquezi','1');
INSERT INTO company_inf VALUES ('3','Verkaufsleiter Ma Erlangzi','1');
INSERT INTO company_inf VALUES ('4','Finanzmanager Zhao Santuozi','1');
INSERT INTO company_inf VALUES ('5','Sekretärin Mitarbeiter J','1');
INSERT INTO company_inf VALUES ('6','F&E-Teamleiter Wu Dabangchui','2');
INSERT INTO company_inf VALUES ('7','Zheng Laoliu, Leiter der Forschungs- und Entwicklungsgruppe 2','2');
INSERT INTO company_inf VALUES ('8','Verkäufer G','3');
INSERT INTO company_inf VALUES ('9','Verkäufer H','3');
INSERT INTO company_inf VALUES ('10','Finanzpersonal I','4');
INSERT INTO company_inf VALUES ('11','Entwickler A','6');
INSERT INTO company_inf VALUES ('12','Entwickler B','6');
INSERT INTO company_inf VALUES ('13','Entwickler C','6');
INSERT INTO company_inf VALUES ('14','Entwickler D','7');
INSERT INTO company_inf VALUES ('15','Entwickler E','7');
INSERT INTO company_inf VALUES ('16','Entwickler F','7');

Wenn wir beispielsweise alle Mitarbeiter unter dem Forschungs- und Entwicklungsleiter Liu Daquzi abfragen möchten, können wir dies in Oracle schreiben

  WÄHLEN *
  VON T_PORTAL_AUTHORITY
  BEGINNEN MIT ID='1'
  VERBINDEN NACH VORHERIGER ID = PARENT_ID

In Mysql benötigen wir die folgende benutzerdefinierte Funktion

Funktion erstellen getChild(parentId VARCHAR(1000))
Gibt VARCHAR(1000) zurück.
BEGINNEN
    DECLARE oTemp VARCHAR(1000);
    DECLARE oTempChild VARCHAR(1000);
    SETZEN Sie oTemp = '';
    SET oTempChild = übergeordneteId;
    WHILE oTempChild ist nicht null DO
        WENN oTemp != '' DANN
            SET oTemp = concat(oTemp,',',oTempChild);
        ANDERS
            SETZEN Sie oTemp = oTempChild;
        ENDE, WENN;
        SELECT group_concat(ID) INTO oTempChild FROM company_inf, wobei parentId<>ID und FIND_IN_SET(parent_id,oTempChild)>0;
    ENDE WÄHREND;
ZURÜCK oTemp;
ENDE

Dann können Sie wie folgt abfragen

Wählen Sie * aus company_inf, wo Find_in_Set (ID, getChild ('2'));

Zu diesem Zeitpunkt handelt es sich bei den durch die Überprüfung der Abfrage erhaltenen Informationen um sämtliche Mitarbeiterinformationen unter Liu Daquzi.

Das Obige ist meine persönliche Erfahrung. Ich hoffe, es kann Ihnen als Referenz dienen. Ich hoffe auch, dass Sie 123WORDPRESS.COM unterstützen werden.

Das könnte Sie auch interessieren:
  • Implementierungsmethode der rekursiven MySQL-Baumabfrage
  • So implementieren Sie eine baumartige Abfrage aller untergeordneten Knoten in MySQL
  • Einführung in die mehrstufige Strukturbaumsuche von MySQL
  • Spezifische Implementierung für untergeordnete Knoten und übergeordnete Knoten der rekursiven Abfragebaumtabelle von MySQL

<<:  Mehr als 300 Zeilen CSS-Code, um die explosiven Spezialeffekte von WeChat 8.0 zu erzielen

>>:  Beispiele für zwei Möglichkeiten zur Implementierung einer horizontalen Bildlaufleiste

Artikel empfehlen

Vue verwendet MockJS, um simulierte Datenfalldetails zu generieren

Inhaltsverzeichnis Installieren Sie Mockjs in Ihr...

Tipps zum Erstellen zweidimensionaler Arrays in JavaScript

Erstellen eines zweidimensionalen Arrays in Js: Z...

Beginnen Sie CSS-Pseudoklassennamen nicht mit Zahlen

Wenn Neulinge Div+CSS entwickeln, müssen sie die ...

Zusammenfassung der Ausnahmen bei der MySQL-Datenbankverbindung (sammelwürdig)

Beim Bereitstellen des Projekts auf Centos ist mi...

Praktische Optimierung des MySQL-Paging-Limits

Vorwort Wenn wir Abfrageanweisungen verwenden, mü...

So installieren Sie MySQL 5.7.29 mit einem Klick mithilfe eines Shell-Skripts

Dieser Artikel bezieht sich auf die Arbeit des 51...

Vue implementiert die Bottom-Query-Funktion

In diesem Artikelbeispiel wird der spezifische Co...

Lösung für mehrere 302-Antworten im Nginx-Proxy (Nginx Follow 302)

Proxying mehrerer 302er mit proxy_intercept_error...

Detaillierter Prozess der FastAPI-Bereitstellung auf Docker

Docker-Lernen https://www.cnblogs.com/poloyy/p/15...

Mehrere Navigationsrichtungen, die in Zukunft beliebt sein werden

<br />Dies ist nicht nur ein Zeitalter der I...

MySQL-Datenbankindizes und -Transaktionen

Inhaltsverzeichnis 1. Inhaltsverzeichnis 1.1 Konz...