Mysql の Enum データ型を 1 つの記事でマスターする

WBOY
リリース: 2022-07-19 14:04:32
転載
5495 人が閲覧しました

この記事では、mysql に関する関連知識を提供します。主に Enum データ型に関連する問題を整理します。Mysql の enum 型は、よく列挙型と呼ばれるものです。その値の範囲には、必要な値が必要です。テーブル作成時に列挙(1つずつ列挙)して明示的に指定する必要がありますので、見ていきましょう。

Mysql の Enum データ型を 1 つの記事でマスターする

推奨学習: mysql ビデオ チュートリアル

Mysql の列挙型は、よく列挙型と呼ばれるものであり、その値の範囲は、テーブルの作成時に列挙 (1 つずつリスト) によって明示的に指定する必要があります。 1 ~ 255 メンバーの列挙には 1 バイトのストレージが必要です。255 ~ 65535 のメンバーには 2 バイトのストレージが必要です。最大 65535 人のメンバーが許可されます。

enum の最下層には、1、2、3、4、5... の順序で厳密に配置された 10 進整数が格納されます。数値の格納には enum を使用しないでください。

一般的に使用される文字列型の代わりに列挙型を使用できる場合があります。列挙型カラムでは、一部の非反復文字列を事前定義されたセットに格納できます。MySQL が列挙型を格納する場合、非常にコンパクトで、1 または 2 に圧縮されます。リスト値 の数に応じて 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'
ログイン後にコピー

上記からわかるように、フィールドの列挙値は次のようになります。 mysql のデータ構造 配列内で添字が 1 から計算されると、次のように結論付けられます:

1. これは、ステートメント 1 および 2 などの正しい列挙値を通じてデータベースに挿入できます。 ;

2. 次のような正しい添字を使用してデータベースに挿入できます: No. 3 および 4 のステートメント;

3. '0' を挿入すると、 No. 6 ステートメント;

4. number 0 または 'unknown' を挿入すると、実行エラーが発生します。ステートメント 5 と 7 など。

クエリデータ

クエリを実行すると、以下のSQL文の実行結果のように、「列名0」を介して列挙型の変更された値の位置関係を取得できます

SELECT id,sex,sex+0 from `mytest` ;
ログイン後にコピー

クエリ結果は次のとおりです:

Mysql の Enum データ型を 1 つの記事でマスターする

列挙型を変更します

列挙型を減らします

使用ALTER TABLE mytest MODIFY COLUMN sex enum('male '); ステートメントは列挙型を減らすことができます。特殊なケースでは、列挙値がレコード行で使用されている場合、[1265] Data truncated for column エラーが発生します。が発生します。

列挙名を変更する

列挙型を減らすのと同じように、列挙値がレコード行で使用されていないことを確認する必要があります

列挙型をヘッダーに挿入します

ALTER TABLE mytest MODIFY COLUMN sex enum('unknown','male',' Female'); ステートメントを使用して、ヘッダーに列挙を挿入します。 **ヘッダーに列挙型を挿入すると、列挙型の位置関係が変わります。 **先頭に列挙を挿入すると、列挙と位置の関係が後方に移動します。

以下に示すように、挿入前の結果:

Mysql の Enum データ型を 1 つの記事でマスターする

以下に示す、挿入後の結果:

Mysql の Enum データ型を 1 つの記事でマスターする

列挙を途中に組み込みます

使用 ALTER TABLE mytest MODIFY COLUMN sex enum(' Male','Unknown',' Female');Statement中央に列挙を挿入します。 **の途中に列挙型を挿入すると、列挙型の位置関係が変わります。 **列挙を途中に挿入すると、列挙と挿入位置以降の位置との関係が後方に移動します。

以下に示すように、挿入前の結果:

Mysql の Enum データ型を 1 つの記事でマスターする

以下に示す、挿入後の結果:

Mysql の Enum データ型を 1 つの記事でマスターする

末尾に列挙を挿入します (推奨)

ALTER TABLE mytest MODIFY COLUMN sex enum('male',' Female','unknown'); ステートメントを使用して、列挙を挿入します。最後に列挙。 ** の最後に列挙を挿入しても、列挙値と位置の関係は変わりません。 **変更がないため、写真はここには表示されません。

列挙型使用の罠

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 データ型を 1 つの記事でマスターする

插入数字例子(不推荐)

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 データ型を 1 つの記事でマスターするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート