如何实现两列乘积为新列并持久化?建表时该方法是否正确?
嘿,刚好对这个问题很熟,我分两种场景给你详细拆解,顺便帮你判断实现方法的正确性:
一、给现有数据表添加乘积新列并持久化
如果你的表已经存在,想要新增一列存储两列的乘积,直接用数据库原生的持久化生成列是最优解,不同主流数据库的语法略有差异:
MySQL/MariaDB
ALTER TABLE your_table_name ADD COLUMN product_col DECIMAL(12,2) GENERATED ALWAYS AS (col1 * col2) STORED;
GENERATED ALWAYS AS声明这是一个计算生成的列STORED关键字表示该列会被持久化到磁盘,每次col1或col2更新时,数据库会自动同步乘积值
PostgreSQL
ALTER TABLE your_table_name ADD COLUMN product_col NUMERIC(12,2) GENERATED ALWAYS AS (col1 * col2) STORED;
PostgreSQL的语法和MySQL类似,同样用STORED标记持久化
SQL Server
ALTER TABLE your_table_name ADD product_col DECIMAL(12,2) AS (col1 * col2) PERSISTED;
SQL Server用PERSISTED关键字来指定持久化计算列
注意:选择数据类型时要留足余量,比如两个
DECIMAL(8,2)相乘,结果可能需要DECIMAL(12,2)来避免溢出
二、新建数据表时直接定义乘积持久化列
如果是从头建表,直接在表结构里定义乘积列即可,同样用持久化生成列:
MySQL/MariaDB
CREATE TABLE new_product_table ( id INT PRIMARY KEY AUTO_INCREMENT, price DECIMAL(8,2) NOT NULL, quantity INT NOT NULL, total_amount DECIMAL(12,2) GENERATED ALWAYS AS (price * quantity) STORED );
PostgreSQL
CREATE TABLE new_product_table ( id SERIAL PRIMARY KEY, price NUMERIC(8,2) NOT NULL, quantity INT NOT NULL, total_amount NUMERIC(12,2) GENERATED ALWAYS AS (price * quantity) STORED );
SQL Server
CREATE TABLE new_product_table ( id INT PRIMARY KEY IDENTITY(1,1), price DECIMAL(8,2) NOT NULL, quantity INT NOT NULL, total_amount DECIMAL(12,2) AS (price * quantity) PERSISTED );
三、实现方法的正确性判断
如果用上面提到的数据库原生持久化生成列,这个方法是完全正确且推荐的,原因有三点:
- 数据一致性:原列更新时,乘积列会自动同步,不会出现手动计算导致的数值不一致问题
- 查询性能:因为值是持久化到磁盘的,查询时不需要实时计算,速度更快
- 维护成本:不用写额外的触发器、定时任务或业务代码来维护这个列,减少出错概率
如果是手动用UPDATE语句计算后插入值,虽然能实现功能,但属于非规范做法——一旦忘记在更新原列时同步更新乘积列,就会出现数据错误,不建议这么做。
内容的提问来源于stack exchange,提问作者bingaloman




