你真的知道数据是如何存储的吗

48 阅读6分钟

在现代应用程序中,数据存储是关键的环节。本文将探讨一般的数据存储方式:数据库对象存储服务。文章从数据库、对象存储服务概念的解释和二者的关系为脉络梳理数据的存储方式。

数据库

数据库的分类

关系型数据库

根本特点

  • 使用表格结构组织数据,数据按行和列存储。
  • 数据表有固定的模式(schema),需在存储数据之前定义字段。

存储格式

  • 表格:
    • 每行代表一个记录。
    • 每列代表一个字段。
  • 存储对象:
    • 结构化数据。 例如: Users 表(用户信息)
UserIDUserNameEmailCreatedAt
1Alicealice@example.com2024-09-15 14:22
2Bobbob@example.com2024-09-15 15:30

非关系型数据库

根本特点

  • 支持多种数据模型,如文档键值列族,允许更灵活的数据存储和处理方式。
  • 通常没有固定的模式,数据在存储时具有动态和灵活的结构。

存储对象

  • 非结构化数据。
  • 半结构化数据。

存储格式

1. 键值存储
  • 以键值对存储数据。
  • 适合快速的简单数据访问和缓存需求。
示例: Redis
  • 场景: 缓存系统。
  • 示例数据: 用户信息。
  • : "user:1234"
  • : { "name": "John Doe", "age": 30 }
  • 操作: 通过键 "user:1234" 快速检索用户信息。
2. 文档存储
  • 数据以 JSONBSON 等文档形式存储。
  • 适合灵活的数据结构和复杂的数据层次,支持嵌套数据。
示例: MongoDB
  • 场景: 内容管理系统。
  • 示例数据: 博客。
  • 文档:
{
  "_id": "article_1",
  "title": "Introduction to MongoDB",
  "author": "Jane Doe",
  "content": "MongoDB is a NoSQL database...",
  "tags": ["database", "NoSQL"],
           "published_date": "2024-09-01"
 }
  • 操作: 通过 _id 检索文章,或通过查询字段(如 tags、published_date)搜索。
3. 列存储
  • 以列为存储单位。
  • 适合大规模数据存储和分析,特别是在分布式环境中
  • 当执行查询时,列存储数据库只读取涉及的列数据,而不是整行数据。这样可以减少I/O操作和提高查询性能。
示例

数据表:

       lua
       复制代码
       | ID | Name | Age | Salary |
       |----|------|-----|--------|
       | 1  | Alice| 30  | 70000  |
       | 2  | Bob  | 25  | 50000  |
       | 3  | Carol| 35  | 80000  |

列块存储:

  • ID 列块: [1, 2, 3]
  • Name 列块: ["Alice", "Bob", "Carol"]
  • Age 列块: [30, 25, 35]
  • Salary 列块: [70000, 50000, 80000]
4. 图存储
  • 以图为存储单位。
  • 适合处理复杂关系数据和图结构分析。
示例: Neo4j
  • 场景: 社交网络。
  • 示例数据: 社交网络用户和他们的关系。
  • 节点: 用户 A:
        {
          "id": "user_1",
          "name": "Alice",
          "age": 29
        }

用户 B:

        {
          "id": "user_2",
          "name": "Bob",
          "age": 31
        }
  • : 友谊关系:
        {
          "from": "user_1",
          "to": "user_2",
          "type": "friend",
          "since": "2022-01-01"
        }
  • 操作: 使用图查询语言(如 Cypher)查询用户的朋友或分析用户之间的复杂关系。

数据的类型

结构化数据:

  • 定义: 高度组织化的数据,具有清晰的字段和定义。
  • 存储方式: 关系型数据库。

半结构化数据:

  • 定义: 介于结构化数据和非结构化数据之间,包含一些标签、元数据或键值对帮助标记数据关系。常见的例子包括 JSONXML
  • 示例:
    {
      "UserID": 1,
      "Name": "Alice",
      "ContactInfo": {
        "Email": "alice@example.com",
        "Phone": "123-456-7890"
      }
    }
    

非结构化数据

  • 定义: 没有固定格式或组织的数据,通常是非文本形式的,例如图片、视频、音频文件、社交媒体内容等。
  • 存储方式: 对象存储服务、非关系型数据库。

数据库的部署方式

  • 本地部署:

    • 部署在中心服务器。
  • 分布式部署:

    • 数据分布在多个地理位置的数据中心中,提供跨地域的高可用性和低延迟访问。
  • 云数据库:

    • 部署在云计算环境中,由云服务提供商负责硬件基础设施和软件的管理、维护、扩展等工作。

对象存储服务器

作用

存储大量非结构化体积大的数据的仓库,如图片、视频、音频、备份文件、日志等,没有复杂的数据查询和操作功能

存储单位

数据以对象形式存储,每个对象包括文件数据元数据唯一标识符

访问方式

每个对象基于唯一的 URL 来访问,可以下载、解析数据。

部署

  • 云对象存储: 数据分布在多个地理位置,用户通过网络(HTTP/HTTPS)访问。
  • 本地对象存储: 在本地数据中心部署对象存储系统(如 MinIO、Ceph)。

数据库 VS 对象存储服务

区别

存储对象

  • 数据库: 一般存储结构化/半结构化数据。
  • 对象存储服务: 大型非结构化数据。

存储大小

  • 数据库: 不适合存储过大数据,成本高。
  • 对象存储服务: 专门存储大型文件。

功能

  • 数据库: 管理和存储动态数据。
  • 对象存储服务: 存储静态数据。

访问方式

  • 数据库: 查询语言。
  • 对象存储服务: URL。

扩展方式

  • 数据库: 提高硬件能力。
  • 对象存储服务: 增加节点(服务器)。

性能

  • 数据库: 依赖于硬件,提供复杂功能。
  • 对象存储服务: 依赖于网络带宽,专注于传输数据。

二者合作的应用

  • 数据库存储结构化数据,对象存储服务存储非结构化数据的实际内容。
  • 数据库:存储产品信息
   CREATE TABLE Products (
       ProductID INT PRIMARY KEY,
       ProductName VARCHAR(255),
       ProductDescription TEXT,
       ImageURL VARCHAR(255)  -- 存储图片在对象存储中的URL
   );
  • 对象存储:存储产品图片
    • 上传产品图片到对象存储服务(如 AWS S3)
    • 图片的 URL 被存储在数据库中的 ImageURL 列中
    • 图片示例 URL: https://example-bucket.s3.amazonaws.com/product123.jpg

为什么数据库不直接存储资源的二进制数据?

存储大文件(如图片、视频)的二进制数据会显著增加数据库的大小,导致数据库性能下降。而且非结构化数据资源往往是静态的,不需要频繁操作。使用对象存储服务后,数据库仅需存储URL就可以访问资源。同时,大型资源存储在对象存储服务更加经济。

结语

  • 除了数据库和对象存储服务,数据还可以存储在文件系统、CDN、内存、日志...
  • 数据库和对象存储服务各有专长,它们针对不同类型的数据提供了高效的存储和管理方式。数据库更适合存储和处理结构化动态数据和复杂操作,而对象存储服务则擅长存储大规模非结构化静态数据。在现代应用中,二者通常协同工作,分别处理不同类型的数据需求,从而使系统具备更好的灵活性、扩展性和性能。