>백엔드 개발 >Golang >Go의 데이터베이스 상호작용: SQL에서 NoSQL로

Go의 데이터베이스 상호작용: SQL에서 NoSQL로

Susan Sarandon
Susan Sarandon원래의
2024-10-01 22:07:021011검색

Database Interactions in Go: From SQL to NoSQL

소개

Go(Golang)는 강력한 고성능 백엔드 서비스를 구축하기 위한 인기 있는 선택이 되었습니다. Go의 주요 강점 중 하나는 기존 SQL 데이터베이스를 사용하든 최신 NoSQL 솔루션을 사용하든 상관없이 데이터베이스 작업에 대한 탁월한 지원입니다. 이 가이드에서는 SQL 및 NoSQL 접근 방식을 모두 다루면서 Go에서 데이터베이스와 상호 작용하는 방법을 살펴보겠습니다.

목차

  1. SQL 데이터베이스 상호 작용
    • 데이터베이스/SQL 패키지 사용
    • ORM 작업: GORM
  2. NoSQL 데이터베이스 상호 작용
    • 공식 Go 드라이버를 갖춘 MongoDB
  3. 모범 사례 및 일반적인 함정
  4. 결론

SQL 데이터베이스 상호 작용

데이터베이스/sql 패키지 사용

Go의 표준 라이브러리는 SQL(또는 SQL과 유사한) 데이터베이스에 대한 일반 인터페이스를 제공하는 데이터베이스/sql 패키지를 제공합니다. 이 패키지는 데이터베이스 관련 드라이버와 함께 사용하도록 설계되었습니다.

SQLite를 사용하는 간단한 예부터 시작해 보겠습니다.

package main

import (
    "database/sql"
    "fmt"
    "log"
)

func main() {
    // Open the database
    db, err := sql.Open("sqlite3", "./test.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // Create table
    _, err = db.Exec(`CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        age INTEGER
    )`)
    if err != nil {
        log.Fatal(err)
    }

    // Insert a user
    result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "Alice", 30)
    if err != nil {
        log.Fatal(err)
    }

    // Get the ID of the inserted user
    id, err := result.LastInsertId()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Inserted user with ID: %d\n", id)

    // Query for the user
    var name string
    var age int
    err = db.QueryRow("SELECT name, age FROM users WHERE id = ?", id).Scan(&name, &age)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("User: %s, Age: %d\n", name, age)
}

이 예에서는 Go에서 SQL 데이터베이스 작업의 기본 사항을 보여줍니다.

  1. 데이터베이스 연결 열기
  2. 테이블 만들기
  3. 데이터 삽입
  4. 데이터 쿼리

database/sql 패키지는 데이터베이스에 대한 하위 수준 인터페이스를 제공하여 쿼리와 작업을 세밀하게 제어할 수 있습니다.

ORM 작업: GORM

database/sql 패키지는 강력하지만 많은 개발자는 보다 편리한 데이터베이스 작업을 위해 ORM(객체 관계형 매핑) 도구 사용을 선호합니다. GORM은 Go에서 가장 인기 있는 ORM 중 하나입니다.

다음은 SQLite와 함께 GORM을 사용하는 예입니다.

package main

import (
    "fmt"
    "log"

    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type User struct {
    ID   uint
    Name string
    Age  int
}

func main() {
    // Open the database
    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        log.Fatal(err)
    }

    // Auto Migrate the schema
    db.AutoMigrate(&User{})

    // Create a user
    user := User{Name: "Bob", Age: 25}
    result := db.Create(&user)
    if result.Error != nil {
        log.Fatal(result.Error)
    }
    fmt.Printf("Inserted user with ID: %d\n", user.ID)

    // Query for the user
    var fetchedUser User
    db.First(&fetchedUser, user.ID)
    fmt.Printf("User: %s, Age: %d\n", fetchedUser.Name, fetchedUser.Age)

    // Update the user
    db.Model(&fetchedUser).Update("Age", 26)

    // Delete the user
    db.Delete(&fetchedUser)
}

GORM은 데이터베이스 작업에 대한 더 높은 수준의 추상화를 제공하므로 원시 SQL 쿼리를 작성하는 대신 Go 구조체로 직접 작업할 수 있습니다. 자동 마이그레이션, 후크, 연결과 같은 기능도 제공합니다.

NoSQL 데이터베이스 상호 작용

