SQLite 中的各種限制

來源:互聯網
上載者:User

標籤:

英文原文:Limits In SQLite 
   

本文定義了 SQLite 的限制,如何針對這些限制定製特定的應用程式。預設的限制設定通常是適當的,幾乎適合於每一個應用。有一些應用程式可能需要在這裡或者那裡增加一個設定,但是我們估計這非常罕見。更普遍的是,應用程式可能需要重新編譯SQLite以及更低的限制來避免過多的資源使用率,以及在進階SQL語句產生器上協助阻止攻擊者注入惡意SQL語句時發生錯誤。

在使用 sqlite3_limit() 介面的 limit categories 上,為該介面定義一些限制,可以在運行時改變每個基礎的串連。應用程式設計的運行時限制多資料庫,一些僅供內部使用的限制可以影響或控制潛在的敵對外部代理。舉例來說,一個web瀏覽器應用程式可能使用一個內部的資料庫來追蹤曆史頁面瀏覽量,但是它有一個或很多分離的資料庫,它們被建立和控制是通過 javascript 應用,這些應用都是從互連網上下載的。那麼 sqlite3_limit() 介面是允許通過可信代碼來管理約束內建資料庫的,同時在資料庫建立或控制上有著嚴格的限制,它會拒絕不可信的外部代碼攻擊服務。

 

 

無若
翻譯於 7天前

0人頂

 

頂 翻譯的不錯哦!

1、string或者BLOB的最大長度

SQLite中string或者BLOB的最大位元組數是由前置處理器宏SQLITE_MAX_LENGTH定義的。這個宏的預設值是10億,你可以在編譯時間使用像下面這樣的命令列參數來對這個預設值進行調整:

-DSQLITE_MAX_LENGTH=123456789

在當前實現中僅支援將string或者BLOB長度上調到最大231-1 or 2147483647。並且這個時候一些內建的函數例如hex()將會調用失敗。在安全敏感的應用中最好不要嘗試增加string和BlOB的最大長度。實際上,如果可以的話,你可以將string和BLOB的最大長度在一定範圍內降低(幾百方位元組)。

在SQLite的INSERT和SELECT處理時,資料庫中中的每一行的所有內容都被編碼成單個BLOB。所以SQLITE_MAX_LENGTH這個參數同樣也定義了一行的最大位元組數。string或者BLOB的最大長度可以在運行時通過sqlite3_limit(db,SQLITE_LIMIT_LENGTH,size) 方法調低。

2、最大列數

SQLITE_MAX_COLUMN在編譯時間用來設定一個上限:預設設定SQLITE_MAX_COLUMN的值是2000。你可以在編譯的時候將它調整到最大32767。另一方面,許多經驗豐富的資料庫設計者會認為一個設計良好的資料庫永遠都不會在表中需要超過100列。

在大多數應用中的列數是很小的,大約幾十個而已。在SQLite代碼產生器中使用的演算法是O(N²),這個N就是列數。所以如果你重新定義SQLITE_MAX_COLUMN為一個巨大的數字,那麼在產生SQL的時候使用這個大列數你就會發現sqlite3_prepare_v2() 啟動並執行很慢。最大列數可以在運行時使用sqlite3_limit(db,SQLITE_LIMIT_COLUMN,size) 方法調低。

  • 表中的列數

  • 索引中的列數

  • 視圖中的列數

  • UPDATE語句中SET子句中的項數

  • SELECT語句結果集中的列數

  • GROUP BY 或者 ORDER BY子句中的項數

  • INSERT語句中的value項數

氣質舞王尼古拉斯趙四
翻譯於 5天前

0人頂

 

