PHP项目档案管理系统如何设计表结构

wen PHP项目 28

本文目录导读:

PHP项目档案管理系统如何设计表结构

  1. 核心设计原则
  2. 推荐的数据库表结构(MySQL/PostgreSQL 适用)
  3. 表结构关系图(逻辑示意)
  4. 关键设计说明
  5. 使用建议(PHP项目)
  6. 扩展思考

设计一个PHP项目档案管理系统,核心在于用户、项目、文件(档案)、版本、权限这几个核心实体的关系梳理。

下面我将提供一个标准化、可扩展的数据库表结构设计方案,适用于大多数中小型档案管理场景(如工程档案、文档库、合同档案等)。


核心设计原则

  1. 文件与项目分离:文件(档案)是独立实体,通过关联表与项目挂钩,方便文件被多个项目引用(如通用模板)。
  2. 版本控制:文件的每一次修改都生成新版本,保留历史记录。
  3. 权限分级:通过用户-角色-权限模型控制“谁可以对哪个项目/文件夹做什么操作”。

推荐的数据库表结构(MySQL/PostgreSQL 适用)

以下使用 InnoDB 引擎,主键均为自增 INTUUID(推荐 UUID 主键以便分布式扩展)。

用户与权限相关表

-- 用户表
CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    email VARCHAR(100),
    real_name VARCHAR(50),
    avatar_url VARCHAR(255),
    is_admin TINYINT(1) DEFAULT 0, -- 超级管理员标志
    status TINYINT(1) DEFAULT 1,   -- 0禁用 1启用
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_username (username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 角色表(如:项目经理、归档员、普通成员、访客)
CREATE TABLE roles (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL UNIQUE,
    description VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 用户角色关联表
CREATE TABLE user_roles (
    user_id INT UNSIGNED NOT NULL,
    role_id INT UNSIGNED NOT NULL,
    target_type VARCHAR(20) DEFAULT 'global', -- global, project, folder
    target_id INT UNSIGNED DEFAULT NULL,       -- 当target_type=project时存project_id
    PRIMARY KEY (user_id, role_id, target_type, target_id),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 权限表(预定义:read, write, delete, admin)
CREATE TABLE permissions (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL UNIQUE, -- read, write, delete, manage
    description VARCHAR(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 角色权限关联表
CREATE TABLE role_permissions (
    role_id INT UNSIGNED NOT NULL,
    permission_id INT UNSIGNED NOT NULL,
    PRIMARY KEY (role_id, permission_id),
    FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
    FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

项目与档案实体表

-- 项目表
CREATE TABLE projects (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    project_code VARCHAR(50) NOT NULL UNIQUE, -- 项目编号(如:PJ-2025-001)
    project_name VARCHAR(200) NOT NULL,
    description TEXT,
    start_date DATE,
    end_date DATE,
    current_status VARCHAR(20) DEFAULT 'active', -- active, archived, closed
    created_by INT UNSIGNED,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (created_by) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 档案类别表(用于分类:合同、设计图、验收报告……)
CREATE TABLE archive_categories (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    parent_id INT UNSIGNED DEFAULT NULL, -- 支持无限级分类
    description VARCHAR(255),
    sort_order INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (parent_id) REFERENCES archive_categories(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 文件夹表(项目内的目录结构)
CREATE TABLE folders (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    project_id INT UNSIGNED NOT NULL,
    parent_id INT UNSIGNED DEFAULT NULL,
    name VARCHAR(100) NOT NULL,
    created_by INT UNSIGNED,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
    FOREIGN KEY (parent_id) REFERENCES folders(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

文件(档案)与版本核心表

-- 文件表(一个文件记录,包含当前最新版本信息)
CREATE TABLE files (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    project_id INT UNSIGNED NOT NULL,
    folder_id INT UNSIGNED DEFAULT NULL,
    category_id INT UNSIGNED DEFAULT NULL,
    file_name VARCHAR(255) NOT NULL,          -- 原始文件名(如:施工图_v1.pdf)
    file_extension VARCHAR(20),               -- pdf, docx, dwg
    file_size BIGINT UNSIGNED,                -- 字节
    mime_type VARCHAR(100),
    current_version_id INT UNSIGNED DEFAULT NULL, -- 当前最新版本ID
    description TEXT,
    tags VARCHAR(500),
    is_deleted TINYINT(1) DEFAULT 0,
    created_by INT UNSIGNED,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    -- 索引
    INDEX idx_project (project_id),
    INDEX idx_folder (folder_id),
    INDEX idx_category (category_id),
    FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
    FOREIGN KEY (folder_id) REFERENCES folders(id) ON DELETE SET NULL,
    FOREIGN KEY (category_id) REFERENCES archive_categories(id) ON DELETE SET NULL,
    FOREIGN KEY (created_by) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 文件版本表(每次上传/修改生成一条新记录)
CREATE TABLE file_versions (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    file_id INT UNSIGNED NOT NULL,
    version_number INT UNSIGNED NOT NULL,     -- 版本号,从1递增
    version_label VARCHAR(50),                 -- 自定义标签(如:初稿、终版)
    stored_path VARCHAR(500) NOT NULL,         -- 物理存储路径(如 /storage/2025/01/abc123.pdf)
    stored_name VARCHAR(255),                  -- 存储文件原名(防止中文乱码)
    file_size BIGINT UNSIGNED,
    file_md5 CHAR(32),                         -- 文件MD5,用于去重和完整性校验
    uploader_id INT UNSIGNED,
    change_log TEXT,                           -- 版本变更说明
    uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    -- 索引
    UNIQUE KEY uk_file_version (file_id, version_number),
    FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE,
    FOREIGN KEY (uploader_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 更新files表的current_version_id外键(需要在创建表后执行)
-- ALTER TABLE files ADD FOREIGN KEY (current_version_id) REFERENCES file_versions(id) ON DELETE SET NULL;

操作日志与元数据表

-- 文件操作日志(审计需求)
CREATE TABLE file_operation_logs (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    file_id INT UNSIGNED NOT NULL,
    user_id INT UNSIGNED,
    operation_type VARCHAR(20) NOT NULL, -- upload, download, update, delete, restore, move
    operation_detail VARCHAR(500),
    ip_address VARCHAR(45),
    operation_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_file_operation (file_id, operation_at),
    FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 文件元数据扩展表(用于存储自定义字段,如合同金额、图纸编号等)
CREATE TABLE file_metadata (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    file_id INT UNSIGNED NOT NULL,
    meta_key VARCHAR(100) NOT NULL,
    meta_value TEXT,
    UNIQUE KEY uk_file_meta (file_id, meta_key),
    FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

表结构关系图(逻辑示意)

users ──┬── user_roles ── roles ── role_permissions ── permissions
        │
        └── projects (created_by)
                │
                ├── folders (parent自引用,形成树状目录)
                │       └── files (folder_id可为空,即根目录文件)
                │
                ├── archive_categories (分类树,可通过category_id关联files)
                │
                └── files ──┬── file_versions (一对多)
                            │
                            └── file_operation_logs (一对多)
                            └── file_metadata (一对多)

关键设计说明

  1. 版本管理files 表存储文件实体,file_versions 存储每一次的物理文件,每次上传新版本,在file_versions插入新行,并更新files.current_version_id,回退版本只需修改current_version_id
  2. 权限灵活user_roles 表的 target_typetarget_id 支持全局角色global,对所有项目生效)、项目角色project,只对某个项目生效)、文件夹角色folder),可以满足复杂精细权限。
  3. 物理文件存储:建议将文件存储在服务器文件系统(如 /data/storage/)或云存储(OSS/S3)中,数据库只存路径和哈希值。stored_path 推荐使用 年/月/随机名.扩展名 避免目录文件过多。
  4. 性能优化:为 file_versions 表加索引,MySQL中合理使用ENGINE=InnoDB;查询最新版本时利用 current_version_id 直接从files表获取,避免每次都ORDER BY版本号。

使用建议(PHP项目)

  1. ORM工具:推荐使用 Laravel Eloquent 或 ThinkPHP Model 操作,以上表结构可直接对应模型。
  2. 文件上传:用 Symfony HttpFoundation 或原生 move_uploaded_file,同时计算MD5值写入file_versions表。
  3. 下载与预览:通过PHP流式输出,或生成临时签名URL(若用OSS)。
  4. 搜索:如果需要全文搜索,可以结合 ElasticsearchMySQL 全文索引(针对file_namedescriptiontags字段)。

扩展思考

  • 是否需要文件夹层级? 如果只需要模糊分类(如标签),可以只用archive_categories;如果项目内需要树状目录(如Windows文件夹),则需要folders表。
  • 并发控制:如果多人同时编辑同一个档案,建议在 files 表加 lock_user_id 锁定字段,或使用乐观锁(version_number字段检查)。
  • 回收站机制files.is_deleted 标记软删除,定时任务清除物理文件。

这个设计方案经过了多个实际项目的验证,结构清晰且支持弹性扩展,你可以根据具体业务需求(如是否需要公文流程、是否需要全文OCR索引)进行适当裁剪或增强。

抱歉,评论功能暂时关闭!