공식 Go 드라이버가 포함된 MongoDB

NoSQL 데이터베이스의 경우 공식 Go 드라이버를 사용하여 MongoDB와 상호작용하는 방법을 살펴보겠습니다.

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type User struct {
    Name string `bson:"name"`
    Age  int    `bson:"age"`
}

func main() {
    // Set client options
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

    // Connect to MongoDB
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
        log.Fatal(err)
    }

    // Check the connection
    err = client.Ping(context.TODO(), nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Connected to MongoDB!")

    // Get a handle for your collection
    collection := client.Database("test").Collection("users")

    // Insert a user
    user := User{Name: "Charlie", Age: 35}
    insertResult, err := collection.InsertOne(context.TODO(), user)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Inserted user with ID: %v\n", insertResult.InsertedID)

    // Find a user
    var result User
    filter := bson.M{"name": "Charlie"}
    err = collection.FindOne(context.TODO(), filter).Decode(&result)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Found user: %+v\n", result)

    // Update a user
    update := bson.M{
        "$set": bson.M{
            "age": 36,
        },
    }
    updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Updated %v user(s)\n", updateResult.ModifiedCount)

    // Delete a user
    deleteResult, err := collection.DeleteOne(context.TODO(), filter)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Deleted %v user(s)\n", deleteResult.DeletedCount)

    // Disconnect
    err = client.Disconnect(context.TODO())
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Connection to MongoDB closed.")
}

이 예에서는 공식 Go 드라이버를 사용하여 MongoDB의 기본 CRUD(생성, 읽기, 업데이트, 삭제) 작업을 보여줍니다.

모범 사례 및 일반적인 함정

Go에서 데이터베이스 작업을 할 때 다음 모범 사례를 염두에 두세요.

  1. 연결 풀링 사용: 데이터베이스/sql과 대부분의 NoSQL 드라이버 모두 연결 풀링을 구현합니다. 각 작업마다 새 연결을 여는 대신 데이터베이스 연결을 재사용하세요.

  2. 올바른 오류 처리: 항상 데이터베이스 작업에서 반환된 오류를 확인하고 적절하게 처리하세요.

  3. Prepared 문 사용: SQL 데이터베이스의 경우 준비된 문을 사용하여 성능을 향상하고 SQL 주입 공격을 방지합니다.

  4. 리소스 닫기: 작업이 끝나면 결과 세트, 명령문 및 데이터베이스 연결을 항상 닫습니다. 이때 defer 키워드가 유용합니다.

  5. 필요할 때 트랜잭션 사용: 여러 단계가 필요한 작업의 경우 트랜잭션을 사용하여 데이터 일관성을 보장합니다.

  6. N 1 쿼리 문제에 주의하세요: ORM을 사용할 때 N 1 쿼리 문제에 주의하고 적절한 경우 즉시 로딩을 사용하세요.

  7. 시간 초과에 컨텍스트 사용: 특히 장기 실행 쿼리의 경우 컨텍스트를 사용하여 데이터베이스 작업에 대한 시간 초과를 설정합니다.

피해야 할 일반적인 함정:

  1. SQL 주입 취약점 무시: 항상 매개변수화된 쿼리나 준비된 문을 사용하세요.
  2. 연결 오류 처리 안 함: 연결 오류를 확인하고 처리하며, 필요한 경우 재시도 논리를 구현합니다.
  3. GORM 후크를 과도하게 사용: 편리하지만 GORM 후크를 과도하게 사용하면 디버깅하기 어려운 문제가 발생할 수 있습니다.
  4. 인덱싱이 제대로 되지 않음: 데이터베이스 스키마가 쿼리 패턴에 맞게 적절하게 인덱싱되었는지 확인하세요.
  5. 민감한 데이터를 일반 텍스트로 저장: 중요한 데이터를 데이터베이스에 저장하기 전에 항상 암호화하세요.

결론

Go는 SQL 및 NoSQL 데이터베이스 상호 작용을 모두 강력하게 지원합니다. 데이터베이스/SQL의 낮은 수준 제어를 선호하든, GORM과 같은 ORM의 편리함을 선호하든, MongoDB와 같은 NoSQL 데이터베이스로 작업하는 것을 선호하든 Go가 모든 것을 도와드립니다.

위 내용은 Go의 데이터베이스 상호작용: SQL에서 NoSQL로의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.