Mes collègues m'ont demandé comment demander MySQL Récursivement. J'a i été déconcerté et j'ai pris note d'une entrevue d'emploi pour Java R & D dans l'équipe américaine

Reste debout toute la nuit. 2021-08-20 00:02:45 阅读数:999

mes coll gues ont demand

En plus,Avant ça,,Nous devons revoir quelques MYSQLFonctions dans,À utiliser ultérieurement.

find_in_set Fonctions

Syntaxe des fonctions:find_in_set(str,strlist)

str Représente la chaîne à interroger , strlist Est une chaîne séparée par des virgules,Par exemple: (‘a,b,c’).

Cette fonction est utilisée pour trouver str Chaîne dans la chaîne strlist Position in,Renvoie le résultat comme suit: 1 ~ n .S'il n'est pas trouvé,Renvoie0.

Prends une châtaigne.:

select FIND_IN_SET('b','a,b,c,d');

  • 1.

Retour des résultats 2 .Parce que b L'emplacement est le deuxième emplacement de sous - chaîne.

En outre,Lors de l'interrogation des données du tableau,Il y a une autre utilisation,Comme suit:

select * from dept where FIND_IN_SET(id,'1000,1001,1002');

  • 1.

Les résultats renvoient tous les id In strlist Record in,C'est - à - dire: id = ‘1000’ ,id = ‘1001’ ,id = ‘1002’ Trois enregistrements.

Regarde ça., Pour les requêtes récursives que nous allons résoudre , Je ne sais pas si vous avez une idée .

Prenons l'exemple d'une requête récursive vers le bas pour tous les noeuds enfants .Je crois que, Est - il possible de trouver une chaîne concaténée par des virgules contenant le noeud courant et tous les noeuds enfants strlist, Entrée find_in_set Fonctions. Vous pouvez interroger toutes les données récursives requises .

Alors, La question est maintenant de savoir comment construire une telle chaîne strlist .

.Ceci nécessite les fonctions d'épissage de chaîne suivantes .

concat,concat_ws,group_concat Fonctions

Un.、 Dans la fonction d'épissage de chaîne , Le plus basique c'est concat C'est. Il est utilisé pour connecter NChaîne (s),Par exemple:,

select CONCAT('M','Y','S','Q','L') from dual;

  • 1.

Les résultats sont les suivants: ‘MYSQL’ String.

2.、concat Est un séparateur par défaut avec une virgule ,Et concat_ws Vous pouvez spécifier un séparateur , Le premier paramètre passe dans le séparateur , Si séparé par un soulignement .

Trois、group_concat Les fonctions sont plus puissantes , Tout en pouvant être groupés , Concaténer les champs en chaînes avec des délimiteurs spécifiques .

Utilisation:group_concat( [distinct] Champs à connecter [order by Trier les champs asc/desc ] [separator ‘Séparateur’] )

Vous pouvez voir qu'il y a des paramètres optionnels , Vous pouvez dupliquer les valeurs des champs à assembler , Vous pouvez aussi trier ,Spécifiez le séparateur. Si non spécifié , Par défaut séparé par des virgules .

Pour dept Tableau, On peut mettre tous les id Joins - les par des virgules .( Il n'est pas utilisé ici group by Champs groupés , On peut considérer qu'il n'y a qu'un seul groupe de )

MySQL Fonction personnalisée, Implémenter une requête récursive

Vous pouvez trouver que les problèmes ci - dessus ont été résolus avec les chaînes d'épissage .Alors, La question est de savoir comment construire une chaîne avec une relation récursive .

Nous pouvons personnaliser une fonction , Via le noeud racine entrant id, Trouve tous ses noeuds enfants .

Prenons l'exemple de la récursion vers le bas .?( Tout en expliquant comment écrire une fonction personnalisée , Expliquer la logique récursive )

delimiter $$
drop function if exists get_child_list$$
create function get_child_list(in_id varchar(10)) returns varchar(1000)
begin
declare ids varchar(1000) default '';
declare tempids varchar(1000);
set tempids = in_id;
while tempids is not null do
set ids = CONCAT_WS(',',ids,tempids);
select GROUP_CONCAT(id) into tempids from dept where FIND_IN_SET(pid,tempids)>0;
end while;
return ids;
end
$$
delimiter ;

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

(1) delimiter$$, Utilisé pour définir le caractère final .Nous savons que MySQL Le caractère de fin par défaut est un point - virgule , Indique que l'instruction est terminée et exécutée . Mais dans le corps de la fonction , Parfois, nous voulons rencontrer un point - virgule qui ne se termine pas , Il est donc nécessaire de changer temporairement le caractère de fin en une autre valeur arbitraire . Je mets ça ici pour $$, Ça veut dire rencontrer $$ C'est fini , Et exécuter l'instruction courante .

