MySQL 8 教程

MySQL 主页 MySQL 简介 MySQL 功能 MySQL 版本 MySQL 变量 MySQL 下载安装和环境配置 MySQL 管理 MySQL PHP 语法 MySQL Node.js 语法 MySQL Java 语法 MySQL Python 语法 MySQL 连接 MySQL Workbench

MySQL 8 数据库

MySQL 创建数据库 MySQL 删除数据库 MySQL 选择数据库 MySQL 显示数据库 MySQL 复制数据库 MySQL 数据库导出 MySQL 数据库导入 MySQL 数据库信息

MySQL 8 用户

MySQL 创建用户 MySQL 删除用户 MySQL 显示用户 MySQL 更改密码 MySQL 授予权限 MySQL 显示权限 MySQL 撤销权限 MySQL 锁定用户账户 MySQL 解锁用户账户

MySQL 8 表

MySQL 创建表 MySQL 显示表 MySQL 修改表 MySQL 重命名表 MySQL 克隆表 MySQL 截断表 MySQL 临时表 MySQL 修复表 MySQL 描述表 MySQL 添加/删除列 MySQL 显示列 MySQL 重命名列 MySQL 表锁定 MySQL 删除表 MySQL 派生表

MySQL 8 查询

MySQL 查询 MySQL 约束 MySQL INSERT 插入查询 MySQL SELECT 查询 MySQL UPDATE 更新查询 MySQL DELETE删除查询 MySQL REPLACE 替换查询 MySQL 忽略插入 MySQL 重复键更新时插入 MySQL 插入到另一个表语句

MySQL 8 视图

MySQL 创建视图 MySQL 更新视图 MySQL 删除视图 MySQL 重命名视图

MySQL 8 索引

MySQL 索引 MySQL 创建索引 MySQL 删除索引 MySQL 显示索引 MySQL 唯一索引 MySQL 聚集索引 MySQL 非聚集索引

MySQL 运算符和子句

MySQL Where 子句 MySQL Limit 子句 MySQL Distinct 子句 MySQL Order By 子句 MySQL Group By 子句 MySQL Having 子句 MySQL AND 运算符 MySQL OR 或运算符 MySQL LIKE 运算符 MySQL IN 运算符 MySQL ANY 运算符 MySQL Exists 运算符 MySQL NOT 运算符 MySQL NOT EQUAL 运算符 MySQL IS NULL 运算符 MySQL IS NOT NULL 运算符 MySQL Between 运算符 MySQL UNION 运算符 MySQL UNION 与 UNION ALL MySQL MINUS 运算符 MySQL INTERSECT 运算符 MySQL INTERVAL 运算符

MySQL 连接

MySQL 使用连接 MySQL Inner Join 内连接 MySQL LEFT JOIN 左连接 MySQL RIGHT JOIN 右连接 MySQL CROSS JOIN 交叉连接 MySQL 全连接 MySQL 自连接 MySQL Delete Join 删除连接 MySQL UPDATE JOIN 更新连接 MySQL 联合 vs 连接

MySQL 键

MySQL UNIQUE 唯一键 MySQL PRIMARY KEY 主键 MySQL FOREIGN KEY 外键 MySQL 复合键 MySQL 备用键

MySQL 触发器

MySQL 触发器 MySQL 创建触发器 MySQL 显示触发器 MySQL 删除触发器 MySQL 插入前触发器 MySQL 插入后触发器 MySQL 更新前触发器 MySQL 更新后触发器 MySQL 删除前触发器 MySQL 删除后触发器

MySQL 8 数据类型

MySQL 数据类型 MySQL VARCHAR MySQL BOOLEAN MySQL ENUM 枚举 MySQL DECIMAL 十进制 MySQL INT 整数 MySQL FLOAT 浮点数 MySQL BIT 位 MySQL TINYINT 微小整数 MySQL BLOB 二进制大对象 MySQL SET 集合

MySQL 正则表达式

MySQL 正则表达式 MySQL RLIKE 运算符 MySQL NOT LIKE 运算符 MySQL NOT REGEXP 运算符 MySQL regexp_instr() 函数 MySQL regexp_like() 函数 MySQL regexp_replace() 函数 MySQL regexp_substr() 函数

MySQL 全文搜索

MySQL 全文搜索 MySQL 自然语言全文搜索 MySQL 布尔全文搜索 MySQL 查询扩展全文搜索 MySQL ngram 全文解析器

MySQL8 函数和运算符

MySQL 日期和时间函数 MySQL 算术运算符 MySQL 数字函数 MySQL 字符串函数 MySQL 聚合函数

MySQL 8 其他概念

