>  기사  >  백엔드 개발  >  데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동)

데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동)

藏色散人
藏色散人앞으로
2020-10-27 13:50:212275검색

에서 소개한 내용입니다. DataBase/SQL을 사용할 때 이 11가지 함정에 빠지지 않도록 하세요. 필요한 친구들에게 도움이 되길 바랍니다!

우리는 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동) 언어와 해당 데이터베이스 액세스 라이브러리 database/sql의 열렬한 팬입니다. 아마도 눈으로 볼 수 있듯이 database/sql은 매우 작지만 이를 통해 많은 일을 할 수 있습니다. 여기에는 상당한 오류 및 기만적인 오류 위험이 포함됩니다. 이 블로그 게시물은 여러분이 같은 실수를 반복하지 않기를 바라면서 과거에 우리가 저지른 몇 가지 실수에 대해 다룹니다.

일반적인 함정

  • 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동)루프 내 지연.

    수명이 긴 함수에는 루프 내에 쿼리가 있으며 루프 내에서 rows.Close()를 지연하면 메모리와 연결 사용량이 모두 제한 없이 증가합니다. database/sql 的忠实粉丝。正如你可能亲眼看到的那样,database/sql 的体积非常小,但是你可以用它做很多事情。这包括大量的错误和欺骗性错误的风险。这篇博文专门介绍我们过去犯过的一些错误,希望到时候你不会再犯同样的错误。

    常见陷阱

    • 在循环内延迟。 长生命期函数在循环内有查询,在循环内延迟 rows.Close(),会导致内存和连接使用量都无限制地增长。

    • 打开许多 db 对象。 请创建一个全局sql.DB,并且不要为你的 API 服务器应该响应的每个传入 HTTP 请求打开一个新的。否则,你将打开和关闭大量到数据库的 TCP 连接。 TIME_WAIT 状态下的延迟,负载和 TCP 连接很多。

    • 操作完成后不做 rows.Close() 忘记关闭 rows 变量意味着连接泄漏。再加上服务器上不断增长的负载,这可能意味着会遇到 max_connections 错误或类似情况。请尽快运行 rows.Close() ,即使它稍后会再次用到(也是无害的)。出于同样的原因,将 db.QueryRow().Scan() 链接在一起。

    • 预处理语句膨胀。 如果代码以高并发运行,请考虑预处理语句是否是正确的解决方案,因为当连接繁忙时,它们可能会在不同的连接上多次重新预处理。

    • strconv 或 casts 使代码杂乱无章。 建议将结果扫描到一个你想要的类型的变量中,让 .Scan() 在幕后为你转换。

    • 错误处理和重试导致代码混乱。database/sql 为你处理连接池、重新连接和重试逻辑。

    • rows.Next() 之后忘记检查错误。 别忘了,rows.Next() 循环可能会异常退出。

    • 使用 db.Query() 进行非 SELECT 查询。 如果没有结果集,不要告诉 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동) 你希望在结果集上迭代,否则会泄露连接。

    • 假设后续语句使用相同的连接。 如果连续运行两个语句,则它们很可能在两个不同的连接上运行。运行 LOCK TABLES tbl1 WRITE,然后运行SELECT * FROM tbl1,你很可能会阻塞并等待。如果需要保证使用单条语句,则需要使用参数 sql.Tx

    • 在使用 TX 的同时访问数据库。 sql.Tx 与事务绑定,但数据库没有绑定,所以访问它不会参与事务。

    • 对一个 NULL 感到惊讶。 你不能将一个 NULL 类型扫描成变量,除非它是 database/sql 包提供的 NullXXX 类型之一(或者是你自己制作的,或者是驱动提供的),否则。仔细检查您的模式,因为如果一个列可以是 NULL,那么总有一天它会变成 NULL

    많은 db 개체를 엽니다.
    전역 sql.DB를 생성하고 API 서버가 응답해야 하는 모든 수신 HTTP 요청에 대해 새 DB를 열지 마세요. 그렇지 않으면 데이터베이스에 대한 많은 TCP 연결을 열고 닫게 됩니다. TIME_WAIT 상태의 지연 시간, 많은 로드 및 TCP 연결.

  • 작업이 완료된 후에는 rows.Close()를 수행하지 마세요.
  • 행 변수를 닫는 것을 잊는 것은 연결 누출을 의미합니다. 서버의 로드 증가와 함께 이는 max_connections 오류 또는 유사한 상황이 발생할 수 있음을 의미할 수 있습니다. 나중에 다시 사용하더라도 최대한 빨리 rows.Close()를 실행하세요(무해합니다). 같은 이유로 db.QueryRow().Scan()을 함께 연결합니다. 🎜🎜
  • 🎜🎜준비된 문장이 부풀어오릅니다. 🎜 코드가 높은 동시성으로 실행되는 경우 준비된 문이 올바른 솔루션인지 고려하세요. 연결이 사용 중일 때 다른 연결에서 여러 번 다시 준비될 수 있기 때문입니다. 🎜🎜
  • 🎜🎜strconv 또는 캐스트는 코드를 복잡하게 만듭니다. 🎜 결과를 원하는 유형의 변수로 스캔하고 .Scan()이 뒤에서 변환을 수행하도록 하는 것이 좋습니다. 🎜🎜
  • 🎜🎜오류 처리 및 재시도는 코드를 혼란스럽게 만듭니다. 🎜 database/sql이 연결 풀링, 재연결 및 재시도 로직을 처리하도록 하세요. 🎜🎜
  • 🎜🎜rows.Next() 이후 오류를 확인하는 것을 잊어버렸습니다. 🎜 잊지 마세요. rows.Next() 루프가 비정상적으로 종료될 수 있습니다. 🎜🎜
  • 🎜🎜SELECT가 아닌 쿼리에는 db.Query()를 사용하세요. 🎜 결과 세트가 없으면 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동)에게 결과 세트를 반복하겠다고 말하지 마세요. 그렇지 않으면 연결이 누출됩니다. 🎜🎜
  • 🎜🎜다음 명령문이 동일한 조인을 사용한다고 가정합니다. 🎜 두 개의 명령문을 연속해서 실행하는 경우 두 개의 서로 다른 연결에서 실행될 가능성이 높습니다. LOCK TABLES tbl1 WRITE를 실행한 다음 SELECT * FROM tbl1을 실행하면 차단하고 기다릴 가능성이 높습니다. 단일 문이 사용되는지 확인해야 하는 경우 sql.Tx 매개 변수를 사용해야 합니다. 🎜🎜
  • 🎜🎜TX를 사용하는 동안 데이터베이스에 액세스하세요. 🎜 sql.Tx는 트랜잭션에 바인딩되어 있지만 데이터베이스는 바인딩되어 있지 않으므로 이에 액세스해도 트랜잭션에 참여하지 않습니다. 🎜🎜
  • 🎜🎜NULL에 놀랐습니다. 🎜 database/sql 패키지(또는 사용자 고유의 패키지)에서 제공하는 NullXXX 유형 중 하나가 아닌 한 NULL 유형을 변수로 스캔할 수 없습니다. 드라이버가 생산 또는 제공), 그렇지 않은 경우. 열이 NULL일 수 있으면 어느 날 NULL이 되고 테스트에서 작동하는 것이 프로덕션 축소에서는 작동하지 않을 수 있으므로 스키마를 주의 깊게 확인하십시오. 🎜🎜🎜🎜🎜원본 주소: https://orangematter.solarwinds.com/2017/03/23/common-pitfalls-when-using-database-sql-in-go/🎜🎜번역 주소: https://learnku .com/go/t/50966🎜🎜

위 내용은 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
이전 기사:Go 포인터 소개다음 기사:Go 포인터 소개