1
votes

La taille de ligne ne dépasse pas pour VarChar

Ma table :

3 byte character - ‱

Row Format - DYNAMIC

Collation - UTF8mb3

Character set - utf8_general_ci

Mysql - 5.7

Insérer une requête :

insert into test values(1, '‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱','‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱‱');

Mon la taille de la page est de 16 Ko . Ainsi, une ligne de ma table peut contenir au maximum 8192 octets (c'est-à-dire 8KB).

J'ai créé 11 colonnes VARCHAR (chaque 255 caractères), où ces 11 colonnes peuvent contenir un maximum de 255 * 11 = 2805 caractères.

Si je stocke un 2805 - 3 octets caractères, cela prendra ( 255 * 11 * 3 ) = 8415bytes qui dépasse la limite de la taille de ligne maximale ( 8192 octets ).

Maintenant, j'ai essayé d'insérer la requête sur une seule ligne ci-dessus, qui contient des données de 8415 octets . Mais mon MYSQL n'a pas généré d'erreur qui a accepté cette requête d'insertion.

create table test( pk bigint primary key,
value1 varchar(255),
value2 varchar(255),
value3 varchar(255),
value4 varchar(255),
value5 varchar(255),
value6 varchar(255),
value7 varchar(255),
value8 varchar(255),
value9 varchar(255),
value10 varchar(255),
value11 varchar(255),
);

Mise à jour : la même chose se produit également pour la colonne CHAR (changement de VarChar en Char), qui est une colonne de longueur fixe.


2 commentaires

Mysql varchar peut être 1 octet ou 2 octets mysqltutorial.org/mysql-varchar . Devez-vous utiliser le type varchar de cette manière pour une raison particulière? Parce qu'il existe aussi un type BLOB qui fonctionne bien.


@BUcorp - Je suis sceptique à propos de ce site Web de tutoriel - Je ne vois aucun indice sur les MOTEURS impliqués, ni sur la version de MySQL / MariaDB. La question du PO a connu plusieurs changements au fil des ans.


3 Réponses :


4
votes

Vous avez mal compris la description de la limite de taille de ligne innodb. Citation tirée du manuel mysql (je souligne):

La longueur maximale des lignes, à l'exception des colonnes de longueur variable (VARBINARY, VARCHAR , BLOB et TEXT), est légèrement inférieure à la moitié d'une page pour 4 Ko, 8 Ko , 16 Ko et 32 ​​Ko de tailles de page. Par exemple, la longueur de ligne maximale pour innodb_page_size par défaut de 16 Ko est d'environ 8 000 octets. ...

Si une ligne fait moins d'une demi-page, tout est stocké localement dans la page. S'il dépasse une demi-page, des colonnes de longueur variable sont choisies pour le stockage externe hors page jusqu'à ce que la ligne tienne dans une demi-page , comme décrit dans la Section 14.12.2, «Gestion de l'espace fichier». < / p>

Puisque vos champs sont varchar (un type fiekd de longueur variable), les données au-dessus de la limite de taille de demi-page sont simplement stockées dans un autre emplacement hors page, donc votre instruction sql est correcte.

<❯edit

Pour les champs char , le comportement dépend du format de ligne et du jeu de caractères utilisé.

La longueur d'un champ char est fixe en termes de nombre de caractères, mais en fonction du jeu de caractères, la longueur d'octet peut être soit fixe (par exemple latin1 est fixé à 1 octet / caractère), soit variable (par exemple, utf8mb3 a une longueur variable de 1 à 3 octets / caractère).

Pour le format de ligne compact , le jeu de caractères n'est pas pertinent, vous obtenez un message d'erreur si la longueur d'octet maximale possible dépasse la limite de page de données dérivée de la configuration de taille de page lorsque vous souhaitez créer le tableau.

Pour le format de ligne dynamique , si le jeu de caractères est de longueur fixe et que la longueur d'octet dépasse la limite de la page de données, vous obtenez une erreur lorsque vous souhaitez créer le tableau. Cependant, si le jeu de caractères est de longueur variable, les données sont stockées dans les pages de débordement.


15 commentaires

J'ai un doute sur la raison pour laquelle ils imposent des limites de taille de ligne pour la colonne VARCHAR. Vérifiez les exemples de limite de taille de ligne dans la documentation URL .oracle.com / cd / E17952_01 / mysql-5.5-fr /… . . Veuillez donner une brève description à ce sujet. Et quelles colonnes seront stockées hors page pour mon cas comme vous l'avez dit.


1) l'exemple innodb dans votre lien utilise le type de données char , qui n'est pas dynamique, il est de longueur fixe. Vous avez utilisé le type de données varchar , qui est de longueur variable. 2) Aucune idée des colonnes qui seront stockées hors de la page. Consultez la Section 14.12.2, «Gestion de l'espace fichier» du manuel mysql, cela vous donnera peut-être la réponse.


