Maison >base de données >tutoriel mysql >Le partage le plus complet des spécifications d'utilisation de MySQL dans l'histoire
[Recommandations d'apprentissage associées : Tutoriel MySQL]
Il y a eu de nombreuses opérations liées aux bases de données récemment, et les spécifications existantes de l'entreprise sont pas trop complet. Selon les normes pertinentes de divers experts sur Internet, j'ai compilé quelques usages standards pour mon propre usage. J'espère que vous pourrez me corriger.
Environnement de base de données
dev : Environnement de développement
Le développement peut lire et écrire, et peut modifier la structure des tables. Les développeurs peuvent modifier la structure de la table et les données qu'elle contient à volonté, mais doivent s'assurer que cela n'affecte pas les autres collègues de développement.
test : L'environnement de test
est lisible et inscriptible par les développeurs, et les développeurs peuvent modifier la structure de la table via des outils.
en ligne : environnement en ligne
Les développeurs ne sont pas autorisés à effectuer directement des opérations de base de données dans l'environnement en ligne. Si des opérations sont nécessaires, ils doivent trouver l'administrateur de base de données pour opérer et effectuer. enregistrements correspondants. Ceci est interdit.
Le problème clé est que les autorisations utilisateur correspondant au serveur MySQL dans chaque environnement doivent être clairement divisées et identifiables, et peuvent distinguer spécifiquement les scénarios commerciaux, etc.
Conventions de dénomination
Règles de dénomination de base
Dans MySQL, les bases de données et les tables correspondent aux répertoires et fichiers situés sous ces répertoires. Par conséquent, la sensibilité du système d’exploitation détermine la sensibilité à la casse des noms de base de données et de table.
Il n'est pas sensible à la casse sous Windows.Les tables du même module doivent utiliser le même préfixe autant que possible, et les noms des tables doivent exprimer la signification comme autant que possible. Toutes les tables de journaux commencent par log_
Nom de champUn mot anglais ou une abréviation qui exprime sa signification réelle. Les champs ayant une signification booléenne sont préfixés par is_, suivi du participe passé du verbe.
L'index non unique doit être nommé selon "idx_field name_field name[_field name]"
Contrainte de clé primaire : nom de la table_pk.
Le moteur de table dépend de l'application réelle scénario ; journaux et rapports Il est recommandé d'utiliser myisam pour les tables de classes et le moteur innodb pour les tables liées aux transactions, aux audits et aux montants. S'il n'y a pas d'explication, le moteur innodb sera utilisé lors de la création de la table
Le jeu de caractères utf8mb4 par défaut est utilisé et la règle de tri de la base de données est utf8mb4_general_ci (puisque la définition de la base de données utilise la valeur par défaut, la table de données. ne peut plus être défini, mais à des fins d'assurance, il est recommandé d'écrire
Pourquoi ne pas choisir utf8 pour le jeu de caractères et utf8_general_ci pour la règle de tri des octets d'expressions Emoji ? faire en sorte que le projet back-end prenne pleinement en charge les expressions Emoji saisies par le client, la mise à niveau de l'encodage vers utf8mb4 est la meilleure solution. Pour la chaîne de connexion JDBC, le caractère Encoding est défini sur utf8 ou la configuration ci-dessus ne peut toujours pas être insérée normalement dans le. Dans le cas des données emoji, vous devez spécifier le jeu de caractères de connexion comme utf8mb4 dans le code Toutes les tables et tous les champs doivent utiliser l'attribut de colonne de commentaire pour décrire la véritable signification de la table et du champ. valeur d'énumération, il est recommandé de définir tout le contenu utilisé dans ce champ. S'il n'est pas spécifié, le premier champ d'identification de la table doit être la clé primaire et croître automatiquement en tant que contexte et condition. une non-transaction est interdite. Il est interdit d'utiliser le type varchar comme conception d'instruction de clé primaire.
S'il n'y a pas de description, la table doit contenir les champs create_time et modifier_time, c'est-à-dire que la table doit contenir des champs qui enregistrent l'heure de création et l'heure de modification
S'il n'y a pas de description, la table doit contient is_del, qui est utilisé pour indiquer si les données ont été supprimées. En principe, la suppression physique des données de la base de données n'est pas autorisée.
Quelle est la différence entre datetime et timestamp ?
Points similaires :
Le format d'affichage de la colonne TIMESTAMP est le même que la colonne DATETIME. La largeur d'affichage est fixée à 19 caractères et le format est AAAA-MM-JJ HH:MM:SS.
Différences :
TIMESTAMP
Comment utiliser l'attribut d'affectation automatique de TIMESTAMP ?
Définissez l'heure actuelle comme valeur par défaut de ts : ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP. Lorsque la ligne est mise à jour, mettez à jour la valeur de ts : ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP.
Vous pouvez combiner 1 et 2 : ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
Comment utiliser INT UNSIGNED pour stocker l'IP ?
Utilisez INT UNSIGNED au lieu de char(15) pour stocker l'adresse ipv4 et utilisez les fonctions MySQL inet_ntoa et inet_aton pour la conversion. Les adresses IPv6 n'ont actuellement pas de fonction de conversion et doivent être stockées à l'aide de DECIMAL ou de deux bigINT.
INT[M]. Que signifie la valeur M ?
Notez que le nombre après les parenthèses de type numérique indique uniquement la largeur et n'a rien à voir avec la plage de stockage. Beaucoup de gens pensent que les plages de valeurs de INT(4) et INT(10) sont respectivement (-9999 à 9999) et (-9999999999 à 9999999999). Cette compréhension est fausse. En fait, lorsque la valeur M dans l'entier est utilisée en combinaison avec l'attribut ZEROFILL, les valeurs des colonnes peuvent être de même largeur. Quelle que soit la valeur de M dans INT[M], sa plage de valeurs est toujours (-2147483648 à 2147483647 lorsqu'elle est signée), (0 à 4294967295 lorsqu'elle n'est pas signée).
La largeur d'affichage ne limite pas la plage de valeurs pouvant être enregistrées dans la colonne, ni l'affichage des valeurs qui dépassent la largeur spécifiée de la colonne. Lorsqu'ils sont utilisés conjointement avec l'attribut étendu facultatif ZEROFILL, les espaces supplémentaires par défaut sont remplacés par des zéros. Par exemple : Pour une colonne déclarée comme INT(5) ZEROFILL, la valeur 4 est récupérée sous la forme 00004. Veuillez noter que si vous stockez une valeur dans une colonne entière qui dépasse la largeur d'affichage, MySQL rencontrera des problèmes lors de la génération de tables temporaires pour des jointures complexes, car dans ces cas, MySQL estime que les données correspondent à la largeur de colonne d'origine si vous spécifiez ZEROFILL pour. une colonne numérique, MySQL ajoute automatiquement l'attribut UNSIGNED à la colonne.
Utilisez VARBINARY pour stocker des chaînes de longueur variable sensibles à la casse
Quand utiliser CHAR et quand utiliser VARCHAR ?
Les types CHAR et VARCHAR sont similaires, mais ils sont enregistrés et récupérés différemment. Ils diffèrent également en termes de longueur maximale et de préservation des espaces de fin. La longueur déclarée pour les types CHAR et VARCHAR représente le nombre maximum de caractères que vous souhaitez enregistrer. Par exemple, CHAR(30) peut occuper 30 caractères.
La longueur de la colonne CHAR est fixée à la longueur déclarée lors de la création du tableau. La longueur peut être n'importe quelle valeur comprise entre 0 et 255. Lors de l'enregistrement des valeurs CHAR, remplissez-les vers la droite avec des espaces jusqu'à la longueur spécifiée. Lorsqu'une valeur CHAR est récupérée, les espaces de fin sont supprimés. Aucune conversion de cas n'est effectuée pendant le stockage ou la récupération.
Les valeurs des colonnes VARCHAR sont des chaînes de longueur variable. La longueur peut être spécifiée comme une valeur comprise entre 0 et 65 535. (La longueur effective maximale de VARCHAR est déterminée par la taille maximale des lignes et le jeu de caractères utilisé. La longueur maximale globale est de 65 532 octets). Par rapport à CHAR, la valeur VARCHAR enregistre uniquement le nombre requis de caractères, plus un octet pour enregistrer la longueur (si la longueur déclarée de la colonne dépasse 255, deux octets sont utilisés). Les valeurs VARCHAR sont enregistrées sans remplissage. Les espaces de fin sont conservés lorsque la valeur est enregistrée et récupérée, conformément au SQL standard.
char convient au stockage de la valeur de hachage MD5 du mot de passe utilisateur, et sa longueur est toujours la même. char est également meilleur que varchar pour les valeurs qui changent fréquemment, car les lignes de longueur fixe sont moins sujettes à la fragmentation, et char est également plus efficace que varchar pour les colonnes très courtes. La chaîne char(1) n'occupera qu'un octet pour un jeu de caractères à un octet, mais la chaîne varchar(1) occupera 2 octets, car 1 octet est utilisé pour stocker les informations de longueur.
Spécifications de conception d'index
La vitesse des requêtes MySQL repose sur une bonne conception d'index, les index sont donc cruciaux pour des performances élevées. Les index raisonnables accéléreront les requêtes (y compris les vitesses UPDATE et DELETE. MySQL chargera la page contenant la ligne en mémoire puis effectuera les opérations UPDATE ou DELETE), tandis que les index déraisonnables ralentiront la vitesse. La recherche par index MySQL est similaire à la recherche en pinyin et en radical dans le dictionnaire Xinhua. Lorsque l'index en pinyin et en radical n'existe pas, il ne peut être recherché qu'en tournant page par page. Lorsque les requêtes MySQL ne peuvent pas utiliser d'index, MySQL effectuera une analyse complète de la table, ce qui consommera beaucoup d'E/S. Objectif de l'index : déduplication, accélération du positionnement, évitement du tri, écrasement de l'index.
Qu'est-ce qu'un index de couverture
Dans le moteur de stockage InnoDB, l'index secondaire (index de clé non primaire) ne stocke pas directement les adresses de lignes et stocke la clé primaire valeurs. Si l'utilisateur doit interroger une colonne de données qui n'est pas incluse dans l'index secondaire, il doit d'abord trouver la valeur de la clé primaire via l'index secondaire, puis interroger les autres colonnes de données via la clé primaire. être interrogé deux fois. Le concept de l'index de couverture est que la requête peut être complétée dans un index, et l'efficacité de l'index de couverture sera relativement élevée. La requête de clé primaire est un index de couverture naturel. La création raisonnable d'index et l'utilisation raisonnable d'instructions de requête peuvent améliorer les performances lors de l'utilisation d'index de couverture. Par exemple, SELECT email, uid FROM user_email WHERE uid=xx, si uid n'est pas la clé primaire, vous pouvez ajouter l'index en tant qu'index(uid, email) le cas échéant pour améliorer les performances.
Spécifications de base pour les index
Pourquoi ne peut-il pas y avoir trop d'index dans un tableau?
L'index secondaire d'InnoDB utilise b+tree pour le stockage, donc b+tree doit être ajusté pendant UPDATE, DELETE et INSERT. Des index excessifs ralentiront la vitesse de mise à jour.
Utiliser l'index de préfixe pour les chaînes. La longueur de l'index de préfixe ne doit pas dépasser 8 caractères. Il est recommandé de donner la priorité à l'index de préfixe. Si nécessaire, vous pouvez ajouter des pseudo-colonnes et créer des index.
N'indexez pas les champs tels que les objets blob/texte ou les champs volumineux. Cela risquerait de faire occuper trop d'espace de stockage par l'index.
Qu'est-ce qu'un index de préfixe ?
Pour parler franchement, un index de préfixe indexe les premiers caractères du texte (plus précisément, les quelques caractères spécifiés lors de la création de l'index), afin que l'index créé soit plus petit, donc la requête est plus rapide. L'index de préfixe peut réduire efficacement la taille des fichiers d'index et améliorer la vitesse d'indexation. Mais les index de préfixe ont aussi leurs inconvénients : MySQL ne peut pas utiliser d'index de préfixe dans ORDER BY ou GROUP BY, ni comme index de couverture.
Syntaxe pour établir un index de préfixe : ALTER TABLE table_name ADD KEY(column_name(prefix_length));
Critères de clé primaire
Le SQL important doit être indexé, le noyau SQL donne la priorité à la couverture de l'index
avoir la plus grande différenciation Placez les champs au premier plan
Index Tabou
Limitations sur les index dans MYSQL
La longueur totale du Les index du moteur de stockage MYISAM ne peuvent pas dépasser 1 000 octets
Seuls les index de préfixe peuvent être créés pour les colonnes de type BLOB et TEXT
MYSQL ne prend actuellement pas en charge les index de fonction
Lors de l'utilisation d'une valeur différente de (!= ou a8093152e673feb7aba1828c43532094) , MYSQL ne peut pas utiliser l'index.
Après avoir filtré les champs à l'aide d'opérations fonctionnelles (telles que abs (colonne)), MYSQL ne peut pas utiliser d'index.
MYSQL ne peut pas utiliser l'index lorsque les types de champs de condition de jointure dans l'instruction de jointure sont incohérents
Lors de l'utilisation de l'opération LIKE, si la condition commence par un caractère générique (tel que '%abc…'), MYSQL ne peut pas utiliser le indice.
Spécifications de conception des instructions
Utiliser des instructions précompiléesÉviter la conversion implicite
Provoquera un échec de l'indexUtiliser pleinement l'index de préfixe
N'utilisez pas de requêtes négatives, telles que not in/like
Évitez d'utiliser des procédures stockées et des déclencheurs, des serveurs, des UDF, des événements, etc.
Évitez d'utiliser JOIN de grandes tables
Ce que MySQL fait le mieux, c'est la requête clé primaire/index secondaire d'une seule table
Évitez les opérations mathématiques dans la base de données
Réduire le nombre d'interactions avec la base de données
Utiliser la pagination de manière raisonnable
Limiter le nombre de pages affichées par pagination Vous ne pouvez cliquer sur la page précédente et la page suivante qu'en utilisant le différé. associationComment utiliser correctement la pagination ?
Supposons qu'il existe une instruction de pagination similaire à la suivante : SELECT * FROM table ORDER BY id LIMIT 10000, 10 Puisque la façon dont LIMIT OFFSET est traitée dans MySQL consiste à supprimer toutes les données de OFFSET+ LIMIT, puis supprimez OFFSET et renvoyez LIMIT en bas. Par conséquent, lorsque la valeur OFFSET est grande, les performances des requêtes MySQL seront très faibles. Il peut être résolu en utilisant id > n : Il existe des limites à l'utilisation de id > Pour le problème des identifiants discontinus, il peut être résolu en transmettant le dernier identifiant en même temps lors de la rotation. la page.http://example.com/page.php?last=100 select * from table where id<100 order by id desc limit 10 //上一页 http://example.com/page.php?first=110 select * from table where id>110 order by id desc limit 10Le plus gros inconvénient de cette méthode est que s'il y a une opération d'insertion/suppression pendant la navigation, le changement de page ne sera pas mis à jour, et le nombre total de pages pourra toujours être calculé en fonction du nouveau décompte ( *), et enfin Certains enregistrements peuvent être inaccessibles. Afin de résoudre ce problème, vous pouvez continuer à introduire le numéro de page actuel et s'il existe des opérations d'insertion/suppression qui affectent le nombre total d'enregistrements depuis le dernier tour de page et les mettre en cache
select * from table where id >= (select id from table order by id limit #offset#, 1)
select * from test_union1 union select * from test_union2Ce SQL extrait d'abord les résultats des deux tables pendant le fonctionnement, puis utilise l'espace de tri pour trier et supprimer les enregistrements en double, et renvoie enfin l'ensemble de résultats si les données de la table sont volumineuses. cela peut entraîner l'utilisation de disques. Et union all combine simplement les deux résultats et les renvoie. De cette façon, s'il y a des données en double dans les deux jeux de résultats renvoyés, le jeu de résultats renvoyé contiendra des données en double.
从效率上说,union all要比union快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用union all,如下:
select * from test_union1 union all select * from test_union2
分表规范
单表一到两年内数据量超过500w或数据容量超过10G考虑分表,需提前考虑历史数据迁移或应用自行删除历史数据,采用等量均衡分表或根据业务规则分表均可。要分表的数据表必须与DBA商量分表策略
行为规范
其他规范
日志类数据不建议存储在MySQL上,优先考虑Hbase或OceanBase,如需要存储请找DBA评估使用压缩表存储。
相关图文教程:mysql数据库图文教程
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!