区别

列式存储(Column-Oriented Storage)和行式存储(Row-Oriented Storage)是数据库管理系统中两种主要的数据存储方式,它们的主要区别在于如何在磁盘上组织和存储表中的数据:

行式存储(Row-Oriented Storage)

  • 特点
  • 数据以行为单位进行存储,同一行的所有字段值紧密地存储在一起。
  • 在读取包含多个列但只需要其中少数几个列的记录时,会同时加载不需要的冗余列数据到内存中。
  • 行存适用于事务型工作负载,频繁进行增删改查操作且涉及整行数据的操作场景,如OLTP系统(联机事务处理)。
  • 对于需要一次性处理整个实体(即一行)的查询来说,行存有较好的性能表现。

列式存储(Column-Oriented Storage)

  • 特点
  • 数据以列为单位进行存储,同一列的所有数据连续存放,不同列的数据分开存储。
  • 在读取数据时,只需要从磁盘读取所需的列,而不必读取整行数据,从而大大减少I/O开销,尤其适合分析型查询。
  • 列存对于大数据量、复杂聚合查询以及BI分析等需求特别有利,因为它可以高效地对单个或少数几列进行扫描和压缩,显著提升大规模数据分析性能。
  • 因为每列数据类型相同,列存能够更有效地进行数据压缩,降低存储空间占用。
  • 写入性能相比行存可能较低,尤其是涉及全行更新的时候,因为需要单独写入每一列。

总结起来,行式存储更适合于事务密集型应用,而列式存储则在分析密集型和大量读取查询的应用中有更好的表现。现代数据库系统往往支持混合模式或者根据实际查询需求动态调整存储策略,以达到最佳性能。

示例

举例说明行存和列存的区别:

假设有一个包含以下字段的用户表 users

CREATE TABLE users (
    id INT,
    name VARCHAR(100),
    age INT,
    gender CHAR(1),
    occupation VARCHAR(50),
    last_login TIMESTAMP
);

行式存储(Row-Oriented Storage)
在行式存储中,数据会这样排列:

| id | name     | age | gender | occupation | last_login       |
|----|----------|-----|--------|------------|------------------|
| 1  | Alice    | 25  | F      | Developer  | 2022-01-01 10:00 |
| 2  | Bob      | 30  | M      | Designer   | 2022-01-02 14:30 |
| ...| ...      | ... | ...    | ...        | ...              |

如果进行一个查询,例如获取所有用户的年龄分布:

SELECT age, COUNT(*) FROM users GROUP BY age;

在这种情况下,即使只需要age这一列的数据,行存数据库仍需要加载整行数据,包括名字、性别、职业和最后登录时间等无关信息。

列式存储(Column-Oriented Storage)
在列式存储中,数据按列分开存储:

// Age 列
| age |
|-----|
| 25  |
| 30  |
| ... |

// Name 列
| name     |
|----------|
| Alice    |
| Bob      |
| ...      |

// 其他列同样独立存储...

对于上述相同的查询,在列存数据库中,只需要读取并扫描“age”这一列的数据即可完成统计,无需加载其他无关列,大大减少了磁盘I/O和内存使用,提高查询效率。尤其当表中有大量数据且只需处理少数几列时,列存的优势更为明显。