Quel est le meilleur classement à utiliser pour MySQL avec PHP? [fermé]


731

Je me demande s'il y a un "meilleur" choix pour l'assemblage dans MySQL pour un site Web général où vous n'êtes pas sûr à 100% de ce qui sera entré? Je comprends que tous les encodages doivent être les mêmes, tels que MySQL, Apache, le HTML et tout ce qui se trouve à l'intérieur de PHP.

Dans le passé, j'ai configuré PHP pour qu'il sorte en "UTF-8", mais à quel classement cela correspond-il dans MySQL? Je pense qu'il est l' un des caractères UTF-8 ceux, mais je l' ai utilisé utf8_unicode_ci, utf8_general_ciet utf8_binavant.


35
Remarque: "utf8" de MySQL n'est pas le bon UTF-8 (pas de support pour les caractères Unicode de 4 octets comme 𝌆), mais "utf8mb4" l'est. Avec utf8, un champ sera tronqué lors de l'insertion en commençant par le premier caractère Unicode non pris en charge. mathiasbynens.be/notes/mysql-utf8mb4
basic6

6
Je me demande si nous aurons besoin de 5 octets pour tous ces emojis ... soupir
Álvaro González

1
Question connexe: stackoverflow.com/questions/38228335/… "Quel classement MySQL correspond exactement à la comparaison de chaînes de PHP?"
William Entriken

Pour un aperçu des options sensées
Flux

Réponses:


618

La principale différence est la précision du tri (lors de la comparaison des caractères dans la langue) et les performances. Le seul spécial est utf8_bin qui sert à comparer les caractères au format binaire.

utf8_general_ciest un peu plus rapide que utf8_unicode_ci, mais moins précis (pour le tri). Le codage de langue spécifique utf8 (tel que utf8_swedish_ci) contient des règles de langue supplémentaires qui les rendent les plus précises à trier pour ces langues. La plupart du temps, j'utilise utf8_unicode_ci(je préfère la précision aux petites améliorations de performances), sauf si j'ai une bonne raison de préférer une langue spécifique.

Vous pouvez en savoir plus sur des jeux de caractères Unicode spécifiques dans le manuel MySQL - http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html


4
petites améliorations de performances? es-tu sûr de ça ? publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=/… Le classement que vous choisissez peut avoir un impact significatif sur les performances des requêtes dans la base de données.
Adam Ramadhan

62
C'est pour DB2 et non pour MySQL. De plus, il n'y a pas de chiffres ou de repères concrets, vous vous basez donc simplement sur l'opinion de l'écrivain.
Eran Galperin

3
Notez que si vous souhaitez utiliser des fonctions, il y a un bogue dans MySQL (les versions les plus distribuées actuellement) où les fonctions renvoient toujours la chaîne en utilisant utf8_general_ci, causant des problèmes si vous utilisez un autre classement pour vos chaînes - voir bugs.mysql.com/ bug.php? id = 24690
El Yobo

1
D'après mon expérience avec différents endroits que j'utiliserais toujoursutf8_unicode_*
Shiplu Mokaddim

11
Mise à jour: pour les versions plus récentes, recommandez utf8mb4et utf8mb4_unicode_520_ci. Ceux-ci vous donnent le reste du chinois, ainsi qu'un classement amélioré.
Rick James

129

En fait, vous voudrez probablement utiliser utf8_unicode_ciou utf8_general_ci.

  • utf8_general_ci trie en supprimant tous les accents et en les triant comme si c'était ASCII
  • utf8_unicode_ci utilise l'ordre de tri Unicode, donc il trie correctement dans plus de langues

Cependant, si vous ne l'utilisez que pour stocker du texte anglais, cela ne devrait pas différer.


1
J'aime ton explication! Bon. Mais j'ai besoin de mieux comprendre exactement pourquoi l'ordre de tri unicode est un meilleur moyen de trier correctement que de supprimer les accents.
weia design

