数据操作
主要用于保存文件元信息的保存
这里主要是在技术选型上的考虑
SQL数据库与非SQL数据库的区别与选择
在现代应用开发中,选择合适的数据库管理系统至关重要。无论是传统的关系型数据库(SQL)还是新兴的非关系型数据库(NoSQL),它们各自都拥有独特的优势,适用于不同的应用场景。本文将介绍SQL数据库与非SQL数据库的主要区别,并探讨其中的代表性数据库系统。
SQL数据库:结构化数据的强大工具
SQL数据库,也称为关系型数据库(RDBMS),以其结构化的数据管理和查询能力著称。常见的SQL数据库系统包括:
- SQL Server
- Oracle
- MySQL
这些系统依赖于表格来存储数据,并通过标准化的SQL语言来进行数据的增删改查。SQL数据库的主要特点如下:
- 数据结构化:表格设计遵循严格的模式(Schema),每一列的数据类型和约束都是预先定义好的。
- 关系性强:能够通过外键建立表与表之间的关系,支持复杂的查询和事务。
- 一致性和安全性高:适合对数据一致性要求高的场景,如金融系统、ERP系统等。
非SQL数据库:灵活的数据存储
随着大数据和云计算的普及,非SQL数据库(NoSQL)迅速崛起。它们不依赖表格存储数据,常用的非SQL数据库包括:
- MongoDB
- HBase
- Redis
NoSQL数据库不需要预定义的数据模式,数据可以以文档、键值对或列族的形式存储。其主要特点有:
- 灵活的数据模型:无需预定义表结构,数据可以是非结构化或半结构化的,特别适合存储动态变化的数据。
- 高扩展性:通过横向扩展,可以处理海量数据和高并发请求。
- 性能优越:在大规模数据存储和检索时,非SQL数据库通常具有更好的性能表现。
MySQL的特点与优劣点分析
MySQL作为一种开源的SQL数据库,是许多开发者的首选数据库之一。它拥有众多社区支持,适用于各类中小型应用场景。
MySQL的优点:
- 小巧、稳定:MySQL作为轻量级数据库,性能稳定,特别适合中小型应用和一般的业务场景。
- 社区活跃:MySQL的开源社区非常活跃,开发者能够快速获得支持和帮助。
- 多平台支持:MySQL可以运行在多种操作系统上,如Windows、Linux和macOS,具有很强的跨平台能力。
- 满足一般场景需求:对于大多数Web应用和中小型企业系统,MySQL都能够很好地满足需求。
MySQL的缺点:
- 缺乏高级功能:相比Oracle、SQL Server等商业数据库,MySQL在事务处理、复杂查询和大规模数据处理方面稍显不足。
- 扩展性有限:MySQL虽然支持集群和分布式架构,但在大规模并发和数据存储时的表现不如某些专用的NoSQL数据库。
如何选择数据库
在选择数据库时,需要根据具体的业务需求进行评估。如果你的应用场景涉及复杂的事务处理、需要保证数据的高一致性和完整性,那么SQL数据库是最佳选择。而如果你的应用场景涉及高并发、大数据量和灵活的数据模型,NoSQL数据库可能更适合你。
项目结构改变

这里涉及到数据库主从复制,可以参考我的另一篇文章:mysql安装配置(归类中间件)
数据库表的设计:
-
id 作为主键,可以唯一标识每个文件记录。
-
file_sha1 字段存储文件的 SHA1 哈希值,这与 UploadHandler 函数中计算的 FileSha1 相对应。它被设置为唯一索引,可以快速查找文件。
-
file_name 和 file_size 分别对应上传文件的名称和大小,这些信息在 UploadHandler 中都有收集。
-
file_addr 存储文件在服务器上的位置,对应 UploadHandler 中的 Location 字段。
-
create_at 和 update_at 字段自动记录创建和更新时间,有助于文件管理。
-
status 字段可用于标记文件状态,如可用、禁用或已删除等,这对文件生命周期管理很有用。
-
ext1 和 ext2 作为扩展字段,为将来可能的功能扩展预留了空间。
CREATE TABLE `tbl_file` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`file_sha1` char(40) NOT NULL DEFAULT '' COMMENT '文件hash',
`file_name` varchar(256) NOT NULL DEFAULT '' COMMENT '文件名',
`file_size` bigint(20) DEFAULT '0' COMMENT '文件大小',
`file_addr` varchar(1024) NOT NULL DEFAULT '' COMMENT '文件存储位置',
`create_at` datetime default NOW() COMMENT '创建日期',
`update_at` datetime default NOW() on update current_timestamp() COMMENT '更新日期',
`status` int(11) NOT NULL DEFAULT '0' COMMENT '状态(可用/禁用/已删除等状态)',
`ext1` int(11) DEFAULT '0' COMMENT '备用字段1',
`ext2` text COMMENT '备用字段2',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_file_hash` (`file_sha1`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
持久化文件信息表
func OnFileUploadFinished(filehash string, filename string,
filesize int64, fileaddr string) bool {
stmt, err := mydb.DBConn().Prepare(
"insert ignore into tbl_file (`file_sha1`,`file_name`,`file_size`," +
"`file_addr`,`status`) values (?,?,?,?,1)")
if err != nil {
fmt.Println("Failed to prepare statement, err:" + err.Error())
return false
}
defer stmt.Close()
ret, err := stmt.Exec(filehash, filename, filesize, fileaddr)
if err != nil {
fmt.Println(err.Error())
return false
}
if rf, err := ret.RowsAffected(); nil == err {
if rf <= 0 {
fmt.Printf("File with hash:%s has been uploaded before", filehash)
}
return true
}
return false
}
从数据库中获取文件信息
func GetFileMeta(filehash string) (*TableFile, error) {
stmt, err := mydb.DBConn().Prepare(
"select file_sha1,file_addr,file_name,file_size from tbl_file " +
"where file_sha1=? and status=1 limit 1")
if err != nil {
fmt.Println(err.Error())
return nil, err
}
defer stmt.Close()
tfile := TableFile{}
err = stmt.QueryRow(filehash).Scan(
&tfile.FileHash, &tfile.FileAddr, &tfile.FileName, &tfile.FileSize)
if err != nil {
if err == sql.ErrNoRows {
// 查不到对应记录, 返回参数及错误均为nil
return nil, nil
} else {
fmt.Println(err.Error())
return nil, err
}
}
return &tfile, nil
}

浙公网安备 33010602011771号