Maison > base de données > tutoriel mysql > le corps du texte

Test d'instance de type enum MySQL

小云云
Libérer: 2017-11-30 11:05:37
original
1549 Les gens l'ont consulté

Qu'est-ce qu'une énumération ? enum est l'abréviation de Mappage d'URI de numéro E.164. Derrière cette abréviation se cache une idée géniale : la possibilité d'utiliser le même numéro de téléphone partout dans le monde via le routage le meilleur et le moins cher. Vous pouvez enregistrer un numéro ENUM tout comme un nom de domaine.

Lors du développement de projets, nous rencontrons généralement certains champs de statut, comme le statut d'une commande en attente de paiement, payée, clôturée, remboursée, etc. Dans les projets sur lesquels j'ai travaillé auparavant, ces statuts étaient stockés dans la base de données sous forme de chiffres en php. Des constantes sont utilisées dans le code pour maintenir une table de mappage, par exemple :

const STATUS_PENDING = 0;
const STATUS_PAID = 1;
const STATUS_CLOSED = 2;
const STATUS_REFUNDED = 3;
Copier après la connexion

Cependant, lors de l'utilisation réelle, nous avons constaté que ce n'était pas si simple à utiliser. Pour diverses raisons (bugs de suivi, temporaires. exigences statistiques, etc.) nous devons souvent vous connecter au serveur MySQL pour exécuter manuellement certains SQL Requête, puisque de nombreuses tables ont des champs d'état, vous devez écrire du SQL en fonction de la relation de mappage dans le code PHP. Si vous ne faites pas attention, vous risquez de confondre les numéros d'état des différentes tables, provoquant de gros problèmes.

J'ai donc prévu d'utiliser le type enum de MySQL pour stocker divers états dans le nouveau projet. Lors de l'utilisation, j'ai constaté que si j'utilisais le. Toute modification apportée à la table de type enum (même les modifications apportées aux champs de type non-enum) entraînera une erreur

[Doctrine\DBAL\DBALException]
Unknown database type enum requested, Doctrine\DBAL\Platforms\MySQL57Platform may not support it.
Copier après la connexion

Après une recherche, j'ai découvert que la doctrine ne prend pas en charge l'énumération de MySQL. L'article répertorie 3 lacunes de. enum :

Lors de l'ajout d'une valeur enum, vous devez reconstruire la table entière, ce qui peut prendre plusieurs heures lorsque la quantité de données est importante.

Les valeurs Enum sont triées dans l'ordre spécifié lors de la création de la structure du tableau, et non selon la taille de la valeur littérale.

Il n'est pas nécessaire de s'appuyer sur mysql pour vérifier la valeur enum. L'insertion de valeurs illégales sous la configuration par défaut finira par devenir une valeur nulle.

Selon la situation réelle du nouveau projet, il est peu probable qu'il soit nécessaire de trier les champs de statut. Même si c'est le cas, nous pouvons déterminer l'ordre lors de la conception de la structure de la table, donc l'inconvénient 2 peut être ignoré ; Cela peut être évité grâce aux spécifications du code, à la vérification avant l'insertion/la mise à jour, etc. Quant à l'inconvénient 1, nous devons faire quelques tests.

Préparation du test#

Créez d'abord un tableau :

CREATE TABLE `enum_tests` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `status` enum('pending','success','closed') COLLATE utf8mb4_unicode_ci NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Copier après la connexion

Puis insérez 100 W de données :

$count = 1000000;
$bulk = 1000;
$data = [];
foreach (['pending', 'success', 'closed'] as $status) {
  $data[$status] = [];
  for ($i = 0; $i < $bulk; $i++) {
    $data[$status][] = [&#39;status&#39; => $status];
  }
}
  
for ($i = 0; $i < $count; $i += $bulk) {
  $status = array_random([&#39;pending&#39;, &#39;success&#39;, &#39;closed&#39;]);
  EnumTest::insert($data[$status]);
Copier après la connexion

Processus de test#

Test 1#

Ajouter une valeur remboursée à la fin de la liste de valeurs enum

ALTER TABLE `enum_tests` CHANGE `status` `status` ENUM(&#39;pending&#39;,&#39;success&#39;,&#39;closed&#39;,&#39;refunded&#39;) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
Copier après la connexion


Sortie :

Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
Copier après la connexion


Conclusion : Il n'y a presque aucun coût lors de l'ajout de valeurs d'énumération à la fin.

Test 2 : #

Supprimer la valeur juste ajoutée remboursée

ALTER TABLE `enum_tests` CHANGE `status` `status` ENUM(&#39;pending&#39;,&#39;success&#39;,&#39;closed&#39;) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
Copier après la connexion
Copier après la connexion


Sortie :

Query OK, 1000000 rows affected (5.93 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Copier après la connexion


Conclusion : la suppression d'une valeur d'énumération inutilisée nécessite toujours une analyse complète de la table, ce qui est plus coûteux, mais toujours dans une plage acceptable.

Test 3 : #

Insérer remboursé au milieu de la liste de valeurs au lieu de la fin

ALTER TABLE `enum_tests` CHANGE `status` `status` ENUM(&#39;pending&#39;,&#39;success&#39;,&#39;refunded&#39;, &#39;closed&#39;) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
Copier après la connexion


Sortie :

Query OK, 1000000 rows affected (6.00 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Copier après la connexion


Conclusion : L'ajout d'une nouvelle valeur au milieu de la liste de valeurs d'énumération d'origine nécessite d'analyser et de mettre à jour l'intégralité de la liste. table, ce qui coûte cher.

Test 4 : #

Supprimer la valeur au milieu de la liste de valeurs

ALTER TABLE `enum_tests` CHANGE `status` `status` ENUM(&#39;pending&#39;,&#39;success&#39;,&#39;closed&#39;) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
Copier après la connexion
Copier après la connexion


Résultat :

Query OK, 1000000 rows affected (4.23 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Copier après la connexion


Conclusion : Une analyse complète du tableau est nécessaire et le coût est élevé.

Test 5 : #

Ajoutez un index au champ d'état puis exécutez le test ci-dessus

ALTER TABLE `enum_tests` ADD INDEX(`status`);
Copier après la connexion


J'ai trouvé que les tests 2-4 La consommation de temps a plutôt augmenté, ce qui peut être dû à la nécessité de mettre à jour l'index en même temps.

Conclusion : #

Pour mon nouveau projet, seules les nouvelles valeurs d'énumération apparaîtront Même si certains états sont abandonnés à l'avenir, il n'est pas nécessaire d'ajuster la liste de valeurs d'énumération, j'ai donc décidé d'introduire enum dans le projet Le type sert de type de données pour stocker l’état.

Recommandations associées :

Explication détaillée de l'utilisation d'Enum (énumération) en php

Exemple de code de la fonctionnalité d'extension Enum

Comment résoudre la confusion concernant la valeur par défaut du type de données enum

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!