14
@Adam Cela dépend vraiment de votre public cible. Le tri est un problème délicat à localiser correctement. Par exemple, en norvégien, les lettres Æ Ø Å sont les 3 derniers de l'alphabet. Avec utf8_general_ci, Ø et Å sont convertis en O et A, ce qui les place dans une position complètement incorrecte lorsqu'ils sont triés (je ne sais pas comment Æ est géré, car il s'agit d'une ligature, pas d'un caractère accentué). Cet ordre de tri est différent dans presque toutes les langues, par exemple le norvégien et le suédois ont des ordres différents (et des lettres légèrement différentes qui sont considérées comme égales): Æ Ø Å est trié Å Æ Ø (les lettres réelles sont Å Ä Ö). Unicode corrige cela.
Vegard Larsen

Donc, ce que je dis essentiellement, c'est que vous devriez probablement utiliser un tri spécifique à la langue si vous le pouvez, mais dans la plupart des cas, cela est impossible, alors optez pour le tri général Unicode. Ce sera toujours étrange dans certaines langues, mais plus correct qu'en ASCII.
Vegard Larsen

3
@Manatax - avec l'un des classements utf8_, les données sont stockées sous le nom utf8. La collation concerne à peu près quels personnages sont considérés comme égaux et comment ils sont ordonnés.
frymaster

2
@frymaster - pas vrai, selon: mathiasbynens.be/notes/mysql-utf8mb4 "L'utf8 de MySQL ne vous permet de stocker que 5,88% de tous les points de code Unicode possibles"
données

120

Soyez très, très conscient de ce problème qui peut survenir lors de l'utilisation utf8_general_ci.

MySQL ne fera pas de distinction entre certains caractères dans les instructions select, si le utf8_general_ciclassement est utilisé. Cela peut conduire à des bugs très désagréables - en particulier par exemple, lorsque les noms d'utilisateur sont impliqués. Selon l'implémentation qui utilise les tables de base de données, ce problème peut permettre à des utilisateurs malveillants de créer un nom d'utilisateur correspondant à un compte administrateur.

Ce problème s'expose au moins dans les premières versions 5.x - je ne sais pas si ce comportement a changé plus tard.

Je ne suis pas un administrateur de base de données, mais pour éviter ce problème, j'y vais toujours au utf8-binlieu d'un insensible à la casse.

Le script ci-dessous décrit le problème par l'exemple.

-- first, create a sandbox to play in
CREATE DATABASE `sandbox`;
use `sandbox`;

-- next, make sure that your client connection is of the same 
-- character/collate type as the one we're going to test next:
charset utf8 collate utf8_general_ci

-- now, create the table and fill it with values
CREATE TABLE `test` (`key` VARCHAR(16), `value` VARCHAR(16) )
    CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO `test` VALUES ('Key ONE', 'value'), ('Key TWO', 'valúe');

-- (verify)
SELECT * FROM `test`;

-- now, expose the problem/bug:
SELECT * FROM test WHERE `value` = 'value';

--
-- Note that we get BOTH keys here! MySQLs UTF8 collates that are 
-- case insensitive (ending with _ci) do not distinguish between 
-- both values!
--
-- collate 'utf8_bin' doesn't have this problem, as I'll show next:
--

-- first, reset the client connection charset/collate type
charset utf8 collate utf8_bin

-- next, convert the values that we've previously inserted in the table
ALTER TABLE `test` CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;

-- now, re-check for the bug
SELECT * FROM test WHERE `value` = 'value';

--
-- Note that we get just one key now, as you'd expect.
--
-- This problem appears to be specific to utf8. Next, I'll try to 
-- do the same with the 'latin1' charset:
--

-- first, reset the client connection charset/collate type
charset latin1 collate latin1_general_ci

-- next, convert the values that we've previously inserted
-- in the table
ALTER TABLE `test` CONVERT TO CHARACTER SET latin1 COLLATE latin1_general_ci;

-- now, re-check for the bug
SELECT * FROM test WHERE `value` = 'value';

--
-- Again, only one key is returned (expected). This shows 
-- that the problem with utf8/utf8_generic_ci isn't present 
-- in latin1/latin1_general_ci
--
-- To complete the example, I'll check with the binary collate
-- of latin1 as well:

-- first, reset the client connection charset/collate type
charset latin1 collate latin1_bin

-- next, convert the values that we've previously inserted in the table
ALTER TABLE `test` CONVERT TO CHARACTER SET latin1 COLLATE latin1_bin;

-- now, re-check for the bug
SELECT * FROM test WHERE `value` = 'value';

--
-- Again, only one key is returned (expected).
--
-- Finally, I'll re-introduce the problem in the exact same 
-- way (for any sceptics out there):

-- first, reset the client connection charset/collate type
charset utf8 collate utf8_generic_ci

-- next, convert the values that we've previously inserted in the table
ALTER TABLE `test` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

-- now, re-check for the problem/bug
SELECT * FROM test WHERE `value` = 'value';

--
-- Two keys.
--

DROP DATABASE sandbox;

36
-1: Ceci est sûrement résolu en appliquant une clé unique à la colonne appropriée. Vous verriez le même comportement si les deux valeurs étaient 'value'et 'valUe'. L'intérêt d'un classement est qu'il fournit des règles (entre autres) lorsque deux chaînes sont considérées comme égales l'une à l'autre.
Hammerite

13
C'est exactement le problème que j'essaie d'illustrer - le classement rend deux choses égales alors qu'elles ne sont en fait pas censées être égales du tout (et donc, une contrainte unique est exactement l'opposé de ce que vous voudriez atteindre)
Guus

18
Mais vous le décrivez comme un "problème" et conduisant à des "bogues" lorsque le comportement est exactement ce qu'un classement est destiné à atteindre. Votre description est correcte, mais seulement dans la mesure où il s'agit d'une erreur de la part du DBA pour sélectionner un classement inapproprié.
Hammerite

32
Le fait est que, lorsque vous entrez deux noms d'utilisateur qui sont considérés comme égaux par le classement, cela ne sera pas autorisé si vous définissez le nom d'utilisateur coloumn comme unique, ce que vous devez bien sûr faire!
Élève de Poudlard

12
J'ai surévalué à la fois cette réponse et le commentaire de @ Hammerite, car les deux combinés m'ont aidé à comprendre la collation.
Nacht - Rétablir Monica

86

Il est préférable d'utiliser le jeu de caractères utf8mb4avec le classement utf8mb4_unicode_ci.

Le jeu de caractères utf8, ne prend en charge qu'une petite quantité de points de code UTF-8, soit environ 6% des caractères possibles. utf8prend uniquement en charge le plan multilingue de base (BMP). Il y a 16 autres avions. Chaque avion contient 65 536 caractères. utf8mb4prend en charge les 17 avions.

MySQL tronquera les caractères UTF-8 de 4 octets résultant en des données corrompues.

Le utf8mb4jeu de caractères a été introduit dans MySQL 5.5.3 le 24/03/2010.

Certaines des modifications requises pour utiliser le nouveau jeu de caractères ne sont pas anodines:

  • Des modifications peuvent devoir être apportées à votre adaptateur de base de données d'application.
  • Des modifications devront être apportées à my.cnf, y compris la définition du jeu de caractères, le classement et le passage de innodb_file_format à Barracuda
  • Les instructions SQL CREATE peuvent devoir inclure: ROW_FORMAT=DYNAMIC
    • DYNAMIC est requis pour les index sur VARCHAR (192) et plus.

REMARQUE: le passage à Barracudade Antelopepeut nécessiter le redémarrage du service MySQL plusieurs fois. innodb_file_format_maxne change pas avant le service MySQL a été redémarré à: innodb_file_format = barracuda.

MySQL utilise l'ancien Antelopeformat de fichier InnoDB. Barracudaprend en charge les formats de ligne dynamiques, dont vous aurez besoin si vous ne voulez pas frapper les erreurs SQL pour créer des index et des clés après avoir basculé sur le jeu de caractères:utf8mb4

  • # 1709 - La taille de la colonne d'index est trop grande. La taille de colonne maximale est de 767 octets.
  • # 1071 - La clé spécifiée était trop longue; la longueur de clé maximale est de 767 octets

Le scénario suivant a été testé sur MySQL 5.6.17: Par défaut, MySQL est configuré comme ceci:

SHOW VARIABLES;

innodb_large_prefix = OFF
innodb_file_format = Antelope

Arrêtez votre service MySQL et ajoutez les options à votre my.cnf existant:

[client]
default-character-set= utf8mb4

[mysqld]
explicit_defaults_for_timestamp = true
innodb_large_prefix = true
innodb_file_format = barracuda
innodb_file_format_max = barracuda
innodb_file_per_table = true

# Character collation
character_set_server=utf8mb4
collation_server=utf8mb4_unicode_ci

Exemple d'instruction SQL CREATE:

CREATE TABLE Contacts (
 id INT AUTO_INCREMENT NOT NULL,
 ownerId INT DEFAULT NULL,
 created timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 contact VARCHAR(640) NOT NULL,
 prefix VARCHAR(128) NOT NULL,
 first VARCHAR(128) NOT NULL,
 middle VARCHAR(128) NOT NULL,
 last VARCHAR(128) NOT NULL,
 suffix VARCHAR(128) NOT NULL,
 notes MEDIUMTEXT NOT NULL,
 INDEX IDX_CA367725E05EFD25 (ownerId),
 INDEX created (created),
 INDEX modified_idx (modified),
 INDEX contact_idx (contact),
 PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB ROW_FORMAT=DYNAMIC;
  • Vous pouvez voir l'erreur # 1709 générée pour INDEX contact_idx (contact)si ROW_FORMAT=DYNAMICest supprimée de l'instruction CREATE.

REMARQUE: la modification de l'index pour limiter aux 128 premiers caractères sur contactélimine la nécessité d'utiliser Barracuda avecROW_FORMAT=DYNAMIC

INDEX contact_idx (contact(128)),

Notez également: quand il est dit que la taille du champ est de VARCHAR(128)128 octets. Vous pouvez utiliser 128 caractères de 4 octets ou 128 caractères de 1 octet.

Cette INSERTinstruction doit contenir le caractère «poo» de 4 octets sur la ligne 2:

INSERT INTO `Contacts` (`id`, `ownerId`, `created`, `modified`, `contact`, `prefix`, `first`, `middle`, `last`, `suffix`, `notes`) VALUES
(1, NULL, '0000-00-00 00:00:00', '2014-08-25 03:00:36', '1234567890', '12345678901234567890', '1234567890123456789012345678901234567890', '1234567890123456789012345678901234567890', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678', '', ''),
(2, NULL, '0000-00-00 00:00:00', '2014-08-25 03:05:57', 'poo', '12345678901234567890', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', ''),
(3, NULL, '0000-00-00 00:00:00', '2014-08-25 03:05:57', 'poo', '12345678901234567890', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '123💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');

Vous pouvez voir la quantité d'espace utilisée par la lastcolonne:

mysql> SELECT BIT_LENGTH(`last`), CHAR_LENGTH(`last`) FROM `Contacts`;
+--------------------+---------------------+
| BIT_LENGTH(`last`) | CHAR_LENGTH(`last`) |
+--------------------+---------------------+
|               1024 |                 128 | -- All characters are ASCII
|               4096 |                 128 | -- All characters are 4 bytes
|               4024 |                 128 | -- 3 characters are ASCII, 125 are 4 bytes
+--------------------+---------------------+

Dans votre adaptateur de base de données, vous souhaiterez peut-être définir le jeu de caractères et le classement pour votre connexion:

SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'

En PHP, cela serait défini pour: \PDO::MYSQL_ATTR_INIT_COMMAND

Références:




6
utf8mb4_unicode_ci devrait absolument être le classement recommandé pour les nouveaux projets en 2015.
Trevor Gehman

7
Mettre à jour ... utf8mb4_unicode_520_cic'est mieux. À l'avenir, il y en aura utf8mb4_unicode_800_ci(ou quelque chose comme ça), car MySQL rattrapera les normes Unicode.
Rick James

46

Les classements affectent la façon dont les données sont triées et la façon dont les chaînes sont comparées les unes aux autres. Cela signifie que vous devez utiliser le classement attendu par la plupart de vos utilisateurs.

Exemple tiré de la documentation de charset unicode :

utf8_general_ciest également satisfaisant pour l'allemand et le français, sauf que «ß» est égal à «s» et non à «ss». Si cela est acceptable pour votre application, vous devez l'utiliser utf8_general_cicar c'est plus rapide. Sinon, utilisez-le utf8_unicode_cicar il est plus précis.

Donc - cela dépend de votre base d'utilisateurs attendus et de combien vous avez besoin d' un tri correct . Pour une base d'utilisateurs en anglais, cela utf8_general_cidevrait suffire, pour d'autres langues, comme le suédois, des classements spéciaux ont été créés.


1
J'utilisais utf8_general_ci et il a fallu quelques secondes lors du tri et armscii_general_ci fait extrêmement quick.Why cela est arrivé une question, Que pensez - vous que la collation est utilisé par les sites de réseaux sociaux?

22

Essentiellement, cela dépend de la façon dont vous pensez d'une chaîne.

J'utilise toujours utf8_bin à cause du problème mis en évidence par Guus. À mon avis, en ce qui concerne la base de données, une chaîne n'est encore qu'une chaîne. Une chaîne est un nombre de caractères UTF-8. Un personnage a une représentation binaire, alors pourquoi a-t-il besoin de connaître la langue que vous utilisez? Habituellement, les gens construiront des bases de données pour des systèmes ayant la portée de sites multilingues. C'est tout l'intérêt d'utiliser UTF-8 comme jeu de caractères. Je suis un peu puriste, mais je pense que les risques de bogues l'emportent largement sur le léger avantage que vous pouvez obtenir sur l'indexation. Toutes les règles liées au langage doivent être effectuées à un niveau beaucoup plus élevé que le SGBD.

Dans mes livres, la «valeur» ne devrait jamais, dans un million d'années, être égale à la «valúe».

Si je veux stocker un champ de texte et faire une recherche insensible à la casse, j'utiliserai des fonctions de chaîne MYSQL avec des fonctions PHP telles que LOWER () et la fonction php strtolower ().


9
Si la comparaison binaire des chaînes est votre comparaison souhaitée, vous devez bien sûr utiliser le classement binaire; mais rejeter les classements alternatifs comme un "risque de bogue" ou simplement pour des raisons d'indexation suggère que vous ne comprenez pas complètement le but d'un classement.
Hammerite

13

Pour les informations textuelles UTF-8, vous devez utiliser utf8_general_cicar ...

  • utf8_bin: comparer les chaînes par la valeur binaire de chaque caractère de la chaîne

  • utf8_general_ci: comparer des chaînes en utilisant des règles de langage générales et en utilisant des comparaisons insensibles à la casse

alias cela devrait rendre la recherche et l'indexation des données plus rapides / plus efficaces / plus utiles.


12

La réponse acceptée suggère assez définitivement d'utiliser utf8_unicode_ci, et bien que pour de nouveaux projets c'est génial, je voulais raconter ma récente expérience contraire au cas où cela ferait gagner du temps à quelqu'un.

Parce que utf8_general_ci est le classement par défaut pour Unicode dans MySQL, si vous souhaitez utiliser utf8_unicode_ci, vous finissez par devoir le spécifier à de nombreux endroits.

Par exemple, toutes les connexions client ont non seulement un jeu de caractères par défaut (c'est logique pour moi) mais aussi un classement par défaut (c'est-à-dire que le classement sera toujours par défaut utf8_general_ci pour unicode).

Probablement, si vous utilisez utf8_unicode_ci pour vos champs, vos scripts qui se connectent à la base de données devront être mis à jour pour mentionner explicitement le classement souhaité - sinon les requêtes utilisant des chaînes de texte peuvent échouer lorsque votre connexion utilise le classement par défaut.

Le résultat est que lors de la conversion d'un système existant de n'importe quelle taille en Unicode / utf8, vous pouvez finir par être obligé d'utiliser utf8_general_ci en raison de la façon dont MySQL gère les valeurs par défaut.


8

Pour le cas mis en évidence par Guus, je suggérerais fortement d'utiliser soit utf8_unicode_cs (sensible à la casse, correspondance stricte, ordre correct pour la plupart) au lieu de utf8_bin (correspondance stricte, ordre incorrect).

Si le champ est destiné à être recherché, par opposition à une correspondance pour un utilisateur, utilisez alors utf8_general_ci ou utf8_unicode_ci. Les deux sont insensibles à la casse, l'un correspondra à tort («ß» est égal à «s» et non à «ss»). Il existe également des versions spécifiques à la langue, comme utf8_german_ci, où la perte de correspondance est plus adaptée à la langue spécifiée.

[Modifier - près de 6 ans plus tard]

Je ne recommande plus le jeu de caractères "utf8" sur MySQL, et je recommande plutôt le jeu de caractères "utf8mb4". Ils correspondent presque entièrement, mais permettent un peu (beaucoup) plus de caractères Unicode.

De manière réaliste, MySQL aurait dû mettre à jour le jeu de caractères "utf8" et les classements respectifs pour correspondre à la spécification "utf8", mais à la place, un jeu de caractères séparé et des classements respectifs pour ne pas affecter la désignation de stockage pour ceux qui utilisent déjà leur jeu de caractères "utf8" incomplet .


5
FYI: utf8_unicode_csn'existe pas. Le seul utf8 sensible à la casse est utf8_bin. Le problème est que le utf8_bintri est incorrect. Voir: stackoverflow.com/questions/15218077/…
Costa

1
Merci d'avoir mis à jour!
Prométhée


2

Dans votre fichier de téléchargement de base de données, ajoutez la ligne de suivi avant toute ligne:

SET NAMES utf8;

Et votre problème devrait être résolu.


2
Lire une question: dans le passé, j'ai configuré PHP pour qu'il sorte en "UTF-8", mais à quel classement cela correspond-il dans MySQL? Je pense que c'est l'un des UTF-8, mais j'ai déjà utilisé utf8_unicode_ci, utf8_general_ci et utf8_bin.
Jitesh Sojitra

5
Cette réponse n'a rien à voir avec la question. De plus, l'émission SET NAMESdirecte d' une requête ne permet pas au client de connaître l'encodage et peut briser certaines fonctionnalités telles que les instructions préparées de manière très subtile.
Álvaro González
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.