(2)drop function if exists get_child_list$$ . Si la fonction get_child_list Il existe déjà , Supprimer d'abord . Attention, il faut Fermeture personnalisée actuelle $$ Pour terminer et exécuter l'instruction . Parce que, Ceci doit être séparé du corps de la fonction en dessous .

(3)create function get_child_list Créer une fonction . Et le paramètre passe dans le noeud enfant d'un noeud racine id, Il est important de noter que le type et la longueur des paramètres doivent être indiqués , Comme ici varchar(10).returns varchar(1000) Utilisé pour définir le type de paramètre de valeur de retour .

(4)begin Et end Au milieu se trouve le corps de la fonction . Pour écrire une logique concrète .

(5)declare Utilisé pour déclarer les variables , Et peut être utilisé default Définir les valeurs par défaut.

Défini ici ids Est la valeur de retour de la fonction entière , Est utilisé pour assembler les chaînes récursives séparées par des virgules dont nous avons finalement besoin .

Et tempids C'est pour enregistrer le côté while Chaîne concaténée par des virgules pour tous les noeuds enfants générés temporairement dans la boucle .

(6) set Utilisé pour attribuer une valeur à une variable . Le noeud racine entrant est assigné ici à tempids .

(7) while do … end while; Déclaration circulaire, La logique circulaire est incluse .Attention!,end while Un point - virgule doit être ajouté à la fin .

Dans le corps circulant ,D'abord. CONCAT_WS La fonction met le résultat final ids Et Produit temporairement tempids Joins - les avec des virgules .

Et puis avec FIND_IN_SET(pid,tempids)>0 À condition que , Traverser dans tempids Tous dans pid , Trouvez tous les noeuds enfants avec ce noeud parent id ,Et à travers GROUP_CONCAT(id) into tempids Mettez ces noeuds enfants id Tout est assemblé par des virgules , Et écraser les mises à jour tempids .

Attends la prochaine fois que ça arrive , Et ils vont se recoudre ids , Et trouver à nouveau tous les noeuds enfants de tous les noeuds enfants .En boucle, Traversée récursive vers le bas des noeuds enfants d'une couche à l'autre . Jusqu'à ce que le jugement tempids Vide, Indique que tous les noeuds enfants ont été traversés , C'est la fin du cycle. .

Ici.,Avec ‘1000’ Prenons un exemple.,C'est - à - dire:( Voir fig 1 Relations de données de table pour )

 Premier cycle :
tempids=1000 ids=1000 tempids=1001,1002 (1000 Tous les noeuds enfants de )
Deuxième cycle :
tempids=1001,1002 ids=1000,1001,1002 tempids=1003,1004,1005,1013 (1001Et1002 Tous les noeuds enfants de )
Troisième cycle :
tempids=1003,1004,1005,1013
ids=1000,1001,1002,1003,1004,1005,1013
tempids=1003Et1004Et1005Et1013 Tous les noeuds enfants de
...
Dernier cycle , Parce que le noeud enfant n'a pas pu être trouvé ,tempids=null, C'est la fin du cycle .

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

(8)return ids; Pour mettre ids Renvoie comme valeur de retour de fonction .

(9) Après la fin du corps de la fonction , N'oubliez pas d'utiliser la fin $$ Pour mettre fin à toute cette logique ,Et la mise en œuvre.

(10) Et n'oublie pas , .Réinitialiser le caractère de fin au point - virgule de fin par défaut .

Une fois la fonction personnalisée terminée , Nous pouvons l'utiliser pour interroger Récursivement les données dont nous avons besoin .Par exemple:, J'ai demandé à tous les noeuds du Département de recherche et développement de Pékin .

Ce qui précède est une requête récursive vers le bas pour tous les noeuds enfants , Et inclut le noeud actuel , Vous pouvez également modifier la logique pour ne pas inclure le noeud actuel , Je ne vais pas faire de démonstration .

Mise en œuvre manuelle des requêtes récursives ( Récursive vers le haut )

Par rapport à la descente , La récursion vers le haut est plus simple .

Parce qu'en descendant Récursivement , Chaque couche récursive un noeud parent correspond à plusieurs noeuds enfants .

Et Récursivement vers le haut , Un noeud enfant récursif par couche ne correspond qu'à un noeud parent , La relation est relativement simple .

La même chose., On peut définir une fonction get_parent_list Pour obtenir tous les noeuds parents du noeud racine .

delimiter $$
drop function if exists get_parent_list$$
create function get_parent_list(in_id varchar(10)) returns varchar(1000)
begin
declare ids varchar(1000);
declare tempid varchar(10);
set tempid = in_id;
while tempid is not null do
set ids = CONCAT_WS(',',ids,tempid);
select pid into tempid from dept where id=tempid;
end while;
return ids;
end
$$
delimiter ;

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

