Maison > Article > base de données > Maîtrisez le type de données Enum dans Mysql en un seul article
Cet article vous apporte des connaissances pertinentes sur mysql, qui résout principalement les problèmes liés au type de données Enum. Le type enum dans Mysql est ce que nous appelons souvent le type énumération, et sa plage de valeurs doit être créée avant que la table soit. explicitement spécifié via l'énumération (répertorié un par un). Jetons-y un coup d'œil, j'espère que cela sera utile à tout le monde.
Apprentissage recommandé : Tutoriel vidéo mysql
Le type enum dans Mysql est ce que nous appelons souvent un type d'énumération. Sa plage de valeurs doit être énumérée lors de la création d'une table (répertoriée une par une) explicitement spécifiée. Les énumérations pour 1 à 255 membres nécessitent 1 octet de stockage ; pour 255 à 65 535 membres, 2 octets de stockage sont requis. Un maximum de 65 535 membres est autorisé.
La couche inférieure de l'énumération stocke les entiers décimaux, qui sont strictement classés dans l'ordre 1, 2, 3, 4, 5... N'utilisez jamais l'énumération pour stocker des nombres.
Parfois, vous pouvez utiliser des énumérations au lieu des types de chaînes couramment utilisés. Les colonnes d'énumération peuvent stocker des chaînes uniques dans un ensemble prédéfini. MySQL est très compact lors du stockage des énumérations, et il sera basé sur la valeur de la liste compressée en 1. ou 2 octets . MySQL enregistre en interne la position de chaque valeur dans la liste sous forme d'entier et enregistre la "table de recherche" de la relation de mappage "numéro-chaîne" dans le fichier .frm
. .frm
文件中保存“数字-字符串”映射关系的“查找表”。
CREATE TABLE `mytest` ( `id` int(11) NOT NULL AUTO_INCREMENT, `sex` enum('男','女') DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;
insert into mytest(sex) values('男'); // sex = 男 insert into mytest(sex) values('女'); // sex = 女 insert into mytest(sex) values(1); // sex = 男 insert into mytest(sex) values('1'); // sex = 男 insert into mytest(sex) values('未知'); // 插入报错,1265 - Data truncated for column 'sex' insert into mytest(sex) values('0'); // sex = '' insert into mytest(sex) values(0); // 插入报错,1265 - Data truncated for column 'sex'
从上可以看出字段中的enum值在mysql中的数据结构中类似于一个数组,并且下标是从1开始计算的,总结出:
1、通过正确的枚举值可以插入到数据库,如:第1、2条语句;
2、通过正确的下标可以插入到数据库,如:第3、4条语句;
3、插入'0'
将保存为空字符串,如:第6条语句;
4、插入数字0
或者'未知'
事时会出现执行错误,如:第5、7条语句。
查询时,通过 “列名+0” 即可获取改值在枚举中的位置关系,如下SQL语句执行结果
SELECT id,sex,sex+0 from `mytest` ;
查询结果如下:
使用ALTER TABLE mytest MODIFY COLUMN sex enum('男');
语句可以减少枚举类型,特殊情况下如果枚举值在记录行中已被使用则会出现[1265] Data truncated for column
错误。
和减少枚举类型情况一样,必须确保枚举值没有被记录行使用
使用ALTER TABLE mytest MODIFY COLUMN sex enum('未知','男','女');
语句在首部插入一个枚举。在**首部插入枚举会引起枚举的位置关系发生改变。**在首部插入枚举会导致枚举和位置的关系都向后移动。
如下图,插入之前的结果:
如下图,插入之后的结果:
使用ALTER TABLE mytest MODIFY COLUMN
sex enum('男','未知','女');
语句在中间插入一个枚举。在**中间插入枚举会引起枚举的位置关系发生改变。**在中间插入枚举会导致插入位置后的枚举和位置的关系都向后移动。
如下图,插入之前的结果:
如下图,插入之后的结果:
使用 ALTER TABLE mytest MODIFY COLUMN sex enum('男','女','未知');
CREATE TABLE test4 ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, brand VARCHAR(255) NOT NULL, color ENUM('RED','GREEN','BLUE') ) ENGINE = InnoDB;Insérer des données
public enum Color { RED, GREEN, BLUE }Comme le montre ce qui précède, la valeur enum dans le champ est similaire à un tableau dans la structure de données dans MySQL, et l'indice est calculé à partir de 1 , qui se résume :
2. Il peut être inséré dans la base de données via l'indice correct, tel que : 3. et 4 instructions ;
3. Insérez'0'
et il sera enregistré sous forme de chaîne vide, comme l'instruction 6 ; code>'unknown' Code>Des erreurs d'exécution se produiront lors de l'exécution de choses, telles que les instructions 5 et 7. 🎜🎜Données de requête🎜🎜Lors de l'interrogation, vous pouvez obtenir la relation de position de la valeur modifiée dans l'énumération par "nom de colonne + 0". Les résultats d'exécution de l'instruction SQL suivants🎜@Entity @Table(name="test4") public class ClothesRight { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Enumerated(EnumType.STRING) private Color color; private String brand; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public ClothesRight(Long id, Color color, String brand) { super(); this.id = id; this.color = color; this.brand = brand; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } public ClothesRight() { super(); } }🎜Les résultats de la requête sont les suivants : 🎜🎜🎜🎜Modifier l'énumération 🎜
ALTER TABLE mytest MODIFY COLUMN sex enum('male');
pour réduire le type d'énumération. Dans des cas particuliers, si la valeur d'énumération a été utilisée dans la ligne d'enregistrement, [ apparaîtra 1265] Données tronquées pour la colonneErreur. 🎜ALTER TABLE mytest MODIFY COLUMN sex enum('unknown','male','female');
L'instruction insère une énumération dans l'en-tête. L'insertion d'une énumération dans l'en-tête ** entraînera une modification de la relation de position de l'énumération. **L'insertion d'une énumération en tête fera reculer la relation entre l'énumération et le poste. 🎜🎜Comme indiqué ci-dessous, insérez le résultat précédent : 🎜🎜🎜🎜Comme indiqué ci-dessous, le résultat après insertion : 🎜🎜🎜ALTER TABLE mytest MODIFY COLUMN
sex enum('male','unknown','female' ); L'instruction
insère une énumération au milieu. L'insertion d'une énumération au milieu de ** entraînera une modification de la relation de position de l'énumération. **L'insertion d'une énumération au milieu fera reculer la relation entre l'énumération et la position après la position d'insertion. 🎜🎜Comme indiqué ci-dessous, insérez le résultat précédent : 🎜🎜🎜🎜Comme indiqué ci-dessous, le résultat après insertion : 🎜🎜🎜ALTER TABLE mytest MODIFY COLUMN sex enum('male','female','unknown'); code> instruction Insère une énumération à la fin. L'insertion d'une énumération à la fin de ** n'entraînera aucun changement dans la relation entre la valeur de l'énumération et la position. **Comme il n'y a aucun changement, l'image ne sera pas affichée ici. 🎜🎜Pièges liés à l'utilisation de types d'énumération🎜🎜🎜1. Il n'est pas recommandé de définir un certain type de champ dans MySQL sur enum, mais la valeur stockée est un nombre🎜, tel que « 0 », « 1 », « 2 » ; 🎜🎜🎜 🎜🎜Explication 1 : 🎜 causera de la confusion car enum peut prendre la valeur via l'indice, mais son indice commence à 1. Pour les personnes qui ne sont pas familières avec ce champ, il y aura une erreur ici🎜
解释2: enum类型的字段对于0与‘0’有非常大的区别,如果你是用0当角标做操作,因它没有这个角标,所要会报错;如果你使用‘0’这个值去取枚举值,并做插入操作,你会发现它竟然会成功,但是插入的结果是一个“空”(不是null)
总之,不要拿mysql的enum类型取存一些数字;如果你一定要使用这个字段去存数字,请把这个字段定义为int,然后在java代码中使用枚举类做一个对于这个字段值范围的一个限定!(后面有代码)
2、可能会出现Caused by: java.sql.SQLException: Data truncated for column 'Color' at row 1 ;
错误
原因:
Jpa默认使用整数顺序值持久化枚举类型;
Mysql中枚举类型Color定义取值的顺序是RED、GREEN、BLUE
,因此,当这三个取值持久化到数据库表时,取值分别是0、1、2;
意思就是我们这里存往数据库的数据是0、1、2这样的数字,而不是RED、GREEN、BLUE
字符串,但是Mysql数据库中定义的是RED、GREEN、BLUE
,并没有其它值所以报错
解决:在entity中使用@Enumerated(EnumType.STRING)
标注你的枚举类型属性,如果标注,默认是integer。
在JPA中使用@Enumerated(EnumType.STRING)
,这种是推荐的方法。
建表语句
CREATE TABLE test4 ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, brand VARCHAR(255) NOT NULL, color ENUM('RED','GREEN','BLUE') ) ENGINE = InnoDB;
Java代码中,枚举类
public enum Color { RED, GREEN, BLUE }
Java代码中,Javabean
@Entity @Table(name="test4") public class ClothesRight { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Enumerated(EnumType.STRING) private Color color; private String brand; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public ClothesRight(Long id, Color color, String brand) { super(); this.id = id; this.color = color; this.brand = brand; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } public ClothesRight() { super(); } }
简单使用
public interface Test4RightRepository extends JpaRepository<clothesright>{ }</clothesright>
@Autowired private Test4RightRepository t4R;/** * 使用@Enumrated()标注字段为枚举的数据 * 结果 正确插入RED */ @GetMapping(value="/addclothesright") public void GetTest4Right(){ List<clothesright> entities = new ArrayList(); ClothesRight clothes = new ClothesRight(); //clothes.setId(1L); clothes.setBrand("佐丹奴"); clothes.setColor(Color.RED); entities.add(clothes); t4R.save(entities); }</clothesright>
结果为:
mysql枚举的字段类型不宜插入数字,但是需求就是要用数字,怎么办?
解决:mysql数据类型定义为int,枚举限定在java代码中解决
建表语句
CREATE TABLE test5num ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, used int(11) DEFAULT NULL COMMENT '0:没用过 1:已用过 2:不能用' )ENGINE = InnoDB;
Java代码
@Entity@Table(name="test5num")public class Test5Num { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; private Used used; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Used getUsed() { return used; } public void setUsed(Used used) { this.used = used; } public Test5Num() { super(); } public Test5Num(Long id, Used used) { super(); this.id = id; this.used = used; } }
/** *枚举类 */public enum Used { UNUSED(0,"没用过"), USED(1,"已用过"), FORBIDDEN(2,"不能用"); private Integer code; private String discribe; public Integer getCode() { return code; } public String getDiscribe() { return discribe; } private Used(Integer code, String discribe) { this.code = code; this.discribe = discribe; }}
/** * dao层 */public interface Test5NumRepository extends JpaRepository<test5num>{ }</test5num>
@Autowiredprivate Test5NumRepository t5N; /** * mysql枚举的字段类型不宜插入数字,但是需求就是要用数字,怎么办? * 解决:mysql数据类型定义为int,枚举限定在java代码中解决 * */@GetMapping("/test5insert")public void insertT5(){ Test5Num t5 = new Test5Num(); t5.setUsed(Used.USED); List<test5num> list = new ArrayList<test5num>(); list.add(t5); t5N.save(list);}</test5num></test5num>
可以使用enum类型存放例如订单状态、用户性别等数据类型,mysql底层会对枚举值进行压缩并按照枚举顺序转换成10进制顺序位存储。
程序在保存enum字段数据时,直接保存enum字符串。要注意0
和'0'
的区别。
enum定义完成以后不要随便删除,也不对对已经在使用的enum值进行修改。
使用alert语句修改enum的规范是后面添加而不是在首部后者中间插入或者修改。
推荐学习: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!