数据操作

主要用于保存文件元信息的保存

这里主要是在技术选型上的考虑

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的优点:

  1. 小巧、稳定:MySQL作为轻量级数据库,性能稳定,特别适合中小型应用和一般的业务场景。
  2. 社区活跃:MySQL的开源社区非常活跃,开发者能够快速获得支持和帮助。
  3. 多平台支持:MySQL可以运行在多种操作系统上,如Windows、Linux和macOS,具有很强的跨平台能力。
  4. 满足一般场景需求:对于大多数Web应用和中小型企业系统,MySQL都能够很好地满足需求。

MySQL的缺点:

  1. 缺乏高级功能:相比Oracle、SQL Server等商业数据库,MySQL在事务处理、复杂查询和大规模数据处理方面稍显不足。
  2. 扩展性有限: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
}
posted @ 2024-09-07 19:18  daligh  阅读(29)  评论(0)    收藏  举报