Skip to content
RuaRuan
返回

基于 CalDAV 的日程管理系统数据库设计

设计一套基于 CalDAV 的日程管理系统数据库

基于 CalDAV 的日程管理系统数据库设计

1. 设计目标

2. 核心实体与关系

3. 表结构设计

3.1 用户表(users)

存储用户账户信息。

CREATE TABLE users (
    id            SERIAL PRIMARY KEY,
    username      VARCHAR(255) NOT NULL UNIQUE,
    password      VARCHAR(255) NOT NULL,        -- 存储哈希密码
    display_name  VARCHAR(255),
    email         VARCHAR(255) UNIQUE,
    created_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- 索引
CREATE INDEX idx_users_username ON users(username);

3.2 日历表(calendars)

每个日历对应一个 WebDAV 集合(collection)。

CREATE TABLE calendars (
    id            SERIAL PRIMARY KEY,
    user_id       INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name          VARCHAR(255) NOT NULL,        -- 日历的唯一标识(路径后缀)
    display_name  VARCHAR(255),                 -- 显示名称
    description   TEXT,                         -- 描述
    color         VARCHAR(7) DEFAULT '#3788d8', -- 颜色(HEX)
    ctag          VARCHAR(255) NOT NULL,        -- 集合同步标记(sync token)
    created_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(user_id, name)                      -- 同一用户下日历名称唯一
);

-- 索引
CREATE INDEX idx_calendars_user_id ON calendars(user_id);

3.3 日历对象表(calendar_objects)

存储每个日历中的事件、待办等资源。

CREATE TABLE calendar_objects (
    id                      SERIAL PRIMARY KEY,
    calendar_id             INTEGER NOT NULL REFERENCES calendars(id) ON DELETE CASCADE,
    resource_uri            VARCHAR(255) NOT NULL UNIQUE,  -- 资源标识符(如 uuid.ics)
    icalendar_data          TEXT NOT NULL,                 -- 完整的 iCalendar 数据
    etag                    VARCHAR(255) NOT NULL,         -- 实体标记(用于条件请求)
    summary                 TEXT,                          -- 摘要(从 iCalendar 提取,便于快速查询)
    start_time              TIMESTAMP WITH TIME ZONE,      -- 事件开始时间
    end_time                TIMESTAMP WITH TIME ZONE,      -- 事件结束时间
    recurrence_rule         TEXT,                          -- RRULE(重复规则)
    recurrence_exceptions   TEXT[],                        -- 异常日期列表(EXDATE)
    created_at              TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at              TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- 索引
CREATE INDEX idx_calendar_objects_calendar_id ON calendar_objects(calendar_id);
CREATE INDEX idx_calendar_objects_start_time ON calendar_objects(start_time);
CREATE INDEX idx_calendar_objects_end_time ON calendar_objects(end_time);
CREATE INDEX idx_calendar_objects_summary ON calendar_objects(summary) WHERE summary IS NOT NULL;

3.4 日历共享表(calendar_shares)

支持将日历共享给其他用户,并控制访问权限。

CREATE TYPE share_permission AS ENUM ('read', 'write', 'owner');

CREATE TABLE calendar_shares (
    id            SERIAL PRIMARY KEY,
    calendar_id   INTEGER NOT NULL REFERENCES calendars(id) ON DELETE CASCADE,
    user_id       INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    permission    share_permission NOT NULL DEFAULT 'read',
    created_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(calendar_id, user_id)
);

-- 索引
CREATE INDEX idx_calendar_shares_calendar_id ON calendar_shares(calendar_id);
CREATE INDEX idx_calendar_shares_user_id ON calendar_shares(user_id);

4. 设计说明

4.1 数据一致性

4.2 同步支持

4.3 查询优化

4.4 重复事件处理

4.5 扩展性考虑

5. 示例 SQL(PostgreSQL)

-- 创建数据库
CREATE DATABASE caldav_scheduler;

-- 连接到数据库
\c caldav_scheduler;

-- 创建用户表
CREATE TABLE users (
    id            SERIAL PRIMARY KEY,
    username      VARCHAR(255) NOT NULL UNIQUE,
    password      VARCHAR(255) NOT NULL,
    display_name  VARCHAR(255),
    email         VARCHAR(255) UNIQUE,
    created_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- 创建日历表
CREATE TABLE calendars (
    id            SERIAL PRIMARY KEY,
    user_id       INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name          VARCHAR(255) NOT NULL,
    display_name  VARCHAR(255),
    description   TEXT,
    color         VARCHAR(7) DEFAULT '#3788d8',
    ctag          VARCHAR(255) NOT NULL,
    created_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(user_id, name)
);

-- 创建日历对象表
CREATE TABLE calendar_objects (
    id                      SERIAL PRIMARY KEY,
    calendar_id             INTEGER NOT NULL REFERENCES calendars(id) ON DELETE CASCADE,
    resource_uri            VARCHAR(255) NOT NULL UNIQUE,
    icalendar_data          TEXT NOT NULL,
    etag                    VARCHAR(255) NOT NULL,
    summary                 TEXT,
    start_time              TIMESTAMP WITH TIME ZONE,
    end_time                TIMESTAMP WITH TIME ZONE,
    recurrence_rule         TEXT,
    recurrence_exceptions   TEXT[],
    created_at              TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at              TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- 创建枚举类型
CREATE TYPE share_permission AS ENUM ('read', 'write', 'owner');

-- 创建日历共享表
CREATE TABLE calendar_shares (
    id            SERIAL PRIMARY KEY,
    calendar_id   INTEGER NOT NULL REFERENCES calendars(id) ON DELETE CASCADE,
    user_id       INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    permission    share_permission NOT NULL DEFAULT 'read',
    created_at    TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(calendar_id, user_id)
);

-- 创建索引(根据需要添加)
CREATE INDEX idx_calendars_user_id ON calendars(user_id);
CREATE INDEX idx_calendar_objects_calendar_id ON calendar_objects(calendar_id);
CREATE INDEX idx_calendar_objects_start_time ON calendar_objects(start_time);
CREATE INDEX idx_calendar_objects_end_time ON calendar_objects(end_time);
CREATE INDEX idx_calendar_objects_summary ON calendar_objects(summary) WHERE summary IS NOT NULL;
CREATE INDEX idx_calendar_shares_calendar_id ON calendar_shares(calendar_id);
CREATE INDEX idx_calendar_shares_user_id ON calendar_shares(user_id);

6. 注意事项

此数据库设计为基于 CalDAV 的日程管理系统提供了稳固的基础,兼顾了性能、扩展性和协议兼容性。



上一篇
RFC 5545 属性体系详解
下一篇
Kotlin Multiplatform (KMP) 中,如何实现跨平台权限请求?