MySQL NULL 值 MySQL 事务 MySQL 序列 MySQL 处理重复项 MySQL SQL 注入 MySQL 子查询 MySQL 注释 MySQL 检查约束 MySQL 存储引擎 MySQL 将表导出为 CSV 文件 MySQL 将 CSV 文件导入数据库 MySQL UUID MySQL 通用表表达式 MySQL 级联删除 MySQL Upsert 操作 MySQL 水平分区 MySQL 垂直分区 MySQL 游标 MySQL 存储函数 MySQL SIGNAL 异常处理 MySQL RESIGNAL 异常处理 MySQL 字符集 MySQL 排序规则 MySQL 通配符 MySQL 别名 MySQL ROLLUP 超级聚合 MySQL 当前日期 MySQL 字面量 MySQL 存储过程 MySQL EXPLAIN 语句 MySQL JSON MySQL 标准差 MySQL 查找重复记录 MySQL 删除重复记录 MySQL 选择随机记录 MySQL 显示进程列表 MySQL 更改列类型 MySQL 重置自动增量 MySQL Coalesce() 函数

MySQL 8 实用资源

MySQL 实用函数 MySQL 语句参考 MySQL 快速指南 MySQL 实用资源 MySQL 讨论


MySQL - ENUM 枚举数据类型

ENUM(枚举器)是一种用户定义的数据类型,它将一系列值存储为字符串。这些值在定义 ENUM 列时指定。用户可以在向此列插入值时从此预定义列表中选择值。

ENUM 列中定义的每个字符串值都会隐式分配一个从 1 开始的数值。MySQL 在内部使用这些数值来表示 ENUM 值。

MySQL ENUM 数据类型

MySQL ENUM 数据类型允许您在插入或更新操作期间从预定义列表中选择一个或多个值。选定的值以字符串形式存储在表中,当您从 ENUM 列检索数据时,这些值将以人类可读的格式呈现。

ENUM 列可以接受各种数据类型的值,包括整数、浮点数、小数和字符串。但是,MySQL 内部会根据其预定义的列表将这些值转换为最接近的 ENUM 值。

语法

以下是在列上定义 ENUM 数据类型的语法 -

CREATE TABLE table_name (  
   Column1,  
   Column2 ENUM ('value1','value2','value3', ...),  
   Column3...  
);

注意:枚举列最多可以包含 65,535 个值。

枚举的属性

MySQL 中的枚举数据类型有三个属性。具体描述如下:

  • 默认值 - 枚举数据类型的默认值为 NULL。如果在插入时未为枚举字段提供任何值,则会插入 Null 值。

  • NULL - 如果为枚举字段设置了此属性,则其作用与默认值相同。如果设置了该属性,索引值始终为 NULL。

  • NOT NULL - 如果枚举字段设置了此属性,但在插入时未提供任何值,MySQL 将生成一条警告消息。

示例

首先,我们创建一个名为 STUDENTS 的表。在此表中,我们使用以下查询在 BRANCH 列中指定 ENUM 字符串对象 -

CREATE TABLE STUDENTS (
   ID int NOT NULL AUTO_INCREMENT,
   NAME varchar(30) NOT NULL,
   BRANCH ENUM ('CSE', 'ECE', 'MECH'),
   FEES int NOT NULL,
   PRIMARY KEY (ID)
);

以下是获得的输出 -

Query OK, 0 rows affected (0.04 sec)

现在,我们检索 STUDENTS 表的结构,发现"BRANCH"字段具有枚举数据类型 -

DESCRIBE STUDENTS;

输出表明 BRANCH 字段的数据类型为 ENUM,存储值 ('CSE', 'ECE', 'MECH') -

Field Type Null Key Default Extra
ID int NO PRI NULL auto_increment
NAME varchar(30) NO NULL
BRANCH enum('CSE','ECE','MECH') YES NULL
FEES int NO NULL

现在,让我们使用以下 INSERT 查询将记录插入 STUDENTS 表 -

INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES
('Anirudh', 'CSE', 500000),
('Yuvan', 'ECE', 350000),
('Harris', 'MECH', 400000);

在这些插入查询中,我们在"BRANCH"字段中使用了值 ('CSE', 'ECE' 和 'MECH'),它们是有效的枚举值。因此,查询执行没有任何错误 -

Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

使用以下查询,我们可以显示表中的所有值 -

SELECT * FROM STUDENTS;

以下是 STUDENTS 表的记录 -

ID NAME BRANCH FEES
1 Anirudh CSE 500000
2 Yuvan ECE 350000
3 Harris MECH 400000

插入带有数字 ENUM 值的记录

我们可以使用相应的数字索引将枚举列表值插入表的 ENUM 列。数字索引从 1 开始,而不是从 0 开始。

示例

在下面的查询中,我们将使用 ENUM 列表中的值"CSE"的数字索引将其插入到"BRANCH"列中。由于"CSE"位于 ENUM 列表中的位置 1,因此我们在查询中使用 1 作为数字索引。

INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES
('Devi', 1, 380000);

输出

插入查询执行无误 -

Query OK, 1 row affected (0.01 sec)

验证

我们使用以下查询检索表中的所有记录来验证上述插入是否成功 -

SELECT * FROM STUDENTS;

STUDENTS 表显示如下 -

ID NAME BRANCH FEES
1 Anirudh CSE 500000
2 Yuvan ECE 350000
3 Harris MECH 400000
4 Devi CSE 380000

插入无效记录

在 MySQL 中,如果我们尝试将值插入到枚举数据类型的列中,而该列与任何指定的枚举值都不匹配,则会导致错误。

示例

在以下查询中,我们引用了枚举列表中的第 6 个值,该值不存在。因此,以下查询将生成错误 -

插入学生 (姓名, 分校, 学费) 值
('Thaman', 6, 200000);

输出

正如我们在输出中看到的,生成了一个错误,并且没有插入任何新记录 -

错误 1265 (01000):第 1 行"BRANCH"列的数据被截断

按数字枚举值过滤记录

在 MySQL 中,您可以根据字符串值或数字索引从枚举列中检索记录。数字索引从 1 开始,而不是 0。

示例

枚举列表中 1 的数字索引是"CSE"。因此,以下查询将获取 BRANCH 列包含值为 'CSE' 的记录。

SELECT * FROM STUDENTS WHERE BRANCH = 1;

输出

结果显示 'BRANCH' 列包含值为 'CSE' 的记录 -

ID NAME BRANCH FEES
1 Anirudh CSE 500000
4 Devi CSE 380000

按人性化可读的 ENUM 值过滤记录

在某些情况下,枚举列表会包含大量值。记住列表中每个值的数字索引可能很困难。在这种情况下,在查询中使用 ENUM 项的人性化可读的字符串值来根据 ENUM 字段的值检索记录会更方便。

示例

在以下查询中,我们将过滤 BRANCH 列包含值"Mech"的记录。

SELECT * FROM STUDENTS WHERE BRANCH = "MECH";

输出

以下是获得的输出 -

ID NAME BRANCH FEES
3 Harris MECH 400000

ENUM 数据类型的缺点

以下是 MySQL 中 ENUM 数据类型的缺点 -

  • 如果我们希望修改枚举列表中的值,则需要使用 ALTER TABLE 命令重新创建完整的表,这在资源和时间方面非常耗时。

  • 获取完整的枚举列表非常复杂,因为我们需要访问 inform_schema 数据库。

  • 表达式不能与枚举值一起使用。例如,以下 CREATE 语句将返回错误,因为它使用了 CONCAT() 函数来创建枚举值 -

CREATE TABLE Students (  
   ID int PRIMARY KEY AUTO_INCREMENT,   
   NAME varchar(30),   
   BRANCH ENUM('CSE', CONCAT('ME','CH'))
);

User variables cannot be used for an enumeration value. For instance, look at the following query −

mysql> SET @mybranch = 'EEE';  
mysql> CREATE TABLE Students (  
   ID int PRIMARY KEY AUTO_INCREMENT,   
   NAME varchar(30),   
   BRANCH ENUM('CSE', 'MECH', @mybranch)
);

建议不要将数值用作枚举值。

使用客户端程序的枚举数据类型

我们也可以使用客户端程序创建枚举数据类型的列。

语法

要通过 PHP 程序创建枚举数据类型的列,我们需要使用 mysqli 函数 query() 执行"CREATE TABLE"语句,如下所示 -

$sql = 'CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ("CSE", "ECE", "MECH"), FEES int NOT NULL, PRIMARY KEY (ID))';
$mysqli->query($sql);

要通过 JavaScript 程序创建枚举类型的列,我们需要使用 mysql2 库的 query() 函数执行"CREATE TABLE"语句,如下所示:-

sql = "CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ('CSE', 'ECE', 'MECH'), FEES int NOT NULL, PRIMARY KEY (ID) )";
con.query(sql);

要通过 Java 程序创建枚举类型的列,我们需要使用 JDBC 函数 execute() 执行"CREATE TABLE"语句,如下所示 -

String sql = "CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM (\"CSE\", \"ECE\", \"MECH\"), FEES int NOT NULL, PRIMARY KEY (ID))";
statement.execute(sql);

要通过 Python 程序创建枚举数据类型的列,我们需要使用 MySQL Connector/Python 的 execute() 函数执行"CREATE TABLE"语句,如下所示 -

sql = 'CREATE TABLE STUDENTS( ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ('CSE', 'ECE', 'MECH'), FEES int NOT NULL, PRIMARY KEY (ID) )'
cursorObj.execute(sql)

示例

以下是程序 -

