Heim > Artikel > Backend-Entwicklung > Vermeiden Sie diese 11 Fallstricke bei der Verwendung von Datenbank/SQL! (Gehe zur Datenbank)
, 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 Datenbankzugriffsbibliothekdatabase/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.
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
db
-Objekte. Bitte erstellen Sie eine globaleWenn Sie vergessen, die Zeilenvariable zu schließen, liegt ein Verbindungsleck vor. In Kombination mit der zunehmenden Auslastung des Servers kann dies dazu führen, dasssql.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 StatusTIME_WAIT
, viel Last und TCP-Verbindungen.- Führen Sie
rows.Close()
nicht aus, nachdem der Vorgang abgeschlossen ist.
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. 🎜🎜.Scan()
die Konvertierung hinter den Kulissen für Sie durchführen zu lassen. 🎜🎜database/sql
das Verbindungspooling, die Wiederverbindung und die Wiederholungslogik für Sie übernehmen. 🎜🎜rows.Next()
nach Fehlern zu suchen. 🎜 Vergessen Sie nicht, dass die rows.Next()
-Schleife möglicherweise abnormal beendet wird. 🎜🎜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. 🎜🎜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. 🎜🎜sql.Tx
ist an eine Transaktion gebunden, aber die Datenbank ist nicht gebunden, sodass ein Zugriff darauf nicht an der Transaktion beteiligt ist. 🎜🎜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!