Heim  >  Artikel  >  Backend-Entwicklung  >  Vermeiden Sie diese 11 Fallstricke bei der Verwendung von Datenbank/SQL! (Gehe zur Datenbank)

Vermeiden Sie diese 11 Fallstricke bei der Verwendung von Datenbank/SQL! (Gehe zur Datenbank)

藏色散人
藏色散人nach vorne
2020-10-27 13:50:212244Durchsuche

, um Ihnen vorzustellen, wie Sie bei der Verwendung von DataBase/SQL nicht in diese 11 Fallstricke geraten. Ich hoffe, dass es Freunden, die es benötigen, hilfreich sein wird!

Wir sind große Fans der Vermeiden Sie diese 11 Fallstricke bei der Verwendung von Datenbank/SQL! (Gehe zur Datenbank)-Sprache und ihrer Datenbankzugriffsbibliothek database/sql. Wie Sie wahrscheinlich mit eigenen Augen sehen können, ist database/sql sehr klein, aber Sie können damit eine Menge machen. Dies birgt erhebliche Fehler- und Täuschungsrisiken. Dieser Blogbeitrag widmet sich einigen Fehlern, die wir in der Vergangenheit gemacht haben, in der Hoffnung, dass Sie dieselben Fehler nicht noch einmal machen.

Häufige Fallstricke

  • Vermeiden Sie diese 11 Fallstricke bei der Verwendung von Datenbank/SQL! (Gehe zur Datenbank)Verzögerung innerhalb einer Schleife.

    Langlebige Funktionen haben Abfragen innerhalb der Schleife und eine Verzögerung von rows.Close() innerhalb der Schleife führt dazu, dass die Speicher- und Verbindungsnutzung unbegrenzt wächst. 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 查询。 如果没有结果集,不要告诉 Vermeiden Sie diese 11 Fallstricke bei der Verwendung von Datenbank/SQL! (Gehe zur Datenbank) 你希望在结果集上迭代,否则会泄露连接。

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

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

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

    Öffnen Sie viele db-Objekte.
    Bitte erstellen Sie eine globale sql.DB und öffnen Sie nicht für jede eingehende HTTP-Anfrage, auf die Ihr API-Server antworten soll, eine neue. Andernfalls öffnen und schließen Sie viele TCP-Verbindungen zur Datenbank. Latenz im Status TIME_WAIT, viel Last und TCP-Verbindungen.

  • Führen Sie rows.Close() nicht aus, nachdem der Vorgang abgeschlossen ist.
  • Wenn Sie vergessen, die Zeilenvariable zu schließen, liegt ein Verbindungsleck vor. In Kombination mit der zunehmenden Auslastung des Servers kann dies dazu führen, dass max_connections-Fehler oder ähnliche Situationen auftreten. Bitte führen Sie rows.Close() so schnell wie möglich aus, auch wenn es später erneut verwendet wird (was harmlos ist). Verketten Sie db.QueryRow() und .Scan() aus demselben Grund miteinander. 🎜🎜
  • 🎜🎜Vorbereitete Statement-Aufblähung. 🎜 Wenn der Code mit hoher Parallelität ausgeführt wird, überlegen Sie, ob vorbereitete Anweisungen die richtige Lösung sind, da sie möglicherweise mehrmals auf verschiedenen Verbindungen neu vorbereitet werden, wenn die Verbindung ausgelastet ist. 🎜🎜
  • 🎜🎜strconv oder Casts überladen Ihren Code. 🎜 Es wird empfohlen, die Ergebnisse in eine Variable des gewünschten Typs zu scannen und .Scan() die Konvertierung hinter den Kulissen für Sie durchführen zu lassen. 🎜🎜
  • 🎜🎜Fehlerbehandlung und Wiederholungsversuche führen zu verwirrendem Code. 🎜 Lassen Sie database/sql das Verbindungspooling, die Wiederverbindung und die Wiederholungslogik für Sie übernehmen. 🎜🎜
  • 🎜🎜Ich habe vergessen, nach rows.Next() nach Fehlern zu suchen. 🎜 Vergessen Sie nicht, dass die rows.Next()-Schleife möglicherweise abnormal beendet wird. 🎜🎜
  • 🎜🎜Verwenden Sie db.Query() für Nicht-SELECT-Abfragen. 🎜 Wenn kein Ergebnissatz vorhanden ist, teilen Sie Vermeiden Sie diese 11 Fallstricke bei der Verwendung von Datenbank/SQL! (Gehe zur Datenbank) nicht mit, dass Sie über den Ergebnissatz iterieren möchten, da sonst die Verbindung verloren geht. 🎜🎜
  • 🎜🎜Gehen Sie davon aus, dass nachfolgende Anweisungen denselben Join verwenden. 🎜 Wenn Sie zwei Anweisungen nacheinander ausführen, werden sie höchstwahrscheinlich auf zwei verschiedenen Verbindungen ausgeführt. Führen Sie LOCK TABLES tbl1 WRITE und dann SELECT * FROM tbl1 aus, und Sie werden höchstwahrscheinlich blockieren und warten. Wenn Sie sicherstellen müssen, dass eine einzelne Anweisung verwendet wird, müssen Sie den Parameter sql.Tx verwenden. 🎜🎜
  • 🎜🎜Greifen Sie auf die Datenbank zu, während Sie TX verwenden. 🎜 sql.Tx ist an eine Transaktion gebunden, aber die Datenbank ist nicht gebunden, sodass ein Zugriff darauf nicht an der Transaktion beteiligt ist. 🎜🎜
  • 🎜🎜Überrascht von einem NULL. 🎜 Sie können einen NULL-Typ nicht in eine Variable scannen, es sei denn, es handelt sich um einen der vom database/sql-Paket (oder Ihrem eigenen) bereitgestellten NullXXX-Typen hergestellt oder vom Fahrer bereitgestellt), andernfalls. Überprüfen Sie Ihr Schema sorgfältig, denn wenn eine Spalte NULL sein kann, wird sie eines Tages zu NULL, und was im Test funktioniert, funktioniert möglicherweise nicht im Produktionszusammenbruch. 🎜🎜🎜🎜🎜Originaladresse: https://orangematter.solarwinds.com/2017/03/23/common-pitfalls-when-using-database-sql-in-go/🎜🎜Übersetzungsadresse: https://learnku .com/go/t/50966🎜🎜

Das obige ist der detaillierte Inhalt vonVermeiden Sie diese 11 Fallstricke bei der Verwendung von Datenbank/SQL! (Gehe zur Datenbank). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Vorheriger Artikel:Einführung in Go-ZeigerNächster Artikel:Einführung in Go-Zeiger