這篇文章為大家帶來了關於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` ;
查詢結果如下:
使用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('男','女','未知');### 語句在尾部插入一個枚舉。在**尾部插入枚舉不會引起枚舉值和位置關係的任何變化。 **由於沒有任何變化這裡就不上圖了。 ######枚舉類型使用陷阱#########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枚举的字段类型不宜插入数字,但是需求就是要用数字,怎么办?
解决: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中文網其他相關文章!