Как хранить короткие текстовые строки в базе данных SQL Server? - PullRequest
13 голосов
/ 10 сентября 2008

varchar (255), varchar (256), nvarchar (255), nvarchar (256), nvarchar (max) и т.д

256 выглядит как хорошее круглое число с эффективным использованием пространства. Но я видел, 255 использовал много. Почему?

В чем разница между varchar и nvarchar?

Ответы [ 8 ]

17 голосов
/ 15 сентября 2008

В MS SQL Server (7.0 и более поздних версиях) данные varchar внутренне представлены тремя значениями:

  • Фактическая строка символов, которая будет от 0 до более чем 8000 байтов (это зависит от размера страницы, других столбцов, сохраненных для строки, и нескольких других факторов)
  • Два байта используются для указания длины строки данных (которая дает значение от 0 до 8000 +)
  • Если столбец имеет значение NULL, один бит в нулевой битовой маске строки (поэтому нулевой статус до восьми NULL-столбцов может быть представлен одним байтом)

Важной частью является двухбайтовый индикатор длины данных. Если бы это был один байт, вы могли бы правильно записать только строки длиной от 0 до 255; с двумя байтами вы можете записать строки длиной от 0 до 64000+ (в частности, 2 ^ 16 -1). Тем не менее, длина страницы SQL Server составляет 8 КБ, отсюда и ограничение в 8000 символов. (В SQL 2005 есть переполнение данных, но если ваши строки будут такими длинными, вам нужно просто использовать varchar (max).)

Итак, независимо от того, как долго вы объявляете столбец типа данных varchar (15, 127, 511), на самом деле вы будете хранить для каждой строки:

  • 2 байта для указания длины строки
  • Фактическая строка, то есть количество символов в этой строке

Что подводит меня к моему мнению: многие старые системы использовали только 1 байт для хранения длины строки, и это ограничивало вас максимальной длиной 255 символов, что не так уж и долго. С 2 байтами у вас нет такого произвольного ограничения ... и поэтому я рекомендую выбрать число, которое имеет смысл (предположительно нетехнически ориентированному) пользователю. Мне нравятся 50, 100, 250, 500 и даже 1000. Учитывая, что база хранения объемом 8000+ байтов, 255 или 256 столь же эффективна, как 200 или 250, и меньше , когда дело доходит до объяснить вещи конечным пользователям.

Это относится к однобайтовым данным (т. Е. Ansii, SQL _ Latin1 * _ * General_CP1 и др.). Если вам нужно хранить данные для нескольких кодовых страниц или языков, используя разные алфавиты, вам нужно работать с типом данных nvarchar (который, я думаю, работает одинаково, два байта для числа символов, но для каждого действительного символа данных требуется два байты памяти). Если у вас есть строки, которые могут превышать 8000 или более 4000 в nvarchar, вам нужно будет использовать типы данных [n] varchar (max).

И если вы хотите знать, почему так важно занимать место с дополнительными байтами, просто чтобы отследить, насколько длинны данные, посмотрите http://www.joelonsoftware.com/articles/fog0000000319.html

Philip

11 голосов
/ 10 сентября 2008

VARCHAR (255). Он не будет использовать все 255 символов памяти, только то, что вам нужно. Это 255, а не 256, потому что тогда у вас есть место для 255 плюс нулевой терминатор (или размер байта).

«N» для Unicode. Используйте, если вы ожидаете символы не ASCII.

4 голосов
/ 11 сентября 2008

Есть несколько других моментов, которые следует учитывать при определении char / varchar и вариаций N.

Во-первых, есть некоторые накладные расходы на хранение строк переменной длины в базе данных. Хорошее общее правило - использовать CHAR для строк длиной менее 10 символов, поскольку N / VARCHAR хранит как строку, так и длину, а также разницу между хранением коротких строк в N / CHAR и N / VARCHAR до 10 не стоит накладных расходов на длину строки.

