数据库系统中文件附件保存的最佳办法

本文介绍了一种在数据库系统中高效存储文件的新方法:通过在数据库中仅保存文件元信息,并将实际文件内容存储于指定目录中。此方法适用于各种数据库系统,能够提高备份速度、轻松处理大文件并简化程序开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库系统中文件附件保存的最佳办法

作者: http://blog.csdn.net/jacklondon

 

开发数据库系统的人很多,我相信也有很多人碰到过要将文件保存在数据库中的问题。常见的数据库系统,都有 blob/image/binary 之类的字段类型,用于处理这个问题。

软件开发人员,都会碰到这个问题,也都会被这个问题困住一两个星期。

以 Java/JDK 为例, JDBC 驱动程序中,对这个问题也经过多年、历经多次版本升级,才能解决。而且代码还不能跨数据库。 

C# 也一样,总之是麻烦。

 

其实,这个问题可以有另一思路,更简单,更高效。值得系统架构师们考虑:

 

1. 在数据库中,单独用一个表,处理所有各类文件,只保存文件的信息

 

TT_BINARY_DATA_INFO (bin_uuid, file_size, file_name,data_type,compress_format,memo,created_dt,created_by,updated_dt,updated_by,updated_cnt)

 

上面的表中, compress_format 为文件压缩格式,可以不压缩,也可以用 zip 压缩格式,或者其它。

 

2. 在指定目录中,保存文件内容(按年月划分子目录,或者不分子目录),文件名为 uuid.dat

 

采用这一种方案的原因是,数据库系统通常处理不好二进制数据,要么数据多了很占用磁盘空间,导致数据库性能下降、备份时间更长;要么是文件大了无法保存。而采用以上方案,这些问题都不存在:备份更快了;文件大了也能轻松应付;程序更容易写;不论哪种数据库都可以用。

 

这一解决方案,目前在国内基本无人知晓,但在国外,举例来说,Bugzilla/phpBB 都提供了选项,用户可以把文件内容保存在数据库中、或者保存在指定目录中。并且,它们的文档中,都推荐把文件内容,存放在指定目录中下。想必它们经过认真的对比,发现“把文件内容,存放在指定目录中下”更好吧。我也觉得这种方法更好,自从知道这种解决方法,我把我所负责的项目,都转换成这种方式了,效果很不错。

 

 

 

