什么是生成的列?

发布于

一些数据库管理系统 ( DBMS ) 包含一个称为生成列的功能。

也称为“计算列”,生成列与普通列类似,不同之处在于生成列的值是从计算其他列值的表达式派生的。

换句话说,生成的列的值是从其他列计算出来的。

示例子

这是一个基本示例来演示生成的列是如何工作的。

CREATE TABLE Products( 
    Id INTEGER PRIMARY KEY, 
    Name TEXT,
    Qty INT,
    Price INT,
    TotalValue INT GENERATED ALWAYS AS (Qty * Price)
);

此示例是在SQLite中创建的,并使用 SQLite 语法来创建生成的列。此语法使用GENERATED ALWAYS列约束。

该GENERATED ALWAYS部分在 SQLite 中是可选的,因此您可以只使用AS.

实际上,这GENERATED ALWAYS部分在 MySQL 中也是可选的,甚至在TSQL(SQL Server的SQL扩展)中都没有定义,所以关键字就是你所需要的(连同实际的表达式)。AS

表达式决定了该列将包含的实际值。在我的示例中,读取的部分(Qty * Price)是确定该值的表达式。

在这个示例中,它只是将数量(每种产品的数量)乘以每种产品的价格。

因此,此生成的列包含库存中每个库存的总值。

如果我们插入数据并选择它,我们可以看到生成列的计算值。

INSERT INTO Products VALUES 
  (1, 'Hammer', 10, 9.99),
  (2, 'Saw', 5, 11.34),
  (3, 'Wrench', 7, 37.00),
  (4, 'Chisel', 9, 23.00),
  (5, 'Bandage', 70, 120.00);

SELECT * FROM Products;

结果:

ID 名称 数量 价格 TotalValue —– ———- —– —— ———- 1 锤子 10 9.99 99.9 2 锯 5 11.34 56.7 3 扳手 7 37 259 4 凿子 9 23 207 5 绷带 70 120 8400

如果我们看第一行,我们可以看到有 10 把锤子,每把价格为 9.99。生成的列将这两个值相乘,最终得到 99.9。

如果我们减少锤子的数量,那么生成的列将产生不同的值。

这是一个例子。

UPDATE Products 
SET Qty = 5 WHERE Id = 1;

SELECT * FROM Products;

结果:

ID 名称 数量 价格 TotalValue —– ———- —– —— ———- 1 锤子 5 9.99 49.95 2 锯 5 11.34 56.7 3 扳手 7 37 259 4 凿子 9 23 207 5 绷带 70 120 8400

在这个示例中,我将锤子的数量减少到 5 个,因此生成的列计算出的值为 49.95。

生成列的类型

生成的列有两种类型;存储和虚拟。

一些 DBMS 可能使用稍微不同的术语,例如 SQL Server 使用术语“持久”而不是“存储”。无论哪种方式,它都指的是同一件事。

  • VIRTUAL:不存储列值,但在读取行时评估。
  • STORED:在插入或更新行时评估和存储列值。

STORED因此,列需要存储空间,而VIRTUAL列则不需要。

但是,这也意味着VIRTUAL在读取列时会使用更多的 CPU 周期。

生成列的好处

生成的列可以在编写查询时节省时间、减少错误并提高性能。

生成的列可用作简化和统一查询的一种方式。可以将复杂条件定义为生成的列,然后从表上的多个查询中引用。这有助于确保它们都使用完全相同的条件。

存储的生成列可以用作复杂条件的物化缓存,这些条件在运行时计算成本很高。

生成列的限制

与普通列相比,生成的列通常具有限制,尽管限制的程度可能由 DBMS 确定。

例如,生成的列通常只能从同一行中的列计算值。但是,可以通过使用用户定义的函数作为计算列表达式的一部分来克服这个限制(至少在 SQL Server 中)。

请参阅下面的链接以了解有关在各种 DBMS 中实现生成列的更多信息。

官方文档

以下是一些流行的 DBMS 的文档,其中包括它们实现生成列的限制: