Golang实现多选测验功能的最佳实践

Golang实现多选测验功能的最佳实践 大家好,

我正在尝试构建一个多选网页应用,想知道哪种方法更好:从数据库拉取数据还是使用 JSON/CSV 文件。

谢谢

2 回复

你好查德,

这始终取决于你的使用场景。

如果是一个静态的多选列表(如果问题不经常变化)并且问题数量较少,你可以采用 JSON 方案——但仍不建议这样做。
但如果你需要一个能够良好扩展的动态方案,数据库方法始终是首选方案。

希望这能解答你的疑问

更多关于Golang实现多选测验功能的最佳实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


对于实现多选测验功能,使用数据库(如 PostgreSQL、MySQL 或 SQLite)通常是更优的选择,因为它提供了更好的数据管理、查询灵活性和扩展性。JSON 或 CSV 文件更适合小型、静态数据集,但缺乏数据库的事务支持、并发处理和高效索引。

推荐方法:使用数据库(以 PostgreSQL 为例)

  • 优势:支持复杂查询(如随机抽取题目)、数据完整性、用户进度跟踪和扩展性(例如添加用户认证)。
  • 示例代码:使用 Go 的 database/sql 包和 pgx 驱动连接 PostgreSQL,并查询测验题目。

首先,安装依赖:

go mod init quiz-app
go get github.com/jackc/pgx/v5

假设数据库表 questions 结构如下:

CREATE TABLE questions (
    id SERIAL PRIMARY KEY,
    question_text TEXT NOT NULL,
    options JSONB NOT NULL, -- 存储选项,如 {"A": "选项1", "B": "选项2", ...}
    correct_answer CHAR(1) NOT NULL -- 正确答案键,如 'A'
);

Go 代码实现数据库查询:

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/jackc/pgx/v5"
)

type Question struct {
	ID            int
	QuestionText  string
	Options       map[string]string
	CorrectAnswer string
}

func main() {
	// 连接数据库,替换为实际连接字符串
	conn, err := pgx.Connect(context.Background(), "postgresql://user:password@localhost:5432/quizdb")
	if err != nil {
		log.Fatal("连接数据库失败: ", err)
	}
	defer conn.Close(context.Background())

	// 查询所有题目
	rows, err := conn.Query(context.Background(), "SELECT id, question_text, options, correct_answer FROM questions")
	if err != nil {
		log.Fatal("查询失败: ", err)
	}
	defer rows.Close()

	var questions []Question
	for rows.Next() {
		var q Question
		err := rows.Scan(&q.ID, &q.QuestionText, &q.Options, &q.CorrectAnswer)
		if err != nil {
			log.Fatal("扫描数据失败: ", err)
		}
		questions = append(questions, q)
	}

	// 示例:打印第一个题目和选项
	if len(questions) > 0 {
		q := questions[0]
		fmt.Printf("问题: %s\n", q.QuestionText)
		for key, value := range q.Options {
			fmt.Printf("%s: %s\n", key, value)
		}
		fmt.Printf("正确答案: %s\n", q.CorrectAnswer)
	}
}

替代方法:使用 JSON 文件

如果数据量小且不常变更,JSON 文件可以简化部署。

  • 示例代码:从 JSON 文件加载题目。
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
)

type Question struct {
	ID            int               `json:"id"`
	QuestionText  string            `json:"question_text"`
	Options       map[string]string `json:"options"`
	CorrectAnswer string            `json:"correct_answer"`
}

func main() {
	file, err := os.ReadFile("questions.json")
	if err != nil {
		log.Fatal("读取文件失败: ", err)
	}

	var questions []Question
	err = json.Unmarshal(file, &questions)
	if err != nil {
		log.Fatal("解析 JSON 失败: ", err)
	}

	// 示例输出
	if len(questions) > 0 {
		q := questions[0]
		fmt.Printf("问题: %s\n", q.QuestionText)
		for key, value := range q.Options {
			fmt.Printf("%s: %s\n", key, value)
		}
		fmt.Printf("正确答案: %s\n", q.CorrectAnswer)
	}
}

JSON 文件示例(questions.json):

[
  {
    "id": 1,
    "question_text": "Go 语言由哪个组织开发?",
    "options": {"A": "Google", "B": "Microsoft", "C": "Apple"},
    "correct_answer": "A"
  }
]

总结

  • 数据库方案:适用于生产环境,支持动态数据管理和扩展。
  • JSON/CSV 方案:适用于原型或小型应用,部署简单但缺乏高级功能。

根据应用规模选择:如果预期用户量增长或需要复杂功能(如随机抽题、用户评分),优先使用数据库。

回到顶部