mysql为什么没有nvarchar,关于mysql:为什么不将每个VARCHAR指定为VARCHAR(65535)?
由于Varchar字段的存儲要求基于輸入的字符串的實(shí)際長度,因此將每個(gè)Varchar字段指定為最大可能值的缺點(diǎn)是什么:Varchar(65535)? 好吧,除了1個(gè)額外的字節(jié)以外,最大字段數(shù)> 255個(gè)字符?
[長度為L的字符串的存儲要求:如果列值需要0 – 255字節(jié),則L + 1字節(jié);如果值可能需要255個(gè)以上字節(jié),則L + 2字節(jié)]
謝謝!
如果不是相同的問題,請聯(lián)系:stackoverflow.com/questions/262238/
感謝大家的意見! 我是stackoverflow的新手,并真誠地感謝每個(gè)人的響應(yīng)能力。 :-)
從文檔-表的列數(shù)和行大小限制:
Every table (regardless of storage engine) has a maximum row size of 65,535 bytes. Storage engines may place additional constraints on this limit, reducing the effective maximum row size.
The maximum row size constrains the number (and possibly size) of columns because the total length of all columns cannot exceed this size. For example, utf8 characters require up to three bytes per character, so for a CHAR(255) CHARACTER SET utf8 column, the server must allocate 255 × 3 = 765 bytes per value. Consequently, a table cannot contain more than 65,535 / 765 = 85 such columns.
Storage for variable-length columns includes length bytes, which are assessed against the row size. For example, a VARCHAR(255) CHARACTER SET utf8 column takes two bytes to store the length of the value, so each value can take up to 767 bytes.
因此,定義單個(gè)VARCHAR(65535)列可以有效地將您限制為該行中的單個(gè)列(假設(shè)您已將其填滿)。
所有這些,除了對于某些類型的數(shù)據(jù)來說都是如此大的事實(shí)是完全錯(cuò)誤的-如果您的電話號碼列可能包含本地和國際號碼,則可以選擇使用VARCHAR字段來執(zhí)行此操作,但是將其設(shè)置為20以上可能毫無意義(我很慷慨)。
請參見Bill Karwin的答案,該答案還指出如果使用不必要的長VARCHAR字段生成臨時(shí)表可能會導(dǎo)致性能下降(與將此類字段轉(zhuǎn)換為CHAR并再次轉(zhuǎn)換-有關(guān)詳細(xì)信息,請參見該帖子)。
但是,除了VARCHAR(65535)列(稱為data1)之外,我的表確實(shí)還有其他列。 所有這些列都使用輸入的數(shù)據(jù)進(jìn)行填充,因?yàn)闆]有data1列實(shí)際上包含接近最大大小的字符串。
@tgoneil-嘗試在該列中插入65535個(gè)字符,并在其他列中插入數(shù)據(jù)。
我同意您的警告(假設(shè)您已填寫),并理解這一點(diǎn)。 就我而言,可能永遠(yuǎn)不會在該字段中插入大小為65535的實(shí)際字符串,因此從一開始就絕不是問題。 似乎限制VARCHAR大小的唯一真實(shí)原因是,如果嘗試超過預(yù)期的最大大小,則強(qiáng)制執(zhí)行錯(cuò)誤。
@tgoneil-這本身就是一個(gè)很好的理由。
請注意,TEXT和BLOB類型的列不計(jì)入此MySQL行大小限制(我以前曾以為VARCHAR也是如此,但我錯(cuò)了)
我認(rèn)為VARCHAR列長度不僅與存儲有關(guān)。它們也與數(shù)據(jù)語義有關(guān)。
即將name列指定為varchar(100)表示存儲在系統(tǒng)中的名稱不得超過100個(gè)字符。
在存儲方面,它們應(yīng)該是相同的。雖然,行大小估計(jì)在VARCHAR列上具有特定長度的情況下會更準(zhǔn)確,而在沒有行長度估計(jì)的情況下(不需要統(tǒng)計(jì)收集系統(tǒng)將數(shù)據(jù)分布保持在VARCHAR大小上)。
一種可能的原因是改善與其他應(yīng)用程序的兼容性。例如,如果您有一個(gè)使用" product_no"字段長度為100個(gè)字符的應(yīng)用程序,而您想與一個(gè)使用類似" model_no"字段類似長度為40個(gè)字符的應(yīng)用程序進(jìn)行交互,那將很痛苦。應(yīng)用程序中任何超過40個(gè)字符的product_nos都將被截?cái)?#xff0c;您必須找出某種方法在應(yīng)用程序之間進(jìn)行轉(zhuǎn)換。
例如,MySQL中的MEMORY引擎不能很好地支持VARCHAR-Fields。引擎將為每一行保留最大字節(jié)數(shù),而不是實(shí)際使用的長度。因此,如果您定義一個(gè)具有單個(gè)VARCHAR(1000)列的表,則添加的每一行的內(nèi)存使用量將為1000 * 3字節(jié),即使它們是空字符串也是如此。
原因之一是該字段的大小是對輸入數(shù)據(jù)的檢查。您是否真的要有人輸入1000個(gè)字符的電話號碼?字段太大是確保垃圾將輸入到數(shù)據(jù)庫中的一種方法。您的電話號碼上會顯示類似的內(nèi)容(例如,不是隨機(jī)產(chǎn)生的):
"只和前臺的大金發(fā)女郎說話"
而不是真實(shí)的電話號碼或電子郵件字段,其中包含有關(guān)客戶的注釋,因?yàn)樗麄儧]有注釋字段?當(dāng)您嘗試向其發(fā)送電子郵件時(shí),效果并不理想。
寬表可能會在數(shù)據(jù)庫中產(chǎn)生所有問題,因?yàn)槟赡軙龅揭馔獾挠涗浵拗?您可以將表設(shè)計(jì)為比實(shí)際存儲在一個(gè)記錄中更寬的表,有時(shí)這會導(dǎo)致插入意外失敗)和作為數(shù)據(jù)的性能問題跨數(shù)據(jù)頁分隔。我知道您可以從SQL Server的寬表中獲得該信息,如果mysql遇到類似問題,我也不會感到驚訝。 mysql專家將不得不真正解決這個(gè)問題。索引也可能是廣泛領(lǐng)域的問題。數(shù)據(jù)庫引擎可能不太傾向于認(rèn)為索引是有用的。同樣,我不確定mysql是否會出現(xiàn)此問題,但這值得研究。我知道這些是在SQL Server中使用所有字段的最大字段大小的問題,mysql可能有這些問題或其他SQL Server沒有的問題。
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的mysql为什么没有nvarchar,关于mysql:为什么不将每个VARCHAR指定为VARCHAR(65535)?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql list列表批量更新数据,M
- 下一篇: php中 可替代curl,laravel