>  기사  >  데이터 베이스  >  한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.

한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.

WBOY
WBOY앞으로
2022-07-19 14:04:325440검색

이 기사에서는 Enum 데이터 유형과 관련된 문제를 주로 정리하는 mysql에 대한 관련 지식을 제공합니다. Mysql의 열거형 유형은 우리가 흔히 열거형 유형이라고 부르는 것이며 해당 값 범위는 테이블이 명시적으로 생성되기 전에 생성되어야 합니다. 열거형(하나씩 나열)을 통해 지정해 보도록 하겠습니다. 모두에게 도움이 되기를 바랍니다.

한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.

추천 학습: mysql 비디오 튜토리얼

Mysql의 열거형 유형은 테이블을 생성할 때 열거형(하나씩 나열)을 명시적으로 지정해야 하는 것입니다. 1~255명의 구성원을 열거하려면 1바이트의 저장 공간이 필요하고, 255~65535명의 구성원을 열거하려면 2바이트의 저장 공간이 필요합니다. 최대 65535명의 구성원이 허용됩니다.

enum의 맨 아래 레이어는 1, 2, 3, 4, 5의 순서로 엄격하게 배열된 십진 정수를 저장합니다. 숫자를 저장하는 데 enum을 사용하지 마세요.

때때로 일반적으로 사용되는 문자열 유형 대신 열거형을 사용할 수 있습니다. 열거형 열은 일부 고유한 문자열을 미리 정의된 세트에 저장할 수 있습니다. MySQL은 열거형을 저장할 때 매우 컴팩트하며 1로 압축된 수량을 기반으로 합니다. 또는 2바이트 . MySQL은 내부적으로 목록의 각 값의 위치를 ​​정수로 저장하고, "숫자-문자열" 매핑 관계의 "조회 테이블"을 .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` ;

查询结果如下:

한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.

修改枚举

减少枚举类型

使用ALTER TABLE mytest MODIFY COLUMN sex enum('男');语句可以减少枚举类型,特殊情况下如果枚举值在记录行中已被使用则会出现[1265] Data truncated for column错误。

修改枚举名称

和减少枚举类型情况一样,必须确保枚举值没有被记录行使用

首部插入枚举

使用ALTER TABLE mytest MODIFY COLUMN sex enum('未知','男','女');语句在首部插入一个枚举。在**首部插入枚举会引起枚举的位置关系发生改变。**在首部插入枚举会导致枚举和位置的关系都向后移动。

如下图,插入之前的结果:

한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.

如下图,插入之后的结果:

한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.

中间掺入枚举

使用ALTER TABLE mytest MODIFY COLUMN sex enum('男','未知','女');语句在中间插入一个枚举。在**中间插入枚举会引起枚举的位置关系发生改变。**在中间插入枚举会导致插入位置后的枚举和位置的关系都向后移动。

如下图,插入之前的结果:

한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.

如下图,插入之后的结果:

한 기사로 MySQL의 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;
데이터 삽입
public enum Color {
  RED,  
  GREEN,  
  BLUE  
}
위에서 알 수 있듯이 필드에 있는 enum 값은 mysql의 데이터 구조에 있는 배열과 유사하며 첨자는 1부터 계산된다. , 다음과 같이 요약됩니다.
  • 1. 다음과 같은 올바른 열거 값을 통해 데이터베이스에 삽입할 수 있습니다.

    2. 3과 같은 올바른 아래 첨자를 통해 데이터베이스에 삽입할 수 있습니다. 및 4개의 문;

    3. '0'을 삽입하면 빈 문자열로 저장됩니다(예: 문 6). 숫자 0 또는 '알 수 없음' Code>문 5, 7과 같은 작업을 수행할 때 실행 오류가 발생합니다. 🎜🎜쿼리 데이터🎜🎜쿼리 시 "열명 + 0"으로 열거형에서 변경된 값의 위치 관계를 얻을 수 있습니다. 다음 SQL 문 실행 결과🎜
    @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();
     }
        }
    🎜쿼리 결과는 다음과 같습니다. 🎜🎜한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.🎜🎜수정 eration🎜

    열거 유형 줄이기 🎜열거 유형을 줄이려면 ALTER TABLE mytest MODIFY COLUMN sex enum('male'); 문을 사용하세요. 특별한 경우, 레코드 줄에 열거 값이 사용된 경우 [ 1265가 나타납니다] 열의 데이터가 잘렸습니다오류. 🎜

    열거 이름 수정

    🎜열거 유형을 줄이는 것과 마찬가지로 레코드 행에서 열거 값을 사용하지 않도록 해야 합니다.🎜

    헤더에 열거 삽입

    🎜사용 ALTER TABLE mytest MODIFY COLUMN sex enum('unknown','male','female');이 문은 헤더에 열거형을 삽입합니다. ** 헤더에 열거형을 삽입하면 열거형의 위치 관계가 변경됩니다. **앞부분에 열거형을 삽입하면 열거형과 위치의 관계가 뒤로 이동하게 됩니다. 🎜🎜아래와 같이 이전 결과를 삽입하세요: 🎜🎜한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요. 🎜🎜아래와 같이 삽입 후 결과: 🎜🎜 image- 20220712104318213🎜

    열거를 중간에 통합

    🎜 ALTER TABLE mytest MODIFY COLUMN sex enum('male','unknown','female'을 사용하세요. ); 문은 중간에 열거형을 삽입합니다. ** 중간에 열거형을 삽입하면 열거형의 위치 관계가 변경됩니다. **열거를 중간에 삽입하면 열거와 삽입 위치 다음 위치의 관계가 뒤로 이동합니다. 🎜🎜아래와 같이 이전 결과를 삽입하세요: 🎜🎜한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요. 🎜🎜아래와 같이 삽입 후 결과: 🎜🎜 image- 20220712104704714🎜

    끝에 열거 삽입(권장)

    🎜 ALTER TABLE mytest MODIFY COLUMN sex enum('male','female','unknown');을 사용하세요. code> 문 끝에 열거형을 삽입합니다. ** 끝에 열거형을 삽입하면 열거형 값과 위치 사이의 관계가 변경되지 않습니다. **변경사항이 없으므로 여기에는 사진이 표시되지 않습니다. 🎜🎜열거 유형 사용 시 함정🎜🎜🎜1. mysql에서 특정 필드 유형을 열거형으로 설정하는 것은 권장되지 않지만 저장된 값은 '0', '1', '2'와 같은 숫자입니다🎜. 🎜🎜🎜 🎜🎜설명 1: 🎜 enum은 첨자를 통해 값을 가져올 수 있기 때문에 혼란을 야기할 수 있지만, 첨자는 1부터 시작합니다. 이 필드에 익숙하지 않은 사람들을 위해 여기에 오류가 있습니다🎜
  • 解释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의 Enum 데이터 유형을 마스터하세요.

插入数字例子(不推荐)

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视频教程

위 내용은 한 기사로 MySQL의 Enum 데이터 유형을 마스터하세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제