首頁 >資料庫 >mysql教程 >一文掌握Mysql中的Enum資料類型

一文掌握Mysql中的Enum資料類型

WBOY
WBOY轉載
2022-07-19 14:04:325539瀏覽

這篇文章為大家帶來了關於mysql的相關知識,其中主要整理了Enum資料類型的相關問題,Mysql中的enum類型就是我們常說的枚舉類型,它的取值範圍需要在建立表格時透過枚舉方式(一個個的列出來)明確指定,下面一起來看一下,希望對大家有幫助。

一文掌握Mysql中的Enum資料類型

推薦學習:mysql影片教學

Mysql中的enum類型就是我們常說的枚舉類型,它的取值範圍需要在建立表格時透過枚舉方式(一個個的列出來)明確指定。 對1至255個成員的枚舉需要1個位元組儲存;對於255至65535個成員,需要2個位元組儲存。最多允許有65535個成員。

enum底層存的是十進制整數,嚴格依序1,2,3,4,5…排列,固千萬不要用enum來存數字。

有時候可以使用枚舉來取代常用的字串類型,而枚舉列可以把一些不重複的字串儲存成一個預先定義的集合,MySQL在儲存枚舉時非常緊湊,會根據列表值的數量壓縮到1個或2個位元組中。 MySQL在內部會將每個值在清單中的位置儲存為整數,並且在.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錯誤。

修改枚舉名稱

和減少枚舉類型情況一樣,必須確保枚舉值沒有被記錄行使用

首部插入枚舉

一文掌握Mysql中的Enum資料類型

一文掌握Mysql中的Enum資料類型

一文掌握Mysql中的Enum資料類型

一文掌握Mysql中的Enum資料類型

#使用ALTER TABLE mytest MODIFY COLUMN sex enum('未知','男','女');

語句在首部插入一個枚舉。在**首部插入枚舉會造成枚舉的位置關係改變。 **在首部插入枚舉會導致枚舉和位置的關係都向後移動。

如下圖,插入先前的結果:

    如下圖,插入之後的結果:
  • 中間摻入枚舉######使用###ALTER TABLE mytest MODIFY COLUMN ###sex### enum('男','未知','女');###語句在中間插入一個枚舉。在**中間插入枚舉會造成枚舉的位置關係改變。 **在中間插入枚舉會導致插入位置後的枚舉和位置的關係都向後移動。 ######如下圖,插入先前的結果:###############如下圖,插入之後的結果:############# ##尾部插入枚舉(推薦)######使用###ALTER TABLE mytest MODIFY COLUMN sex enum('男','女','未知');### 語句在尾部插入一個枚舉。在**尾部插入枚舉不會引起枚舉值和位置關係的任何變化。 **由於沒有任何變化這裡就不上圖了。 ######枚舉類型使用陷阱#########1、超級不建議在mysql中設定某一欄位類型為enum,但是存的值為數字###,例如'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刪除