$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'password';
$dbname = 'TUTORIALS';
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($mysqli->connect_errno) {
    printf("Connect failed: %s
", $mysqli->connect_error); exit(); } //printf('Connected successfully.
'); //create table with boolean column $sql = 'CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ("CSE", "ECE", "MECH"), FEES int NOT NULL, PRIMARY KEY (ID))'; $result = $mysqli->query($sql); if ($result) { printf("Table created successfully...! "); } //将数据插入到创建的表中 $q = "INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES ('Anirudh', 'CSE', 500000), ('Yuvan', 'ECE', 350000)"; if ($res = $mysqli->query($q)) { printf("Data inserted successfully...! "); } //现在显示表记录 $s = "SELECT BRANCH FROM STUDENTS"; if ($r = $mysqli->query($s)) { printf("Select query executed successfully...! "); printf("following records belongs to Enum datatypes: "); while ($row = $r->fetch_assoc()) { printf(" Branch Name: %s", $row["BRANCH"]); printf(" "); } } else { printf('Failed'); } $mysqli->close();

输出

获得的输出如下 -

Table created successfully...!
Data inserted successfully...!
Select query executed successfully...!
following records belongs to Enum datatypes:
 Branch Name: CSE
 Branch Name: ECE         
var mysql = require("mysql2");
var con = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "password",
}); //连接到 MySQL

con.connect(function (err) {
  if (err) throw err;
  //   console.log("Connected successfully...!");
  //   console.log("--------------------------");
  sql = "USE TUTORIALS";
  con.query(sql);
 //create a customers that accepts one column enum type.
  sql = "CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ('CSE', 'ECE', 'MECH'), FEES int NOT NULL, PRIMARY KEY (ID) )";
  con.query(sql);
 //将数据插入到创建的表中
  sql ="INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES ('Anirudh', 'CSE', 500000),  ('Yuvan', 'ECE', 350000)";
  con.query(sql);
  //select datatypes of branch
  sql = `SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'STUDENTS' AND COLUMN_NAME = 'BRANCH'`;
  con.query(sql, function (err, result) {
    if (err) throw err;
    console.log(result);
  });
});  

输出

生成的输出如下 -

[ { DATA_TYPE: 'enum' } ]
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Enum {
   public static void main(String[] args) {
      String url = "jdbc:mysql://localhost:3306/TUTORIALS";
      String username = "root";
      String password = "password";
      try {
         Class.forName("com.mysql.cj.jdbc.Driver");
         Connection connection = DriverManager.getConnection(url, username, password);
         Statement statement = connection.createStatement();
         System.out.println("Connected successfully...!");
        //ENUM data types...!;
         String sql = "CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM (\"CSE\", \"ECE\", \"MECH\"), FEES int NOT NULL, PRIMARY KEY (ID))";
         statement.execute(sql);
         System.out.println("column of a ENUM type created successfully...!");
         ResultSet resultSet = statement.executeQuery("DESCRIBE STUDENTS");
         while (resultSet.next()){
            System.out.println(resultSet.getString(1)+" "+resultSet.getString(2));
         }
         connection.close();
      } catch (Exception e) {
         System.out.println(e);
      }
   }
}  

输出

获得的输出如下所示 -

Connected successfully...!
column of a ENUM type created successfully...!
ID int
NAME varchar(30)
BRANCH enum('CSE','ECE','MECH')
FEES int  
import mysql.connector
# 建立连接
connection = mysql.connector.connect(
    host='localhost',
    user='root',
    password='password',
    database='tut'
)
# 创建游标对象
cursorObj = connection.cursor()
# 创建带有枚举列的表
sql = '''
CREATE TABLE STUDENTS (
ID int NOT NULL AUTO_INCREMENT,
NAME varchar(30) NOT NULL,
BRANCH ENUM ('CSE', 'ECE', 'MECH'),
FEES int NOT NULL,
PRIMARY KEY (ID)
);
'''
cursorObj.execute(sql)
print("The table is created successfully!")
# 需要插入的数据
data_to_insert = [
    ('Anirudh', 'CSE', 500000),
    ('Yuvan', 'ECE', 350000),
    ('Harris', 'MECH', 400000)
]
# 向创建的表中插入数据
insert_query = "INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES (%s, %s, %s)"
cursorObj.executemany(insert_query, data_to_insert)
# 插入操作后提交更改
connection.commit()
print("Rows inserted successfully.")
# 现在显示表记录
select_query = "SELECT * FROM STUDENTS"
cursorObj.execute(select_query)
result = cursorObj.fetchall()
print("Table Data:")
for row in result:
    print(row)
cursorObj.close()
connection.close()  

输出

以下是上述代码的输出 -

The table is created successfully!
Rows inserted successfully.
Table Data:
(1, 'Anirudh', 'CSE', 500000)
(2, 'Yuvan', 'ECE', 350000)
(3, 'Harris', 'MECH', 400000)