Trouvez l'équipe 1 du Département de recherche et développement de Pékin , Et son parent récursif ,Comme suit:

Notes

On a utilisé group_concat Fonction pour assembler les chaînes .Mais, Notez qu'il y a une limite de longueur ,Par défaut 1024 Octets.Peut passer?show variables like "group_concat_max_len";?Pour voir.

Attention!,En octets, Ce n'est pas un caractère .In MySQL Moyenne, Les lettres individuelles occupent 1Octets, Et ce que nous utilisons habituellement utf-8En bas., Un caractère chinois occupe 3Octets.

C'est très mortel pour les requêtes récursives . Parce que les mots récursifs , La hiérarchie des relations est assez profonde , Il y a de fortes chances que la longueur maximale soit dépassée .( Bien qu'en général les épis soient des chaînes numériques , Un seul octet )

Alors..., Nous avons deux façons de résoudre ce problème :

  1. Modifier MySQL Profil my.cnf ,Ajouter?group_concat_max_len = 102400 # La longueur maximale que vous voulez ?.

  2. Exécutez l'une des déclarations suivantes .SET GLOBAL group_concat_max_len=102400;?Ou?SET SESSION group_concat_max_len=102400;

    La différence, c'est que ,global C'est global , Toute ouverture d'une nouvelle session prend effet ,Mais attention., La session en cours qui est déjà ouverte ne prend pas effet .Et session Oui n'entrera en vigueur que pour la session en cours , Les autres sessions ne sont pas valides .

    Le dénominateur commun est , Ils seront tous là MySQL Échec après redémarrage , Sous réserve de la configuration dans le fichier de configuration .Alors..., Il est recommandé de modifier directement le profil .102400 Est généralement assez long pour .Supposons qu'unidLa longueur de10Octets, Peut aussi épeler 10 000 idC'est.

En plus de ça,,Utiliser group_concat La fonction a aussi une limite , Ne peut pas être utilisé en même temps limit .Par exemple:,

Enfin

Je l'ai déjà dit.spring cloud alibaba,Pour toute l'architecture des microservices,Si vous voulez vous améliorer davantage,Quelles sont exactement les compétences de base à acquérir?

Pour les particuliers,Pour l'ensemble de l'architecture des microservices,CommeRPC、Dubbo、Spring Boot、Spring Cloud Alibaba、Docker、kubernetes、Spring Cloud Netflix、Service MeshCe sont les connaissances les plus fondamentales.,Un architecte doit passer!Ci - dessous,Est un schéma d'itinéraire auto - dessiné de l'architecture des microservices,Si vous avez des amis qui ne savent pas encore quelles compétences vous devriez maîtriser,Une référence peut être faite à partir d'un petit plan dessiné à la main.

image

Si l'image n'est pas assez claire,Vous pouvez également trouver un petit rédacteur pour partager l'originalxmindDocumentation!

Et en plus de ce schéma de système de micro - services,J'ai aussi les notes d'apprentissage les plus fortes correspondant à chaque point de connaissance de base du sujet:

  • C'est incroyable.——SpringCloudAlibaba.pdf

  • SpringCloudNotes sur l'architecture des microservices(Un.).pdf

  • SpringCloudNotes sur l'architecture des microservices(2.).pdf

  • SpringCloudNotes sur l'architecture des microservices(Trois).pdf

  • SpringCloudNotes sur l'architecture des microservices(Quatre).pdf

  • DubboCadreRPCPrincipe de réalisation.pdf

  • DubboDernière interprétation complète et approfondie.pdf

  • Spring BootCours d'apprentissage.pdf

  • SpringBooÉcriture de base.pdf

  • Premier livreDockerLes livres-Version complète.pdf

  • UtiliserSpringCloudEtDockerMicroservice opérationnel.pdf

  • K8S(kubernetes)Guide d'apprentissage.pdf

Veuillez télécharger** Cliquez sur le portail:《C'est incroyable.——SpringCloudAlibaba》**

image

En plus,Si vous ne savez pas par où commencer à apprendre,Il y a aussi des points de connaissance de base pour chaque micro - service qui dessinent à la main les grandes lignes de son architecture de connaissances,Mais tout est exporté.xmindDocumentation,Tous les fichiers sources sont ici aussi,De même, il peut être partagé gratuitement avec vous dans le besoin!

image

Copyright:Cet article est[Reste debout toute la nuit.]Établi,Veuillez apporter le lien original pour réimprimer,remercier。 https://fra.fheadline.com/2021/08/20210820000237308K.html