頂 翻譯的不錯哦!

    • SQL語句的最大長度

       一個SQL語句文本中位元組數的最大值,受限於 SQLITE_MAX_SQL_LENGTH ,其預設為 1000000。你可以重新對這個限制進行定義,大到 SQLITE_MAX_LENGTH 和 1073741824 兩者中較小的一個值。 

      如果一個SQL語句在長度上被限制在1百萬個位元組以內,那麼很明顯你就不能夠以字串字面量的形式將幾百萬位元組嵌入到 INSERT 語句中。不過你應該是不會那樣做的。這時候針對這些資料你可以使用佔位參數,像下面這樣先準備好一個簡短的SQL語句:

      INSERT INTO tab1 VALUES(?,?,?);

      然後使用 sqlite3 的_bind_XXXX() 函數來將大型的字串值綁定到這個SQL語句。綁定的使用迴避掉了要在字串中對引號進行轉義的必要, 同時降低了遭受SQL注入攻擊的風險。它運行起來也更快,因為大型的字串不必進行其它方式要進行的多次轉換和複製操作。 

      SQL語句的最大長度可以在運行時使用 sqlite3 的_limit(db,SQLITE_LIMIT_SQL_LENGTH,size) 介面來減小。

    • 一次串連操作中最大的表數量

       SQLite 不支援超過64個表的串連操作。此限制源於在查詢最佳化工具中,SQLite代碼產生器會使用每個串連表一個位的位元影像,這一事實。 

      SQLite 使用了一種高效的 查詢規劃器演算法 ,因此即使是一個大型地串連操作也能被快速地被 預先處理好。 所以沒有任何機制來提高或者降低一次串連操作中表的數量。


  • 運算式樹狀架構結構的最大深度

     SQLite 會將表達解析成一個數結構來進行處理。在代碼產生期間,SQLite會以遞迴的形式遍曆這個樹結構。運算式樹狀架構結構的深度因此被加上了限制,以此避免用掉太多的棧空間。 

    SQLITE_MAX_EXPR_DEPTH 參數決定了運算式樹狀架構結構的最大深度。如果其值為 0,就表示不加任何限制。目前的實現所使用的預設值是 1000。 

    如果 SQLITE_MAX_EXPR_DEPTH 初始是正數,那麼表達書樹結構的最大深度可以在運行時使用 sqlite3 的_limit(db,SQLITE_LIMIT_EXPR_DEPTH,size) 介面來降低。換言之,如果已經在編譯時間對錶達式深度做了限制,那麼運算式樹狀架構結構深度的最大值就可以在運行時被降低。如果If SQLITE_MAX_EXPR_DEPTH 的值在編譯時間被設定為 0(即運算式的深度不受限制),那麼sqlite3 的_limit(db,SQLITE_LIMIT_EXPR_DEPTH,size) 介面就是一個無效操作。

leoxu
翻譯於 4天前

0人頂

 