Во-вторых, таблица на сервере SQL хранится на страницах размером 8 КБ, поэтому максимальный размер строки данных составляет 8060 байтов (остальные 192 используются для служебных данных SQL). Вот почему SQL допускает максимальный определенный столбец VARCHAR (8000) и NVARCHAR (4000). Теперь вы можете использовать VARCHAR (MAX) и версию Unicode. Но с этим могут быть дополнительные накладные расходы.

Если я не ошибаюсь, SQL-сервер попытается сохранить данные на той же странице, что и остальная часть строки, но, если вы попытаетесь поместить слишком много данных в столбец VARCHAR (Max), он обработает его как двоичный файл и сохранить его на другой странице.

Другое большое различие между CHAR и VARCHAR связано с разбиением страниц. Учитывая, что SQL Server хранит данные на страницах размером 8 КБ, на странице может храниться любое количество строк данных. Если вы ОБНОВИТЕ столбец VARCHAR со значением, достаточно большим, чтобы строка больше не помещалась на странице, сервер разделит эту страницу, удалив некоторое количество записей. Если в базе данных нет доступных страниц, а база данных настроена на автоматическое увеличение, сервер сначала увеличит базу данных, чтобы выделить для нее пустые страницы, затем выделит пустые страницы для таблицы и, наконец, разделит одну страницу на две.

3 голосов
/ 10 сентября 2008

Поскольку в 1 байте имеется 8 битов и, таким образом, в 1 байте вы можете сохранить до 256 различных значений, что составляет

0 1 2 3 4 5 ... 255

Обратите внимание, что первое число равно 0, то есть всего 256 чисел.

Так что если вы используете nvarchar (255), он будет использовать 1 байт для хранения длины строки, но если вы опрокинетесь на 1 и используете nvarchar (256), то вы тратите впустую еще 1 байт просто для этого дополнительного 1 элемента из 255 (поскольку вам нужно 2 байта для хранения числа 256 ).

Возможно, это не реальная реализация SQL-сервера, но я считаю, что это типичная причина ограничения 255 на 256 элементов.

и nvarchar для Unicode, которые используют 2+ байта на символ и
varchar - для обычного текста ASCII, в котором используется только 1 байт

3 голосов
/ 10 сентября 2008

Если вы будете поддерживать языки, отличные от английского, вы можете использовать nvarchar.

HTML должен быть в порядке, если он содержит стандартные символы ASCII. Я использовал nvarchar в основном в базах данных с многоязычной поддержкой.

2 голосов
/ 15 сентября 2008

varchar (255) также был максимальной длиной в SQL Server 7.0 и более ранних версиях.

2 голосов
/ 10 сентября 2008

И varchar, и nvarchar автоматически изменяют размер содержимого, но число, которое вы определяете при объявлении типа столбца, является максимальным.

Значения в «nvarchar» занимают вдвое больше места на диске / в памяти, чем «varchar», потому что Юникод является двухбайтовым, но когда вы объявляете тип столбца, вы объявляете количество символов, а не байтов.

Таким образом, когда вы определяете тип столбца, вы должны определить максимальное количество символов, которое столбец когда-либо должен будет содержать, и иметь его как размер varchar (или nvarchar).

Хорошее практическое правило - определить максимальную длину строки, которую должен содержать столбец, а затем добавить поддержку примерно на 10% больше символов, чтобы избежать проблем с неожиданно длинными данными в будущем.

2 голосов
/ 10 сентября 2008

IIRC, 255 - это максимальный размер varchar в MySQL до того, как вам пришлось переключиться на текстовый тип данных, или когда-то это было (на самом деле, я думаю, что сейчас оно выше). Таким образом, сохранение этого значения до 255 может принести вам некоторую совместимость. Вы, возможно, захотите посмотреть на это, прежде чем действовать по нему.

varchar vs nvarchar - это что-то вроде ascii vs unicode. varchar ограничен одним байтом на символ, nvarchar может использовать два. Вот почему вы можете иметь varchar (8000), но только nvarchar (4000)

...