GUID/UUID/MD5/SHA1 sont tous hex et tiret. Pour les
CHAR(..) CHARACTER SET ascii COLLATE ascii_general_ci
Cela permettra A
= a
lorsque l'on compare les chaînes hexagonales.
Pour les choses base64, utilisez l'une des
CHAR(..) CHARACTER SET ascii COLLATE ascii_bin
BINARY(..)
depuis A
est pas sémantiquement la même chose que a
.
Notes complémentaires ...
- UTF8 crache dessus si vous donnez une valeur de 8 bits non valide. Ascii crache sur vous pour toute valeur de 8 bits.
- Latin1 accepte n'importe quoi - ainsi vos problèmes sur la route
- Il est tout à fait correct d'avoir différentes colonnes dans une table ayant des charsets et/ou des collations différents.
- Le jeu de caractères/classement sur la table est juste un par défaut, qui peut être remplacé par la définition de colonne.
BINARY
peut être un peu plus rapide que n'importe quel _bin
classement, mais pas assez pour remarquer.
- Utilisez
CHAR
pour les colonnes dont la longueur est réellement fixe; n'induisez pas l'utilisateur en erreur en l'utilisant pour d'autres cas.
%_bin
est plus rapide que %_general_ci
, ce qui est plus rapide que d'autres classements.Encore une fois, vous auriez du mal à mesurer une différence.
- N'utilisez jamais
TINYTEXT
ou TINYBLOB
.
- Pour un codage correct, utilisez le jeu de caractères approprié.
- Pour un "tri correct", utilisez le classement approprié. Voir l'exemple ci-dessous.
- Pour un «tri correct» lorsque plusieurs langues sont représentées et que vous utilisez,, utilisez
utf8mb4_unicode_520_ci
(ou utf8mb4_900_ci
si vous utilisez la version 8.0). Les 520 et 900 se réfèrent aux normes Unicode; de nouvelles collations sont susceptibles de venir dans le futur.
Si vous êtes entièrement en tchèque, considérez ces charsets et collations. Je leur liste dans l'ordre préféré:
mysql> show collation like '%czech%';
+------------------+---------+-----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+------------------+---------+-----+---------+----------+---------+
| utf8mb4_czech_ci | utf8mb4 | 234 | | Yes | 8 | -- opens up the world
| utf8_czech_ci | utf8 | 202 | | Yes | 8 | -- opens up most of the world
| latin2_czech_cs | latin2 | 2 | | Yes | 4 | -- kinda like latin1
Les autres sont "inutiles":
| cp1250_czech_cs | cp1250 | 34 | | Yes | 2 |
| ucs2_czech_ci | ucs2 | 138 | | Yes | 8 |
| utf16_czech_ci | utf16 | 111 | | Yes | 8 |
| utf32_czech_ci | utf32 | 170 | | Yes | 8 |
+------------------+---------+-----+---------+----------+---------+
7 rows in set (0.00 sec)
Plus
- La raison d'utiliser des types de données plus petits (le cas échéant) est de réduire l'ensemble de données, ce qui conduit à moins d'E/S, ce qui conduit à des choses plus susceptibles d'être mises en cache, ce qui accélère le fonctionnement du programme. Ceci est particulièrement important pour les grands ensembles de données; il est moins important pour les ensembles de données de petite ou moyenne taille.
ENUM
est 1 octet, mais agit comme une chaîne. Donc, vous obtenez le "meilleur des deux mondes". (Il y a des inconvénients, et il y a une «guerre religieuse» entre les défenseurs ENUM
vs TINYINT
vs VARCHAR
.)
- Habituellement, les colonnes qui sont «courtes» ont toujours la même longueur. Un
country_code
est toujours 2 lettres, toujours ascii, pourrait toujours bénéficier de la collation insensible à la casse. Donc CHAR(2) CHARACTER SET ascii COLLATE ascii_general_ci
est optimal. Si vous avez quelque chose qui est parfois 1-char, parfois 2, alors lancez une pièce; quoi que vous fassiez ne fera pas beaucoup de différence.
VARCHAR
(jusqu'à 255) a une longueur supplémentaire de 1 octet qui lui est attachée. Donc, si vos chaînes varient en longueur tout, VARCHAR
est au moins aussi bon que CHAR
. Alors simplifiez le traitement de votre cerveau: "longueur variable ->` VARCHAR ".
BIT
, selon la version, peut être implémenté sous la forme d'un octet TINYINT UNSIGNED
. Si vous n'avez que quelques bits dans votre table, cela ne vaut pas la peine de vous inquiéter.
- Un de mes Rules of Thumb dit que si vous n'obtenez pas une amélioration de 10%, passez à une autre optimisation. Une grande partie de ce dont nous parlons ici est inférieure à 10% (espace dans ce cas). Toujours, prenez l'habitude d'y penser en écrivant
CREATE TABLE
. Je vois souvent des tables avec BIGINT
et DOUBLE
(chaque 8 octets) qui pourraient facilement utiliser des colonnes plus petites. Parfois, en économisant plus de 50% (espace).
- Comment "espace" se traduit par "vitesse". Tables minuscules -> un pourcentage minuscule. Tables énormes -> Dans certains cas 10x. (C'est 10 fois, et non 10%.) (UUID sont un moyen d'obtenir des performances vraiment mauvais sur les tables énormes.)
ENUM
- actes et se sent comme une chaîne, mais prend seulement un octet.(Un octet se traduit indirectement par une légère amélioration de la vitesse.)
- Pratique quand moins de, disons, 10 valeurs différentes.
- Impossible d'ajouter une nouvelle valeur - nécessite
ALTER TABLE
, même si peut être être "inplace".
- Suggérer le début de la liste avec
'unknown'
(ou quelque chose comme ça) et en faisant la colonne NOT NULL
(contre NULL
).
- Le jeu de caractères de l'énumération doit être celui qui est utilisé pour la connexion. Le choix n'a pas beaucoup d'importance sauf si vous avez des options assembler égal (par exemple,
A
par rapport à a
).
UTF-8 utilise seulement plus d'un octet si le caractère est en dehors de la plage ASCII. Les UUID stringifiés (si c'est ce que vous utilisez comme GUID) tombent toujours dans cette plage. – robertklep
@robertklep J'ai entendu cela et cela a du sens, mais je pense que cela ne s'applique pas à l'index (consommation d'espace) !? Par exemple, un 'EXPLAIN SELECT' montre une valeur de' key_len' 2/3 plus petite lors de la conversion de la colonne utf8 en latin1 – toshniba
Ah, je n'en ai pas tenu compte (je ne sais pas comment les index MySQL/InnoDB sont implémentés). – robertklep