Ils ont également utilisé VarChar, veuillez vérifier, ce sera vraiment utile. CREATE TABLE t (a VARCHAR (10000), b VARCHAR (10000), c VARCHAR (10000), d VARCHAR (10000), e VARCHAR (10000), f VARCHAR (10000), g VARCHAR (6000)) MOTEUR = JEU DE CARACTERES InnoDB latin1; ERREUR 1118 (42000): taille de ligne trop grande. La taille de ligne maximale pour le type de table utilisé, sans compter les BLOB, est de 65535. Vous devez changer certaines colonnes en TEXT ou BLOB


cet exemple que vous référencez démontre la limite de taille de ligne maximale MySQL de 65 535 octets , pas la limite de demi-page innodb. Encore une fois, vous mélangez les choses.


J'ai essayé le même processus en changeant VarChar (255) en Char (255). Comme vous l'avez dit Si elle dépasse une demi-page, des colonnes de longueur variable sont choisies pour le stockage externe hors page jusqu'à ce que la ligne tienne dans une demi-page cela ne s'applique qu'aux colonnes de longueur variable et non aux colonnes de longueur fixe ( carboniser). Pourquoi s'insère-t-il sans aucun problème. Une idée


Probablement à cause d'un changement de spécification de colonne silencieux. Mysql convertit les champs char plus longs que quelques caractères en varchar.


Ou simplement la taille des données que vous insérez est inférieure à ce que vous avez calculé.


J'ai calculé la taille correctement et inséré. Et pour le changement de colonne silencieux, il n'est pas mentionné ce type de changements effectués en silence.


Il existe 4 ROW_FORMAT différents dans InnoDB; ils gèrent le stockage hors enregistrement différemment.


«Off page» (aka «off-record») nécessite un «pointeur» dans l'enregistrement principal. Autrement dit, selon ROW_FORMAT , 767 + 20 octets ou 20 octets. Ce dernier contraint une ligne à ne pas avoir plus d'environ 400 varchars.


Quelqu'un a-t-il une référence valide à la limite de 65 Ko? Je pense que c'est un vieux "conte d'épouses".


CHAR n'est plus vraiment de longueur fixe. (Auparavant.) Elle est en fait de longueur fixe car des espaces de fin sont fournis.


Si vous avez inséré du texte anglais dans un CHAR .. CHARSET utf8 , le * 3 disparaît. (Voir mon commentaire précédent.)


@RickJames, voilà: dev.mysql.com/doc/mysql-reslimits-excerpt/8.0/en/...


@RickJames Découvrez ma réponse à cette question.



1
votes

Comme SHADOW l'a dit pour les colonnes VARHCAR

Si une ligne fait moins d'une demi-page, tout est stocké localement dans la page. S'il dépasse une demi-page, des colonnes de longueur variable sont choisies pour le stockage externe hors page jusqu'à ce que la ligne tienne dans une demi-page

Pour les colonnes CHAR

InnoDB encode les champs de longueur fixe supérieurs ou égaux à 768 octets en tant que champs de longueur variable, qui peuvent être stockés hors page. Par exemple, une colonne CHAR (255) peut dépasser 768 octets si la longueur maximale en octets du jeu de caractères est supérieure à 3, comme c'est le cas avec utf8mb4. https://forums.mysql.com/read.php? 24,645115,645215 # msg-645215

Où mysql convertit en interne des champs de longueur fixe en champs de longueur variable https://dev.mysql.com/doc/refman/ 5.6 / fr / storage-requirements.html


0 commentaires

1
votes

En interne, pour les jeux de caractères de longueur variable tels que utf8mb3 et utf8mb4, InnoDB tente de stocker CHAR (N) dans N octets en réduisant les espaces de fin. Si la longueur d'octet d'une valeur de colonne CHAR (N) dépasse N octets, les espaces de fin sont réduits au minimum de la longueur d'octet de la valeur de colonne. La longueur maximale d'une colonne CHAR (N) est la longueur maximale d'octet de caractères × N.

Un minimum de N octets est réservé pour CHAR (N). La réservation de l'espace minimum N dans de nombreux cas permet de mettre à jour les colonnes sur place sans provoquer de fragmentation de la page d'index. Par comparaison, les colonnes CHAR (N) occupent la longueur maximale d'octet de caractères × N lors de l'utilisation du format de ligne REDUNDANT.

- https://dev.mysql.com/doc/refman/5.6/en/innodb-row-format.html#innodb-compact-row-format-characteristics

Ce qui précède fait référence à ROW_FORMAT = COMPACT, DYNAMIC et COMPRESSED (avant compression). Et il s'agit du stockage sur la page de CHAR .


0 commentaires