MySQL - MySQL 8.0(三)进阶操作:生成列(generated column)

生成列(generated column)的值是根据列定义中包含的表达式计算得出的。 生成列包含下面两种类型: virtual(虚拟):当从表中读取记录时,将动态计算该列。 stored(存储):当向表中写入...

生成列(generated column)的值是根据列定义中包含的表达式计算得出的。 生成列包含下面两种类型:


virtual(虚拟):当从表中读取记录时,将动态计算该列。

stored(存储):当向表中写入新记录时,将计算该列并将其存储为常规列。

  virtual生成列比stored生成列更有用,因为一个虚拟的列不占用任何存储空间。你可以使用触发器模拟stored生成列的行为。


举个栗子

1. 创建表时

  假设你的应用程序从t_employees_generated表中检索数据时,使用full_name表示concat(first_name, ' ', last_name),而不是使用表达式来表示,从而实现虚拟列实时计算full_name。

# 创建测试表

mysql> create table if not exists employees.t_employees_generated (

    -> emp_no int(11) not null,

    -> birth_date date not null,

    -> first_name varchar(14) not null,

    -> last_name varchar(16) not null,

    -> gender enum('M', 'F') not null,

    -> hire_date date not null,

    -> full_name varchar(30) as (concat(first_name, ' ', last_name)),

    -> primary key (emp_no),

    -> key name (first_name, last_name)

    -> ) engine=innodb default charset=utf8mb4;

Query OK, 0 rows affected, 1 warning (0.04 sec)

请注意,应该根据虚拟列修改插入语句。你可以这样使用full insert

# 执行插入

mysql> insert into employees.t_employees_generated 

    -> (emp_no, birth_date, first_name, last_name, gender, hire_date) 

    -> values 

    -> (123456, '1987-10-02', 'ABC', 'XYZ', 'F', '2008-07-28');

Query OK, 1 row affected (0.11 sec)


# 验证数据

mysql> select * from employees.t_employees_generated where emp_no = '123456';

+--------+------------+------------+-----------+--------+------------+-----------+

| emp_no | birth_date | first_name | last_name | gender | hire_date  | full_name |

+--------+------------+------------+-----------+--------+------------+-----------+

| 123456 | 1987-10-02 | ABC        | XYZ       | F      | 2008-07-28 | ABC XYZ   |

+--------+------------+------------+-----------+--------+------------+-----------+

1 row in set (0.00 sec)


如果要在INSERT语句中包含full_name,就只能将其指定为DEFAULT

 执行插入

mysql> insert into employees.t_employees_generated 

    -> (emp_no, birth_date, first_name, last_name, gender, hire_date, full_name) 

    -> values 

    -> (123457, '1987-10-02', 'ABC', 'XYZ', 'F', '2008-07-28', DEFAULT);

Query OK, 1 row affected (0.01 sec)


# 验证数据

mysql> select * from employees.t_employees_generated where emp_no = '123457';

+--------+------------+------------+-----------+--------+------------+-----------+

| emp_no | birth_date | first_name | last_name | gender | hire_date  | full_name |

+--------+------------+------------+-----------+--------+------------+-----------+

| 123457 | 1987-10-02 | ABC        | XYZ       | F      | 2008-07-28 | ABC XYZ   |

+--------+------------+------------+-----------+--------+------------+-----------+

1 row in set (0.00 sec)

————————————————


其他值都会引发ERROR 3105 (HY000):错误,不允许在t_employees_generated表中为生成的列full_name指定值:

mysql> insert into employees.t_employees_generated 

    -> (emp_no, birth_date, first_name, last_name, gender, hire_date, full_name) 

    -> values 

    -> (123458, '1987-10-02', 'ABC', 'XYZ', 'F', '2008-07-28', 'TEST');

ERROR 3105 (HY000): The value specified for generated column 'full_name' in table 't_employees_generated' is not allowed.

2. 已有表时

  如果你已经创建了表并希望添加新的生成列,请执行ALTER TABLE语句

# 修改表结构 - 新增生成列

mysql> alter table employees.t_employees_generated add hire_date_year year as (year(hire_date)) virtual;

Query OK, 0 rows affected (0.12 sec)

Records: 0  Duplicates: 0  Warnings: 0


# 验证数据

mysql> select * from employees.t_employees_generated where emp_no = '123456';

+--------+------------+------------+-----------+--------+------------+-----------+----------------+

| emp_no | birth_date | first_name | last_name | gender | hire_date  | full_name | hire_date_year |

+--------+------------+------------+-----------+--------+------------+-----------+----------------+

| 123456 | 1987-10-02 | ABC        | XYZ       | F      | 2008-07-28 | ABC XYZ   |           2008 |

+--------+------------+------------+-----------+--------+------------+-----------+----------------+

1 row in set (0.00 sec)


# 查看表结构

mysql> desc employees.t_employees_generated;

+----------------+---------------+------+-----+---------+-------------------+

| Field          | Type          | Null | Key | Default | Extra             |

+----------------+---------------+------+-----+---------+-------------------+

| emp_no         | int(11)       | NO   | PRI | NULL    |                   |

| birth_date     | date          | NO   |     | NULL    |                   |

| first_name     | varchar(14)   | NO   | MUL | NULL    |                   |

| last_name      | varchar(16)   | NO   |     | NULL    |                   |

| gender         | enum('M','F') | NO   |     | NULL    |                   |

| hire_date      | date          | NO   |     | NULL    |                   |

| full_name      | varchar(30)   | YES  |     | NULL    | VIRTUAL GENERATED |

| hire_date_year | year(4)       | YES  |     | NULL    | VIRTUAL GENERATED |

+----------------+---------------+------+-----+---------+-------------------+

8 rows in set (0.00 sec)

————————————————


  • 发表于 2019-11-08 19:04
  • 阅读 ( 41 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
shitian
shitian

662 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章