頂 翻譯的不錯哦!

    • 函數裡參數的最大數量 

      SQLITE_MAX_FUNCTION_ARG 參數決定了能夠被傳入到一個SQL函數的參數的最大數量。這一限制的預設值為100。SQLite 應該在函擁有數以千計的參數時也能運作。不過,我們對於那些使用過多參數的人持懷疑態度,因為他們可能是在嘗試找出使用了SQLite的系統中的安全性漏洞,而不是做一些實用的事情, 而因為這個原有,我們已經給這個參數設定了相對而言較低的值。 

      傳入函數的參數數量有時會被儲存在一個有符號的字元中,因此 SQLITE_MAX_FUNCTION_ARG 有一個限定死的 127 的上限。 

      一個函數中的參數的最大數量可以在運行時使用 sqlite3 的_limit(db,SQLITE_LIMIT_FUNCTION_ARG,size) 介面來降低。


    • 一個複合SELECT語句中段落的最大數量 

      一個複合 SELECT 語句就是那種由操作符 UNION, UNION ALL, EXCEPT, 或者 INTERSECT 串連起來的兩個或者更多個SQL語句。我們將一個複合SELECT中的每一個獨立的SELECT語句稱為一個“段落”。 

      SQLite中的代碼產生器會使用一種遞迴演算法來對複合SELECT語句進行處理。對棧的大小有必要進行一下限制,我們會因為這個緣故對複合SELECT中的段落數量進行限制。段落的最大數量限制參數就是 SQLITE_MAX_COMPOUND_SELECT ,其預設值為 500。我們認為這已經是一個比較寬裕的分配方案了,因為在實際使用中很少會遇到一個複合SELECT中段落的數量超過個位元。 

      複合SELECT段落的最大數量在運行時可以使用 sqlite3 的_limit(db,SQLITE_LIMIT_COMPOUND_SELECT,size) 介面來降低。


  • LIKE 或者 GLOB 模式的最大數量 

    在特定的一些極端情境中,SQLite預設的LIKE和GLOB實現中所使用的模式比對演算法會表現出 O(N²) 的效能消耗(這裡的N指的是模式中字元的數量。為了避免遭受來自那些能夠自己指定 LIKE 或者 GLOB 模式的人所進行的拒絕服務的攻擊, LIKE 或者 GLOB 模式的長度被 SQLITE_MAX_LIKE_PATTERN_LENGTH 所指定的位元值進行了限定。這個的預設值為 50000。現代的工作站能夠以相對較快的速度計算出一個擁有50000位這樣極端長度的 LIKE 或者 GLOB 模式。拒絕服務的攻擊的問題只有在模式長度達到百萬個位元組位元這樣的程度時才會造成影響。不過因為大多數實用的 LIKE 或者 GLOB模式長度大多隻有幾十個位元組,偏執的開發人員如果知道外部使用者擁有產生任意模式的能力,也許就會想要把這個參數限制到幾百個這樣的範圍之內。  

    LIKE 或者 GLOB 模式的最大長度可以在運行時使用 sqlite3 的_limit(db,SQLITE_LIMIT_LIKE_PATTERN_LENGTH,size) 介面來減小。

  •  

leoxu
翻譯於 4天前

0人頂

 

頂 翻譯的不錯哦!

    • 單個SQL語句中預置參數的最大個數

       預置參數就是SQL語句中的一個預留位置,將來會被使用sqlite3 其中的一個_bind_XXXX() 介面填充。許多SQL程式員對於使用問號 ("?") 作為預置參數都很熟悉。SQLite 也支援以前置 ":", "$", 或者 "@"的命名作為預置參數,並且以“?123”這樣的形式對預置參數進行編號。 

      SQLite語句中的每一個預置參數都被分配了一個數字。該數字一般以1開始,而後對於每一個新的參數其數字加一。然而,當“?123”這樣的形式被使用了的時候,預置參數的編號就會是問號後面跟著的那個數字。 

      SQLite 會給從1到最大預置參數數量之間的預置參數分配空間。因此,一個包含了像 ?1000000000 這樣的預置參數的SQL就會需要千MB的儲存。這樣就會很容易地超過主機的資源供應能力。為了防止這種過度了記憶體配置,預置參數的最大數量就要限制到 SQLITE_MAX_VARIABLE_NUMBER 這樣一個固定值,其預設為 999。 

      預置參數的最大數量可以在運行時使用 sqlite3 的_limit(db,SQLITE_LIMIT_VARIABLE_NUMBER,size) 介面來減小。


  • 觸發器遞迴的最大深度

     SQLite 限制了觸發器的遞迴深度,一次來阻止一個涉及到遞迴觸發器的語句毫無限度的使用記憶體。 

    版本 3.6.18之前的SQLite,觸發器並非遞迴的,因此這一限制毫無意義。從版本3.6.18開始,遞迴觸發器得到了支援,但必須使用 PRAGMA recursive_triggers 語句來明確聲明啟用了它。從版本3.7.0開始,遞迴觸發器就是預設被啟用了的,但可以使用 PRAGMA recursive_triggers 來手動禁用。SQLITE_MAX_TRIGGER_DEPTH 只在其啟用時有效。 

    觸發器遞迴的預設的最大深度為1000。

leoxu
翻譯於 4天前

0人頂

 

頂 翻譯的不錯哦!

從屬資料庫的最大數量

ATTACH 語句是一項SQLite擴充,它能讓兩個或者更多個資料庫與同一個資料庫連接聯合起來,操作起來就好像它們是一個資料庫。能夠被聯合的資料庫數量被限制到了 SQLITE_MAX_ATTACHED 這樣一個常量,其預設值為10。被聯合資料庫的最大數量不能超過125。

被聯合的資料庫的最大數量可以在運行時使用 sqlite3_limit(db,SQLITE_LIMIT_ATTACHED,size) 介面來減小。

一個資料庫檔案中頁面的最大數量

SQLite 能夠限制資料庫檔案的大小,以阻止資料庫檔案變得太大而消耗過多的磁碟空間。SQLITE_MAX_PAGE_COUNT 參數,一般會被設定成 1073741823, 就是一個資料庫檔案中頁面的最大數量。一次會造成資料庫檔案增長超過這個值的插入新資料的操作將會返回 SQLITE_FULL。

 SQLITE_MAX_PAGE_COUNT 最大的可能設定是 214748364。當最大頁面大小為 65536 時, 最大的SQLite資料庫大小就大概是140太位元組。最大頁面總數PRAGMA 可以被用來在運行時提高或者降低這個限制。

表中資料行的最大數量

表中資料行的最大數量理論上可以到 264 (18446744073709551616 or about 1.8e+19)。這一限制是不可及的,因為資料庫會首先達到140太位元組的大小限制。一個140太位元組大小的資料庫可以容納超過將近 1e+13 行的資料,而要容納這麼多行資料,只能在沒有指數資料存在,並且每一行只包含非常少量資料的時候。

leoxu
翻譯於 4天前

0人頂

 

頂 翻譯的不錯哦!

最大資料庫大小

 

每個資料庫都包含一個或多個“頁”(page)。在某個單一資料庫中,每個頁的大小相同,但是不同的資料庫擁有不同的頁大小,大小介於512位元組(含)和65536位元組(含)之間。一個資料庫檔案最多包括2147483646頁。每個頁最大65536位元組,換算可得最大資料庫大小約為1.4e+14位元組(140千萬MB或128太位元組或140000百萬MB或128000吉位元組)。由於開發人員沒有能滿足這個限制的硬體條件,所以沒有對這個上限進行測試。然而,測試表明當資料庫達到底層檔案系統的最大檔案大小(通常要比理論上的最大資料庫大小小很多)並且由於磁碟空間耗盡而無法擴充時,SQLite依然能正確並穩健地運行。

模式中表的最大數量

資料庫檔案中的每個表和索引至少需要一個頁。這裡的索引可以使用CREATE INDEX 語句顯式地建立,也可以通過UNIQUE和PRIMARY KEY約束隱式地建立。由於資料庫檔案的頁的最大數量是2147483646(比20億還多),所以模式中表和索引的數量上限也是這個。

只要資料庫被開啟,就會掃描和解析整個模式,並將模式的解析樹儲存在記憶體中。也就是說資料庫的啟動時間和初始記憶體使用量率與模式大小成正比。

http://www.oschina.net/translate/limits-in-sqlite-new

SQLite 中的各種限制

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.