{"id":18522,"date":"2024-07-18T00:13:07","date_gmt":"2024-07-18T07:13:07","guid":{"rendered":"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/"},"modified":"2024-12-12T00:05:35","modified_gmt":"2024-12-12T08:05:35","slug":"building-robust-go-applications-with-gorm-best-practices","status":"publish","type":"article","link":"https:\/\/www.pingcap.com\/ko\/article\/building-robust-go-applications-with-gorm-best-practices\/","title":{"rendered":"Building Robust Go Applications with GORM: Best Practices"},"content":{"rendered":"\n<p>Building robust applications in Go is crucial for ensuring performance, scalability, and maintainability. One of the most popular tools for achieving this is GORM, an open-source ORM library that <a href=\"https:\/\/medium.com\/%40itskenzylimon\/what-to-know-about-phoenix-ecto-and-golang-gorm-as-db-wrappers-orm-3da456cf2df6\">simplifies database interactions in Go<\/a>. With over <a href=\"https:\/\/blog.jetbrains.com\/go\/2023\/04\/27\/comparing-db-packages\/\">30,400 stars on GitHub<\/a>, GORM is widely adopted due to its developer-friendly design and comprehensive feature set. This blog aims to share best practices for using GORM effectively, helping you to build a Go app with GORM that is both efficient and reliable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Getting_Started_with_GORM\"><\/span>Getting Started with GORM<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Setting Up Your Go Environment<\/h3>\n\n\n\n<p>Before diving into GORM, it&#8217;s essential to have your Go environment properly set up. This ensures a smooth development experience and helps avoid common pitfalls.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Installing Go<\/h4>\n\n\n\n<p>First, you need to install Go. You can download the latest version of Go from the <a href=\"https:\/\/go.dev\/dl\/\">official Go website<\/a>. Follow these steps to install Go on your system:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Download the Installer:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>For Windows, download the <code>.msi<\/code> file.<\/li>\n\n\n\n<li>For macOS, download the <code>.pkg<\/code> file.<\/li>\n\n\n\n<li>For Linux, download the appropriate tarball for your distribution.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Run the Installer:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>On Windows and macOS, simply run the downloaded file and follow the installation prompts.<\/li>\n\n\n\n<li>On Linux, extract the tarball and move the <code>go<\/code> directory to <code>\/usr\/local<\/code>:<br><pre><code class=\"language-sh\">tar -C \/usr\/local -xzf go1.x.x.linux-amd64.tar.gz<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Set Up Environment Variables:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Add Go&#8217;s binary directory to your <code>PATH<\/code> environment variable:<br><pre><code class=\"language-sh\">export PATH=$PATH:\/usr\/local\/go\/bin<\/code><\/pre><\/li>\n\n\n\n<li>Verify the installation by running:<br><pre><code class=\"language-sh\">go version<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Setting Up a Go Workspace<\/h4>\n\n\n\n<p>A well-organized workspace is crucial for managing your Go projects efficiently. Here&#8217;s how to set up your Go workspace:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Create a Workspace Directory:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Choose a directory where you will store all your Go projects. For example:<br><pre><code class=\"language-sh\">mkdir -p $HOME\/go\/{bin,src,pkg}<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Set Up Environment Variables:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Define the <code>GOPATH<\/code> environment variable to point to your workspace directory:<br><pre><code class=\"language-sh\">export GOPATH=$HOME\/go<\/code><\/pre><\/li>\n\n\n\n<li>Add the workspace&#8217;s <code>bin<\/code> directory to your <code>PATH<\/code>:<br><pre><code class=\"language-sh\">export PATH=$PATH:$GOPATH\/bin<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Verify Your Workspace:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Create a simple Go program to ensure everything is set up correctly:<br><pre><code class=\"language-sh\">mkdir -p $GOPATH\/src\/hello<br>cd $GOPATH\/src\/hello<br>echo 'package main; import \"fmt\"; func main() { fmt.Println(\"Hello, World!\") }' > hello.go<br>go run hello.go<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Installing and Configuring GORM<\/h3>\n\n\n\n<p>With your Go environment ready, the next step is to install and configure <strong>GORM<\/strong>. GORM is a powerful ORM library that simplifies database operations in Go applications.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Adding GORM to Your Project<\/h4>\n\n\n\n<p>To add GORM to your project, you need to use Go modules. Here\u2019s how you can do it:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Initialize a New Go Module:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Navigate to your project directory and initialize a new module:<br><pre><code class=\"language-sh\">go mod init your_project_name<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Install GORM and the Database Driver:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Use the <code>go get<\/code> command to install GORM and the MySQL driver (or any other driver you need):<br><pre><code class=\"language-sh\">go get -u gorm.io\/gorm<br>go get -u gorm.io\/driver\/mysql<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Verify Installation:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Check the <code>go.mod<\/code> file to ensure that GORM and the driver have been added as dependencies.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Basic Configuration Options<\/h4>\n\n\n\n<p>Configuring GORM correctly is crucial for optimal performance and ease of use. Here are some basic configuration options:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Connecting to the Database:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Use the following code snippet to connect to a TiDB database:<br><pre><code class=\"language-go\">package main<br><br>import (<br>    \"gorm.io\/driver\/mysql\"<br>    \"gorm.io\/gorm\"<br>    \"log\"<br>)<br><br>func main() {<br>    dsn := \"user:password@tcp(host:port)\/dbname?charset=utf8mb4&amp;parseTime=True&amp;loc=Local\"<br>    db, err := gorm.Open(mysql.Open(dsn), &amp;gorm.Config{})<br>    if err != nil {<br>        log.Fatal(err)<br>    }<br>    \/\/ Use db object for database operations<br>}<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Setting Logger Levels:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>GORM provides various logging levels to help you debug your application:<br><pre><code class=\"language-go\">import \"gorm.io\/gorm\/logger\"<br><br>db, err := gorm.Open(mysql.Open(dsn), &amp;gorm.Config{<br>    Logger: logger.Default.LogMode(logger.Info),<br>})<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Connection Pooling:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Configure connection pooling to manage database connections efficiently:<br><pre><code class=\"language-go\">sqlDB, err := db.DB()<br>if err != nil {<br>    log.Fatal(err)<br>}<br><br>sqlDB.SetMaxIdleConns(10)<br>sqlDB.SetMaxOpenConns(100)<br>sqlDB.SetConnMaxLifetime(time.Hour)<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>By following these steps, you will have a solid foundation for using GORM in your Go projects. This setup not only ensures that your development environment is robust but also prepares you for more advanced GORM features and configurations. For more detailed information, refer to the <a href=\"https:\/\/gorm.io\/docs\/index.html\">official GORM documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Best_Practices_for_Database_Design\"><\/span>Best Practices for Database Design<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Designing your database effectively is a cornerstone of building robust Go applications with GORM. Proper database design ensures data integrity, optimizes performance, and simplifies maintenance. Here, we will explore best practices for structuring your models and managing relationships using GORM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Structuring Your Models<\/h3>\n\n\n\n<p>Models are the backbone of any ORM, and GORM is no exception. Structuring your models correctly can significantly impact the readability, maintainability, and performance of your application.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Defining Models in GORM<\/h4>\n\n\n\n<p>In GORM, models are defined using Go structs. Each struct represents a table in the database, and each field in the struct corresponds to a column. Here\u2019s a simple example:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">type User struct {\n    ID        uint   `gorm:\"primaryKey\"`\n    Name      string `gorm:\"size:255;not null\"`\n    Email     string `gorm:\"uniqueIndex;size:255;not null\"`\n    CreatedAt time.Time\n    UpdatedAt time.Time\n}\n<\/code>\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Primary Key<\/strong>: The <code>gorm:\"primaryKey\"<\/code> tag designates the primary key of the table.<\/li>\n\n\n\n<li><strong>Constraints<\/strong>: Tags like <code>gorm:\"size:255;not null\"<\/code> enforce constraints on the fields, ensuring data integrity.<\/li>\n\n\n\n<li><strong>Indexes<\/strong>: The <code>gorm:\"uniqueIndex\"<\/code> tag creates a unique index on the <code>Email<\/code> field, preventing duplicate entries.<\/li>\n<\/ul>\n\n\n\n<p>By defining models this way, you leverage GORM&#8217;s ability to <a href=\"https:\/\/docs.newrelic.com\/docs\/apm\/agents\/go-agent\/get-started\/introduction-new-relic-go\">manage basic data types efficiently<\/a>, mapping them seamlessly to database tables.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Using Tags for Field Customization<\/h4>\n\n\n\n<p>GORM tags provide a powerful mechanism for customizing field behavior. Here are some commonly used tags:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><p><strong>Column Name<\/strong>: Change the default column name.<code class=\"language-go\">type Product struct {<br>    Code  string `gorm:\"column:product_code\"`<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Default Value<\/strong>: Set a default value for a field.<code class=\"language-go\">type Order struct {<br>    Status string `gorm:\"default:'pending'\"`<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Ignore Field<\/strong>: Exclude a field from the database schema.<code class=\"language-go\">type Customer struct {<br>    Password string `gorm:\"-\"`<br>}<\/code><\/p><\/li>\n<\/ul>\n\n\n\n<p>Using these tags effectively can help tailor your models to meet specific requirements, enhancing both functionality and performance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Managing Relationships<\/h3>\n\n\n\n<p>Handling relationships between models is another critical aspect of database design. GORM simplifies this process with its <a href=\"https:\/\/medium.com\/thirdfort\/effective-management-of-custom-types-in-go-with-gorm-leveraging-valuer-and-scanner-interface-12c9f0629e9d\">intuitive relationship management features<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">One-to-One Relationships<\/h4>\n\n\n\n<p>One-to-one relationships are defined using foreign keys and associations. Here\u2019s an example:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">type Profile struct {\n    ID     uint\n    UserID uint\n    User   User `gorm:\"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;\"`\n}\n<\/code>\n<\/pre>\n\n\n\n<p>In this case, the <code>Profile<\/code> model has a one-to-one relationship with the <code>User<\/code> model. The <code>gorm:\"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;\"<\/code> tag ensures that changes to the <code>User<\/code> model cascade to the <code>Profile<\/code> model, maintaining referential integrity.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">One-to-Many Relationships<\/h4>\n\n\n\n<p>One-to-many relationships are common in database design. Here\u2019s how you can define them in GORM:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">type Author struct {\n    ID      uint\n    Name    string\n    Books   []Book `gorm:\"foreignKey:AuthorID\"`\n}\ntype Book struct {\n    ID       uint\n    Title    string\n    AuthorID uint\n}\n<\/code>\n<\/pre>\n\n\n\n<p>In this example, an <code>Author<\/code> can have multiple <code>Books<\/code>. The <code>gorm:\"foreignKey:AuthorID\"<\/code> tag specifies the foreign key in the <code>Book<\/code> model, linking it to the <code>Author<\/code> model.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Many-to-Many Relationships<\/h4>\n\n\n\n<p>Many-to-many relationships involve a join table to manage the associations. Here\u2019s an example:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">type Student struct {\n    ID     uint\n    Name   string\n    Courses []Course `gorm:\"many2many:student_courses;\"`\n}\ntype Course struct {\n    ID      uint\n    Name    string\n    Students []Student `gorm:\"many2many:student_courses;\"`\n}\n<\/code>\n<\/pre>\n\n\n\n<p>In this scenario, the <code>Student<\/code> and <code>Course<\/code> models are linked through a join table named <code>student_courses<\/code>. This setup allows for efficient querying and management of many-to-many relationships.<\/p>\n\n\n\n<p>By adhering to these best practices for database design, you can ensure that your Go applications built with GORM are both robust and efficient. Properly structured models and well-managed relationships not only enhance performance but also make your code more maintainable and scalable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Efficient_Querying_with_GORM\"><\/span>Efficient Querying with GORM<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Efficient querying is a cornerstone of robust application development. GORM provides a range of features that make querying both intuitive and powerful. This section will guide you through basic and advanced querying techniques to optimize your Go applications.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Queries<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Retrieving Records<\/h4>\n\n\n\n<p>Retrieving records is one of the most fundamental operations in any database-driven application. GORM simplifies this process with straightforward methods:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">var users []User\nresult := db.Find(&amp;users)\nif result.Error != nil {\n    log.Fatal(result.Error)\n}\n<\/code>\n<\/pre>\n\n\n\n<p>In this example, <code>db.Find(&amp;users)<\/code> retrieves all records from the <code>users<\/code> table. The <code>result<\/code> object contains useful metadata, such as the number of rows affected and any errors encountered.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/medium.com\/%40wahyu_32106\/advance-trick-in-gorm-aeea2d3c7ac8\">Filtering and Sorting<\/a><\/h4>\n\n\n\n<p>Filtering and sorting are essential for narrowing down query results. GORM allows you to apply filters and sort results effortlessly:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">var activeUsers []User\ndb.Where(\"status = ?\", \"active\").Order(\"created_at desc\").Find(&amp;activeUsers)\n<\/code>\n<\/pre>\n\n\n\n<p>Here, <code>db.Where(\"status = ?\", \"active\")<\/code> filters users with an <code>active<\/code> status, and <code>.Order(\"created_at desc\")<\/code> sorts them by the <code>created_at<\/code> field in descending order. This combination of filtering and sorting ensures that you retrieve only the relevant data, organized in the desired sequence.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Advanced Query Techniques<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Joins and Preloading<\/h4>\n\n\n\n<p>Joins and preloading are advanced techniques for fetching related data efficiently. GORM supports both inner joins and left joins, as well as preloading associations:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">var orders []Order\ndb.Preload(\"Customer\").Find(&amp;orders)\n<\/code>\n<\/pre>\n\n\n\n<p>In this example, <code>db.Preload(\"Customer\")<\/code> fetches associated <code>Customer<\/code> records for each <code>Order<\/code>, reducing the number of queries and improving performance. For more complex scenarios, you can use joins:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">var results []struct {\n    OrderID   uint\n    CustomerName string\n}\ndb.Table(\"orders\").\n    Select(\"orders.id as order_id, customers.name as customer_name\").\n    Joins(\"[left join](https:\/\/docs-archive.pingcap.com\/tidb\/v6.6\/dev-guide-sample-application-golang) customers on customers.id = orders.customer_id\").\n    Scan(&amp;results)\n<\/code>\n<\/pre>\n\n\n\n<p>This query uses a left join to combine <code>orders<\/code> and <code>customers<\/code> tables, selecting specific fields into a custom struct.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Transactions and Concurrency Control<\/h4>\n\n\n\n<p>Transactions are crucial for ensuring data integrity, especially in multi-step operations. GORM makes it easy to manage transactions:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">tx := db.Begin()\nif err := tx.Error; err != nil {\n    log.Fatal(err)\n}\nif err := tx.Create(&amp;order).Error; err != nil {\n    tx.Rollback()\n    log.Fatal(err)\n}\nif err := tx.Create(&amp;payment).Error; err != nil {\n    tx.Rollback()\n    log.Fatal(err)\n}\nif err := tx.Commit().Error; err != nil {\n    log.Fatal(err)\n}\n<\/code>\n<\/pre>\n\n\n\n<p>In this example, <code>tx := db.Begin()<\/code> starts a new transaction. If any operation fails, <code>tx.Rollback()<\/code> reverts all changes. Finally, <code>tx.Commit()<\/code> applies the changes if all operations succeed.<\/p>\n\n\n\n<p>Concurrency control is another critical aspect, particularly in high-traffic applications. GORM supports both optimistic and pessimistic locking:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><p><strong>Optimistic Locking<\/strong>: Uses a version field to detect conflicts.<code class=\"language-go\">type Product struct {<br>    ID      uint<br>    Version int `gorm:\"version\"`<br>}<br><br>var product Product<br>db.First(&amp;product, 1)<br>product.Version++<br>db.Save(&amp;product)<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Pessimistic Locking<\/strong>: Locks rows to prevent concurrent updates.<code class=\"language-go\">var product Product<br>db.Clauses(clause.Locking{Strength: \"UPDATE\"}).First(&amp;product, 1)<\/code><\/p><\/li>\n<\/ul>\n\n\n\n<p>By leveraging these advanced techniques, you can ensure data consistency and optimize performance in your Go applications using GORM.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Performance_Optimization\"><\/span>Performance Optimization<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Optimizing performance is crucial for building robust Go applications with GORM. This section delves into techniques for indexing, caching, profiling, and monitoring to ensure your application runs efficiently.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Indexing and Caching<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Creating Indexes<\/h4>\n\n\n\n<p>Indexes are fundamental for <a href=\"https:\/\/gorm.io\/docs\/performance.html\">speeding up data retrieval<\/a> and enhancing query performance. By creating indexes on frequently queried columns, you can significantly reduce the time it takes to fetch data.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><p><strong>Primary Indexes<\/strong>: Automatically created for primary key fields.<code class=\"language-go\">type User struct {<br>    ID   uint   `gorm:\"primaryKey\"`<br>    Name string `gorm:\"index\"` \/\/ Creates an index on the Name field<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Unique Indexes<\/strong>: Ensure that all values in a column are unique.<code class=\"language-go\">type Product struct {<br>    Code string `gorm:\"uniqueIndex\"`<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Composite Indexes<\/strong>: Combine multiple columns into a single index.<code class=\"language-go\">type Order struct {<br>    UserID    uint `gorm:\"index\"`<br>    ProductID uint `gorm:\"index\"`<br>    gorm.Model<br>}<\/code><\/p><\/li>\n<\/ul>\n\n\n\n<p>Creating indexes helps the database engine quickly locate rows without scanning the entire table, which is especially beneficial for large datasets.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Implementing Caching Strategies<\/h4>\n\n\n\n<p>Caching is another powerful technique to <a href=\"https:\/\/stackoverflow.com\/questions\/34386108\/caching-vs-indexing\">improve performance by storing frequently<\/a> accessed data in memory, reducing the need for repeated database queries.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><p><strong>In-Memory Caching<\/strong>: Use libraries like <code>groupcache<\/code> or <code>freecache<\/code> to store frequently accessed data in memory.<code class=\"language-go\">import (<br>    \"github.com\/coocood\/freecache\"<br>)<br><br>cacheSize := 100 * 1024 * 1024 \/\/ 100MB<br>cache := freecache.NewCache(cacheSize)<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Distributed Caching<\/strong>: Implement distributed caching solutions like Redis to handle larger datasets and provide high availability.<code class=\"language-go\">import (<br>    \"github.com\/go-redis\/redis\/v8\"<br>    \"context\"<br>)<br><br>rdb := redis.NewClient(&amp;redis.Options{<br>    Addr: \"localhost:6379\",<br>})<br><br>ctx := context.Background()<br>err := rdb.Set(ctx, \"key\", \"value\", 0).Err()<\/code><\/p><\/li>\n<\/ul>\n\n\n\n<p>By combining indexing and caching strategies, you can significantly enhance the responsiveness and scalability of your Go applications using GORM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Profiling and Monitoring<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Using Profiling Tools<\/h4>\n\n\n\n<p>Profiling tools are essential for identifying performance bottlenecks in your application. They help you understand where your application spends most of its time and resources.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><p><strong>pprof<\/strong>: A popular profiling tool in Go that provides insights into CPU and memory usage.<code class=\"language-go\">import (<br>    _ \"net\/http\/pprof\"<br>    \"net\/http\"<br>)<br><br>go func() {<br>    log.Println(http.ListenAndServe(\"localhost:6060\", nil))<br>}()<\/code><\/p><\/li>\n\n\n\n<li><p><strong>GoTrace<\/strong>: Another powerful tool for tracing and visualizing the execution of your Go programs.<code class=\"language-sh\">go tool trace trace.out<\/code><\/p><\/li>\n<\/ul>\n\n\n\n<p>Using these tools, you can gather detailed performance metrics and make informed decisions to optimize your code.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Monitoring Database Performance<\/h4>\n\n\n\n<p>Monitoring the performance of your TiDB database is crucial for maintaining optimal application performance. Here are some best practices:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><p><strong>Prometheus and Grafana<\/strong>: Use Prometheus for collecting metrics and Grafana for visualizing them.<code class=\"language-yaml\">global:<br>  scrape_interval: 15s<br><br>scrape_configs:<br>  - job_name: 'tidb'<br>    static_configs:<br>      - targets: ['localhost:9090']<\/code><\/p><\/li>\n\n\n\n<li><p><strong>TiDB Dashboard<\/strong>: Leverage the built-in TiDB Dashboard for real-time monitoring and performance analysis.<code class=\"language-sh\">tiup cluster display &lt;cluster-name><\/code><\/p><\/li>\n\n\n\n<li><p><strong>Slow Query Log<\/strong>: Enable and analyze slow query logs to identify and optimize slow-running queries.<code class=\"language-sql\">SET GLOBAL tidb_slow_log_threshold = 300;<\/code><\/p><\/li>\n<\/ul>\n\n\n\n<p>By continuously profiling and monitoring your application and database, you can proactively address performance issues and ensure your Go applications remain robust and efficient.<\/p>\n\n\n\n<p>Incorporating these performance optimization techniques will help you build high-performing Go applications with GORM, ensuring they scale effectively and maintain responsiveness under load.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Error_Handling_and_Debugging\"><\/span>Error Handling and Debugging<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Error handling and debugging are critical aspects of building robust Go applications with GORM. Properly managing errors ensures your application can gracefully recover from unexpected situations, while effective debugging techniques help you identify and resolve issues quickly. This section will cover common errors in GORM and provide practical debugging strategies.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common Errors in GORM<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Handling Connection Issues<\/h4>\n\n\n\n<p>Connection issues are among the most frequent problems developers encounter when working with databases. These issues can stem from network problems, incorrect configuration, or database server downtime. Here are some best practices for handling connection issues in GORM:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Retry Logic<\/strong>: Implement retry logic to handle transient connection errors.<code class=\"language-go\">var db *gorm.DB<br>var err error<br>for i := 0; i &lt; 3; i++ {<br>    db, err = gorm.Open(mysql.Open(dsn), &amp;gorm.Config{})<br>    if err == nil {<br>        break<br>    }<br>    time.Sleep(2 * time.Second)<br>}<br>if err != nil {<br>    log.Fatalf(\"failed to connect to database: %v\", err)<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Connection Pooling<\/strong>: Properly configure connection pooling to manage resources efficiently.<code class=\"language-go\">sqlDB, err := db.DB()<br>if err != nil {<br>    log.Fatal(err)<br>}<br>sqlDB.SetMaxIdleConns(10)<br>sqlDB.SetMaxOpenConns(100)<br>sqlDB.SetConnMaxLifetime(time.Hour)<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Graceful Shutdown<\/strong>: Ensure your application can gracefully handle shutdowns and restarts.<code class=\"language-go\">defer func() {<br>    sqlDB, err := db.DB()<br>    if err == nil {<br>        sqlDB.Close()<br>    }<br>}()<\/code><\/p><\/li>\n<\/ol>\n\n\n\n<p>By implementing these strategies, you can mitigate the impact of connection issues on your application&#8217;s stability.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Managing Data Integrity Errors<\/h4>\n\n\n\n<p>Data integrity errors occur when the data in your database does not meet the expected constraints or rules. These errors can lead to inconsistencies and application crashes. Here are some tips for managing data integrity errors:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Validation<\/strong>: Use GORM&#8217;s validation features to enforce data integrity at the application level.<code class=\"language-go\">type User struct {<br>    ID    uint   `gorm:\"primaryKey\"`<br>    Email string `gorm:\"uniqueIndex;not null\"`<br>    Age   int    `gorm:\"check:age >= 18\"`<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Error Handling<\/strong>: Capture and handle data integrity errors gracefully.<code class=\"language-go\">user := User{Email: \"example@example.com\", Age: 17}<br>if err := db.Create(&amp;user).Error; err != nil {<br>    log.Printf(\"error creating user: %v\", err)<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Database Constraints<\/strong>: Define constraints at the database level to ensure data integrity.<code class=\"language-sql\">ALTER TABLE users ADD CONSTRAINT chk_age CHECK (age >= 18);<\/code><\/p><\/li>\n<\/ol>\n\n\n\n<p>By combining application-level validation with database constraints, you can maintain data integrity and prevent errors from propagating through your system.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Debugging Techniques<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Using GORM&#8217;s Debug Mode<\/h4>\n\n\n\n<p>GORM provides a debug mode that logs all SQL statements generated by the ORM. This feature is invaluable for identifying issues related to SQL queries and understanding how GORM translates your code into SQL.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Enable Debug Mode<\/strong>: You can enable debug mode by calling the <code>Debug<\/code> method on your <code>*gorm.DB<\/code> instance.<code class=\"language-go\">db := db.Debug()<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Analyze Logs<\/strong>: Review the logged SQL statements to identify any anomalies or performance bottlenecks.<code class=\"language-sh\">[info] executing: SELECT * FROM `users` WHERE `users`.`id` = 1<\/code><\/p><\/li>\n<\/ol>\n\n\n\n<p>Using GORM&#8217;s debug mode helps you gain insights into the ORM&#8217;s behavior and troubleshoot query-related issues effectively.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Logging and Analyzing Queries<\/h4>\n\n\n\n<p>Effective <a href=\"https:\/\/dev.to\/aspittel\/how-i-built-an-api-with-mux-go-postgresql-and-gorm-5ah8\">logging and analysis of queries<\/a> are crucial for diagnosing and resolving issues in your application. Here are some best practices for logging and analyzing queries in GORM:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Custom Logger<\/strong>: Implement a custom logger to capture detailed information about each query.<code class=\"language-go\">import (<br>    \"gorm.io\/gorm\/logger\"<br>    \"log\"<br>    \"os\"<br>)<br><br>newLogger := logger.New(<br>    log.New(os.Stdout, \"rn\", log.LstdFlags),<br>    logger.Config{<br>        SlowThreshold: time.Second,<br>        LogLevel:      logger.Info,<br>        Colorful:      true,<br>    },<br>)<br>db, err := gorm.Open(mysql.Open(dsn), &amp;gorm.Config{<br>    Logger: newLogger,<br>})<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Slow Query Analysis<\/strong>: Identify and optimize slow queries by setting a threshold for logging slow queries.<code class=\"language-go\">newLogger := logger.New(<br>    log.New(os.Stdout, \"rn\", log.LstdFlags),<br>    logger.Config{<br>        SlowThreshold: 200 * time.Millisecond,<br>        LogLevel:      logger.Warn,<br>        Colorful:      true,<br>    },<br>)<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Query Metrics<\/strong>: Integrate with monitoring tools like Prometheus to collect and analyze query metrics.<code class=\"language-go\">import (<br>    \"github.com\/prometheus\/client_golang\/prometheus\"<br>    \"github.com\/prometheus\/client_golang\/prometheus\/promhttp\"<br>    \"net\/http\"<br>)<br><br>queryDuration := prometheus.NewHistogramVec(<br>    prometheus.HistogramOpts{<br>        Name: \"query_duration_seconds\",<br>        Help: \"Duration of database queries.\",<br>    },<br>    []string{\"query\"},<br>)<br>prometheus.MustRegister(queryDuration)<br><br>http.Handle(\"\/metrics\", promhttp.Handler())<br>go http.ListenAndServe(\":8080\", nil)<\/code><\/p><\/li>\n<\/ol>\n\n\n\n<p>By implementing these logging and analysis techniques, you can gain valuable insights into your application&#8217;s database interactions and optimize performance accordingly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Building_a_Go_App_with_GORM_and_TiDB\"><\/span>Building a Go App with GORM and TiDB<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Integrating <strong>TiDB<\/strong> with <strong>GORM<\/strong> in your Go applications can significantly enhance performance, scalability, and ease of development. This section will guide you through setting up a TiDB cluster, connecting GORM to TiDB, and leveraging TiDB&#8217;s <a href=\"https:\/\/docs.pingcap.com\/tidb\/stable\/dev-guide-sample-application-golang-gorm\">unique features<\/a> to build a robust application.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setting Up TiDB<\/h3>\n\n\n\n<p>Before you can start using TiDB with GORM, you need to set up a TiDB cluster. TiDB offers several deployment options, including serverless and dedicated clusters, to suit different needs.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Creating a TiDB Cluster<\/h4>\n\n\n\n<p>To create a TiDB cluster, follow these steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Choose Your Deployment Method<\/strong>:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Serverless<\/strong>: Ideal for development and testing environments.<\/li>\n\n\n\n<li><strong>Dedicated<\/strong>: Suitable for production environments requiring high availability and performance.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Create a Cluster<\/strong>:<\/p>\n<ul class=\"wp-block-list\">\n<li>For a serverless cluster, visit the <a href=\"https:\/\/tidbcloud.com\/console\/clusters\">TiDB Cloud Console<\/a> and follow the prompts to create a new cluster.<\/li>\n\n\n\n<li>For a dedicated cluster, you can use <a href=\"https:\/\/docs.pingcap.com\/tidb\/stable\/production-deployment-using-tiup\">TiUP<\/a> to deploy a local or cloud-based cluster.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Configure Access<\/strong>:<\/p>\n<ul class=\"wp-block-list\">\n<li>Once your cluster is up and running, configure access by setting up user credentials and network permissions. Ensure you have the necessary connection details like host, port, user, and password.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Connecting GORM to TiDB<\/h4>\n\n\n\n<p>With your TiDB cluster ready, the next step is to connect GORM to TiDB. Here&#8217;s how you can do it:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Install Required Packages<\/strong>:<code class=\"language-sh\">go get -u gorm.io\/gorm<br>go get -u gorm.io\/driver\/mysql<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Set Up Connection String<\/strong>:<\/p>\n<ul class=\"wp-block-list\">\n<li>Create a <code>.env<\/code> file in your project directory and add your TiDB connection details:<br><pre><code class=\"language-env\">TIDB_HOST='your_tidb_host'<br>TIDB_PORT='4000'<br>TIDB_USER='your_user'<br>TIDB_PASSWORD='your_password'<br>TIDB_DB_NAME='your_database'<br>USE_SSL='true'<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Initialize GORM with TiDB<\/strong>:<\/p>\n<ul class=\"wp-block-list\">\n<li>Use the following code snippet to connect GORM to your TiDB database:<br><pre><code class=\"language-go\">package main<br><br>import (<br>    \"gorm.io\/driver\/mysql\"<br>    \"gorm.io\/gorm\"<br>    \"log\"<br>    \"os\"<br>)<br><br>func main() {<br>    dsn := os.Getenv(\"TIDB_USER\") + \":\" + os.Getenv(\"TIDB_PASSWORD\") + \"@tcp(\" + os.Getenv(\"TIDB_HOST\") + \":\" + os.Getenv(\"TIDB_PORT\") + \")\/\" + os.Getenv(\"TIDB_DB_NAME\") + \"?charset=utf8mb4&amp;parseTime=True&amp;loc=Local\"<br>    db, err := gorm.Open(mysql.Open(dsn), &amp;gorm.Config{})<br>    if err != nil {<br>        log.Fatal(err)<br>    }<br>    \/\/ Use db object for database operations<br>}<\/code><\/pre><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Leveraging TiDB Features<\/h3>\n\n\n\n<p>TiDB offers several unique features that can be leveraged to optimize your Go applications. Here, we&#8217;ll focus on two key features: <code>AUTO_RANDOM<\/code> and secondary indexes.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Using AUTO_RANDOM<\/h4>\n\n\n\n<p>The <code>AUTO_RANDOM<\/code> feature in TiDB helps distribute data more evenly across the cluster, reducing hotspots and improving write performance. To use <a href=\"https:\/\/github.com\/tidb-samples\/tidb-golang-gorm-quickstart\"><code>AUTO_RANDOM<\/code> with GORM<\/a>, define your model as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-go\">type User struct {\n    ID   uint64 `gorm:\"primaryKey;autoIncrement:false;column:id\"`\n    Name string `gorm:\"size:255;not null\"`\n}\nfunc (User) TableName() string {\n    return \"users\"\n}\n<\/code>\n<\/pre>\n\n\n\n<p>In your SQL schema, you can enable <code>AUTO_RANDOM<\/code> for the primary key:<\/p>\n\n\n\n<pre class=\"wp-block-code\">\n<code class=\"language-sql\">CREATE TABLE users (\n    id BIGINT PRIMARY KEY AUTO_RANDOM,\n    name VARCHAR(255) NOT NULL\n);\n<\/code>\n<\/pre>\n\n\n\n<p>This setup ensures that new records are distributed evenly, enhancing performance and scalability.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Optimizing with Secondary Indexes<\/h4>\n\n\n\n<p>Secondary indexes are crucial for optimizing query performance, especially for large datasets. TiDB supports creating various types of indexes to speed up data retrieval.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Define Indexes in Your Model<\/strong>:<code class=\"language-go\">type Product struct {<br>    Code  string `gorm:\"uniqueIndex\"`<br>    Price float64<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Create Composite Indexes<\/strong>:<code class=\"language-go\">type Order struct {<br>    UserID    uint `gorm:\"index\"`<br>    ProductID uint `gorm:\"index\"`<br>    gorm.Model<br>}<\/code><\/p><\/li>\n\n\n\n<li><p><strong>Use SQL to Define Indexes<\/strong>:<code class=\"language-sql\">CREATE INDEX idx_user_product ON orders (user_id, product_id);<\/code><\/p><\/li>\n<\/ol>\n\n\n\n<p>By strategically using secondary indexes, you can significantly reduce query times and improve the overall performance of your application.<\/p>\n\n\n\n<p>Leveraging these TiDB features allows you to build a Go app with GORM that is not only efficient but also scalable and robust, capable of handling high loads and complex queries with ease.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>In this blog, we&#8217;ve explored key best practices for building robust Go applications with GORM, from setting up your environment to optimizing performance and handling errors. By applying these practices, you can simplify database interactions, enhance code maintainability, and improve overall application efficiency.<\/p>\n\n\n\n<p>We encourage you to implement these strategies in your real-world projects. As <strong>Thirdfort<\/strong> highlights, adopting GORM allows developers to focus on application logic rather than database complexities, boosting productivity and system security.<\/p>\n\n\n\n<p>Feel free to share your experiences and questions. Your feedback is invaluable in fostering a community of continuous improvement and innovation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"See_Also\"><\/span>See Also<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><a href=\"https:\/\/www.pingcap.com\/article\/best-practices-for-databases-on-kubernetes\/\">Optimal Strategies for Kubernetes Database Management<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.pingcap.com\/article\/move-on-from-mysql-5-key-considerations-towards-scalability-and-performance\/\">Transitioning Beyond MySQL: 5 Vital Factors for Growth and Speed<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.pingcap.com\/article\/building-a-retrieval-augmented-generation-application-with-llamaindex-and-mysql-compatible-database\/\">Constructing RAG App with LlamaIndex and TiDB Serverless Database<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.pingcap.com\/article\/openai-and-mysql-integration-innovative-web-app-features\/\">Innovative Web App Features through OpenAI and MySQL Fusion<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.pingcap.com\/article\/in-age-of-llm-how-to-store-vectors-with-mysql-sql-grammar\/\">Storing Vectors in MySQL SQL Grammar Era of LLM<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Master building robust Go applications with GORM. Learn best practices for setup, database design, efficient querying, performance optimization, and error handling.<\/p>","protected":false},"author":8,"featured_media":0,"template":"","class_list":["post-18522","article","type-article","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Building Robust Go Applications with GORM: Best Practices<\/title>\n<meta name=\"description\" content=\"Master building robust Go applications with GORM. Learn best practices for setup, database design, efficient querying, performance optimization, and error handling.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pingcap.com\/ko\/article\/building-robust-go-applications-with-gorm-best-practices\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building Robust Go Applications with GORM: Best Practices\" \/>\n<meta property=\"og:description\" content=\"Master building robust Go applications with GORM. Learn best practices for setup, database design, efficient querying, performance optimization, and error handling.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.pingcap.com\/ko\/article\/building-robust-go-applications-with-gorm-best-practices\/\" \/>\n<meta property=\"og:site_name\" content=\"TiDB\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/pingcap2015\" \/>\n<meta property=\"article:modified_time\" content=\"2024-12-12T08:05:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/static.pingcap.com\/files\/2024\/09\/11005522\/Homepage-Ad.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1440\" \/>\n\t<meta property=\"og:image:height\" content=\"714\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@PingCAP\" \/>\n<meta name=\"twitter:label1\" content=\"\uc608\uc0c1 \ub418\ub294 \ud310\ub3c5 \uc2dc\uac04\" \/>\n\t<meta name=\"twitter:data1\" content=\"18\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/\",\"url\":\"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/\",\"name\":\"Building Robust Go Applications with GORM: Best Practices\",\"isPartOf\":{\"@id\":\"https:\/\/www.pingcap.com\/#website\"},\"datePublished\":\"2024-07-18T07:13:07+00:00\",\"dateModified\":\"2024-12-12T08:05:35+00:00\",\"description\":\"Master building robust Go applications with GORM. Learn best practices for setup, database design, efficient querying, performance optimization, and error handling.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.pingcap.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Articles\",\"item\":\"https:\/\/www.pingcap.com\/article\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Building Robust Go Applications with GORM: Best Practices\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.pingcap.com\/#website\",\"url\":\"https:\/\/www.pingcap.com\/\",\"name\":\"TiDB\",\"description\":\"TiDB | SQL at Scale\",\"publisher\":{\"@id\":\"https:\/\/www.pingcap.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.pingcap.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.pingcap.com\/#organization\",\"name\":\"PingCAP\",\"url\":\"https:\/\/www.pingcap.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png\",\"contentUrl\":\"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png\",\"width\":811,\"height\":232,\"caption\":\"PingCAP\"},\"image\":{\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/facebook.com\/pingcap2015\",\"https:\/\/x.com\/PingCAP\",\"https:\/\/linkedin.com\/company\/pingcap\",\"https:\/\/youtube.com\/channel\/UCuq4puT32DzHKT5rU1IZpIA\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building Robust Go Applications with GORM: Best Practices","description":"Master building robust Go applications with GORM. Learn best practices for setup, database design, efficient querying, performance optimization, and error handling.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.pingcap.com\/ko\/article\/building-robust-go-applications-with-gorm-best-practices\/","og_locale":"ko_KR","og_type":"article","og_title":"Building Robust Go Applications with GORM: Best Practices","og_description":"Master building robust Go applications with GORM. Learn best practices for setup, database design, efficient querying, performance optimization, and error handling.","og_url":"https:\/\/www.pingcap.com\/ko\/article\/building-robust-go-applications-with-gorm-best-practices\/","og_site_name":"TiDB","article_publisher":"https:\/\/facebook.com\/pingcap2015","article_modified_time":"2024-12-12T08:05:35+00:00","og_image":[{"width":1440,"height":714,"url":"https:\/\/static.pingcap.com\/files\/2024\/09\/11005522\/Homepage-Ad.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_site":"@PingCAP","twitter_misc":{"\uc608\uc0c1 \ub418\ub294 \ud310\ub3c5 \uc2dc\uac04":"18\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/","url":"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/","name":"Building Robust Go Applications with GORM: Best Practices","isPartOf":{"@id":"https:\/\/www.pingcap.com\/#website"},"datePublished":"2024-07-18T07:13:07+00:00","dateModified":"2024-12-12T08:05:35+00:00","description":"Master building robust Go applications with GORM. Learn best practices for setup, database design, efficient querying, performance optimization, and error handling.","breadcrumb":{"@id":"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.pingcap.com\/article\/building-robust-go-applications-with-gorm-best-practices\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pingcap.com\/"},{"@type":"ListItem","position":2,"name":"Articles","item":"https:\/\/www.pingcap.com\/article\/"},{"@type":"ListItem","position":3,"name":"Building Robust Go Applications with GORM: Best Practices"}]},{"@type":"WebSite","@id":"https:\/\/www.pingcap.com\/#website","url":"https:\/\/www.pingcap.com\/","name":"\ud2f0DB","description":"TiDB | SQL at Scale","publisher":{"@id":"https:\/\/www.pingcap.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pingcap.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.pingcap.com\/#organization","name":"PingCAP","url":"https:\/\/www.pingcap.com\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/","url":"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png","contentUrl":"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png","width":811,"height":232,"caption":"PingCAP"},"image":{"@id":"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/pingcap2015","https:\/\/x.com\/PingCAP","https:\/\/linkedin.com\/company\/pingcap","https:\/\/youtube.com\/channel\/UCuq4puT32DzHKT5rU1IZpIA"]}]}},"card_markup":"        <a class=\"card-article\" href=\"https:\/\/www.pingcap.com\/ko\/article\/building-robust-go-applications-with-gorm-best-practices\/\">            <h3>Building Robust Go Applications with GORM: Best Practices<\/h3>            <p>Master building robust Go applications with GORM. Learn best practices for setup, database design, efficient querying, performance optimization, and error handling.<\/p>        <\/a>","_links":{"self":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/article\/18522","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/users\/8"}],"wp:attachment":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/media?parent=18522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}