<think>我们被要求从JIRA中批量导出附件文件。根据引用[1],我们知道JIRA附件默认存储在服务器的文件系统路径中(例如`/var/atlassian/application-data/jira/data/attachments`),并且每个项目的附件按项目键和问题键组织。同时,引用[2]提到在导入数据时,附件可以通过FILE协议访问Jira主目录下的`import/attachments`子目录,但这里我们关注的是导出。 批量导出JIRA附件的步骤: 1. **确定附件存储位置**: 首先,我们需要确认JIRA附件的存储路径。根据引用[1],可以通过JIRA管理界面查看: - 登录JIRA管理员账户。 - 进入右上角的“系统”→“高级”→“附件”,查看附件存储路径(通常为文件系统路径)。 2. **备份附件**: 由于附件存储在文件系统中,我们可以直接通过操作系统的文件操作来备份或导出。但是,由于附件是按照项目(`PROJECT_KEY`)和问题(`ISSUE_KEY`)分目录存储的,我们需要将整个`attachments`目录(可能还包括`avatars`目录)进行备份。 3. **使用脚本批量导出**: 如果需要将附件导出到其他位置(例如另一台服务器或本地),可以编写脚本(如Shell脚本或Python脚本)来复制整个附件目录。 例如,使用Shell命令: ```bash # 假设附件存储路径为 /var/atlassian/application-data/jira/data/attachments # 目标备份目录为 /backup/jira_attachments rsync -av /var/atlassian/application-data/jira/data/attachments /backup/jira_attachments ``` 或者,如果只需要导出特定项目的附件,可以只复制该项目对应的目录。 4. **按需导出(结合数据库信息)**: 有时我们可能需要根据问题键(Issue Key)或项目来导出附件,并且希望保持原始文件名(因为JIRA存储的文件名可能是哈希值)。这时需要结合数据库查询。 JIRA将附件的原始文件名存储在数据库表`fileattachment`的`filename`字段中,而存储在文件系统中的文件名是`fileattachment`表中的`filepath`字段(通常是一个数字,如`12345`)或哈希值。 步骤: a. 从数据库查询出附件文件系统中的存储名称与原始文件名的对应关系。 b. 编写脚本,根据查询结果将文件系统中的文件复制到目标位置,并重命名为原始文件名。 注意:此操作需要访问JIRA数据库,并且需要谨慎处理。 5. **使用JIRA API导出附件**: JIRA提供了REST API,可以通过编程方式获取附件并下载。这种方法不需要直接访问文件系统或数据库,但可能速度较慢,适合少量附件或需要按条件导出的情况。 示例步骤: a. 使用JIRA REST API获取问题列表,然后遍历每个问题获取其附件信息。 b. 对于每个附件,通过API提供的下载URL下载附件。 Python示例(使用jira-python库): ```python from jira import JIRA import requests # 连接JIRA jira = JIRA(server='https://your-jira-url', basic_auth=('username', 'password')) # 定义要导出的问题键列表(可以通过搜索得到) issues = jira.search_issues('project=PROJECT_KEY') for issue in issues: # 获取该问题的所有附件 attachments = issue.fields.attachment for attachment in attachments: # 下载附件 url = attachment.content response = requests.get(url, auth=('username', 'password')) if response.status_code == 200: with open(attachment.filename, 'wb') as f: f.write(response.content) ``` 注意:此方法会逐个下载附件,如果附件数量很大,可能会很慢。同时,需要确保有足够的权限。 6. **注意事项**: - 文件系统操作需要服务器访问权限,且操作时最好停止JIRA服务以避免文件被锁定(或者选择在低峰期操作)。 - 使用API方式不需要停止JIRA,但需要网络请求,且可能受速率限制。 - 如果附件存储在数据库中(不常见),则需要通过数据库导出二进制数据并写入文件,但引用[1]已说明附件默认在文件系统中。 根据引用[1]和[2],我们更推荐使用文件系统直接备份(即方法2或3)来批量导出附件,因为这样最快。但若没有直接访问服务器的权限,则只能使用API方式(方法5)。 因此,具体方法选择取决于: - 是否可以直接访问服务器文件系统 - 是否需要保持原始文件名(如果不需要,直接复制整个attachments目录即可) - 是否需要按特定条件(如项目、问题类型等)导出 最后,引用[1]提到,头像附件存储在`avatars`目录下,如果需要,也应一并备份。</think>### 如何从JIRA批量导出附件文件 #### 方法一:通过文件系统直接导出(推荐) 1. **定位附件存储路径** 登录JIRA管理员账号 → 右上角 **系统 → 高级 → 附件** 查看配置的存储路径(默认:`/var/atlassian/application-data/jira/data/attachments`)[^1] 2. **使用脚本批量导出** 创建Shell脚本批量复制附件(示例): ```bash #!/bin/bash ATTACH_DIR="/var/atlassian/application-data/jira/data/attachments" BACKUP_DIR="/backup/jira_attachments_$(date +%Y%m%d)" mkdir -p $BACKUP_DIR find $ATTACH_DIR -name "*.xlsx" -exec cp {} $BACKUP_DIR \; echo "导出完成!文件保存在: $BACKUP_DIR" ``` #### 方法二:通过JIRA API导出 使用Python脚本(需安装 `jira` 库): ```python from jira import JIRA import shutil # 连接JIRA jira = JIRA(server='https://your-jira-url', basic_auth=('username', 'password')) # 导出PRJ-123项目所有附件 issues = jira.search_issues('project=PRJ-123') for issue in issues: for attachment in issue.fields.attachment: with open(attachment.filename, 'wb') as f: f.write(attachment.get()) print(f"已导出: {attachment.filename}") ``` #### 方法三:数据库导出(高级) 1. 查询附件路径: ```sql SELECT cwd.directory_name, fa.filename, fa.filepath FROM fileattachment fa JOIN jiraissue ji ON fa.issueid = ji.id JOIN project p ON ji.project = p.id WHERE p.pkey = 'PRJ' AND fa.filename LIKE '%.xlsx%'; ``` 2. 根据查询结果的 `filepath` 字段定位文件系统路径导出 #### ⚠️ 注意事项 1. 文件系统导出需服务器权限 2. 附件原始名存储在数据库的 `filename` 字段,文件系统可能使用哈希名[^1] 3. 批量操作前建议备份数据库 4. 导出大文件时使用 `rsync` 替代 `cp` 命令更高效 > 示例:导出所有Excel附件到本地 > `find /jira/attachments -name "*.xlsx" -exec rsync -avP {} ~/jira_backup/ \;` --- ### 相关问题 1. 如何按时间范围导出JIRA附件? 2. JIRA附件存储路径可以修改到网络存储吗? 3. 如何通过API只导出特定用户的附件? 4. JIRA附件和问题如何保持同步导出? [^1]: JIRA备份与附件存储配置 [^2]: JIRA CSV导入规范 [^3]: Python处理Excel文件 [^4]: JIRA问题导出功能
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值