Я работаю над базой данных для небольшого веб-приложения в моей школе, используя SQL Server 2005
.
Я вижу несколько школ мысли по вопросу varchar
против nvarchar
:
- Используйте,
varchar
если вы не имеете дело с большим количеством интернационализированных данных, затем используйтеnvarchar
. - Просто используйте
nvarchar
для всего.
Я начинаю видеть достоинства представления 2. Я знаю, что nvarchar занимает вдвое больше места, но это не обязательно огромная сделка, поскольку она будет хранить данные только для нескольких сотен студентов. Мне кажется, что было бы проще не беспокоиться об этом и просто позволить всему использовать nvarchar. Или мне чего-то не хватает?
sql-server
sql-server-2005
storage
varchar
nvarchar
Джейсон Бейкер
источник
источник
NVARCHAR
» ненужно и расточительно , и это может оказать очень негативное влияние на производительность и затраты / бюджет на оборудование. Несколько рядов, даже несколько тысяч, не будут иметь значения. Но системы растут быстрее, чем ожидают люди, поэтому принятый в настоящее время ответ является плохой услугой для сообщества. Спасибо.Ответы:
Всегда используйте nvarchar.
Возможно, вам никогда не понадобятся двухбайтовые символы для большинства приложений. Однако, если вам требуется поддержка двухбайтовых языков и у вас есть только однобайтовая поддержка в схеме базы данных, очень дорого вернуться и модифицировать свое приложение.
Стоимость переноса одного приложения с varchar на nvarchar будет намного больше, чем немного дополнительного дискового пространства, которое вы будете использовать в большинстве приложений.
источник
Дисковое пространство не проблема ... но память и производительность будут. Двойное чтение страниц, двойной размер индекса, странное LIKE и = постоянное поведение и т. Д.
Вам нужно хранить китайский сценарий и т. Д.? Да или нет...
И от MS BOL " Хранение и производительность Unicode "
Редактировать :
Недавний вопрос о том, насколько плохой может быть производительность nvarchar ...
SQL Server использует высокий процессор при поиске внутри строк nvarchar
источник
Быть последовательным! Присоединение VARCHAR к NVARCHAR имеет большой успех.
источник
nvarchar
кvarchar
против преобразованияnvarchar
кvarchar
и присоединению кvarchar
. Если, конечно, вы не имели в виду согласованность типов данных столбцов, а не присоединение.VARCHAR
иNVARCHAR
, что должно быть связанно с индексациейVARCHAR
колонны вместе с типом сортировки , используемой для этого столбца (а следовательно , и индекса). Я подробно рассмотрю эту тему в следующем сообщении в блоге: Влияние на индексы при смешивании типов VARCHAR и NVARCHAR .У nvarchar будут значительные накладные расходы на память, хранилище, рабочий набор и индексацию, поэтому, если спецификации требуют, что это действительно никогда не понадобится, не беспокойтесь.
У меня не было бы жесткого и быстрого правила «всегда nvarchar», потому что оно может быть полной тратой во многих ситуациях - особенно ETL из ASCII / EBCDIC или идентификаторы и столбцы кода, которые часто являются ключами и внешними ключами.
С другой стороны, есть много случаев столбцов, где я обязательно задал бы этот вопрос рано, и если бы я не получил точный и быстрый ответ сразу, я бы сделал столбец nvarchar.
источник
Я не решаюсь добавить еще один ответ, поскольку их уже немало, но необходимо сделать несколько замечаний, которые либо не были сделаны, либо не были четко сформулированы.
Во- первых: Do не всегда использовать
NVARCHAR
. Это очень опасный и часто дорогостоящий подход / подход. И не лучше сказать « Никогда не используйте курсоры», так как они иногда являются наиболее эффективным средством решения конкретной проблемы, и общий обходнойWHILE
цикл выполнения цикла почти всегда будет медленнее, чем правильно сделанный Курсор.Единственный раз, когда вы должны использовать термин «всегда», это когда вы советуете «всегда делать то, что лучше для ситуации». Конечно, это часто трудно определить, особенно когда мы пытаемся сбалансировать краткосрочные выгоды во времени разработки (менеджер: «нам нужна эта функция, о которой вы не знали до сих пор - неделю назад!») С давно расходы на техническое обслуживание (менеджер, который первоначально заставил команду завершить трехмесячный проект в трехнедельном спринте: «почему у нас возникают такие проблемы с производительностью? как мы могли бы сделать X без гибкости? один-два спринта, чтобы это исправить. Что мы можем сделать за неделю, чтобы вернуться к приоритетным задачам? И нам определенно нужно больше времени уделять дизайну, чтобы этого не происходило! »).
Второе: ответ @ gbn затрагивает некоторые очень важные моменты, которые следует учитывать при принятии определенных решений по моделированию данных, когда путь не ясен на 100%. Но есть еще что рассмотреть:
Потеря пространства имеет огромный каскадный эффект на всю систему. Я написал статью, подробно описав эту тему: « Диск дешев! ORLY? (требуется бесплатная регистрация; извините, я не контролирую эту политику).
Третье: хотя некоторые ответы неправильно фокусируются на аспекте «это маленькое приложение», а некоторые правильно предлагают «использовать то, что уместно», ни один из ответов не дал реального руководства ОП. Важная деталь, упомянутая в Вопросе является то, что это веб-страница для их школы. Большой! Таким образом, мы можем предположить, что:
NVARCHAR
поскольку со временем становится все более вероятным, что имена из других культур будут появляться в этих местах.VARCHAR
с соответствующей кодовой страницей (которая определяется из сопоставления поля).INT
/,TINYINT
поскольку коды ISO имеют фиксированную длину, удобочитаемы и, как правило, стандартны :), используйтеCHAR(2)
двухбуквенные коды иCHAR(3)
3-буквенные коды. И рассмотрите возможность использования бинарной сортировки, такой какLatin1_General_100_BIN2
.VARCHAR
поскольку это международный стандарт, никогда не используйте никакие буквы за пределами AZ. И да, по-прежнему используйте,VARCHAR
даже если хранятся только почтовые индексы США, а не INT, поскольку почтовые индексы не являются числами, они являются строками, и некоторые из них имеют начальный «0». И рассмотрите возможность использования бинарной сортировки, такой какLatin1_General_100_BIN2
.NVARCHAR
поскольку теперь они могут содержать символы Юникода.Четвертое: теперь, когда у вас есть
NVARCHAR
данные, занимающие вдвое больше места, чем нужно для данных, которые хорошо вписываютсяVARCHAR
(«хорошо вписывается» = не превращаются в «?») И каким-то образом, как по волшебству, приложение росло и теперь есть миллионы записей, по крайней мере, в одном из этих полей, где большинство строк являются стандартными ASCII, но некоторые содержат символы Юникода, поэтому вам следует сохранитьNVARCHAR
следующее:Если вы используете SQL Server 2008 - 2016 RTM и используете Enterprise Edition, или, если используете SQL Server 2016 с пакетом обновления 1 (который сделал сжатие данных доступным во всех выпусках) или новее, вы можете включить сжатие данных . Сжатие данных может (но не будет «всегда») сжатие данные Unicode в
NCHAR
иNVARCHAR
поле. Определяющими факторами являются:NCHAR(1 - 4000)
иNVARCHAR(1 - 4000)
использовать стандартную схему сжатия для Unicode , но только начиная с SQL Server 2008 R2, и только для данных IN ROW, а не OVERFLOW! Это выглядит лучше, чем обычный алгоритм сжатия ROW / PAGE.NVARCHAR(MAX)
иXML
(и я думаю, такжеVARBINARY(MAX)
,TEXT
иNTEXT
) данные, которые находятся в строке (не в строке на страницах LOB или OVERFLOW), по крайней мере, могут быть сжаты на PAGE, но не сжаты на ROW. Конечно, сжатие PAGE зависит от размера значения в строке: я проверил с помощью VARCHAR (MAX) и увидел, что 6000 строк символов / байтов не будут сжиматься, но 4000 строк символов / байтов сделали.Если вы используете SQL Server 2005 или RTM 2008 - 2016, а не Enterprise Edition, у вас может быть два поля: одно
VARCHAR
и одноNVARCHAR
. Например, предположим, что вы храните URL-адреса, которые в основном все являются базовыми символами ASCII (значения 0–127) и, следовательно, вписываютсяVARCHAR
, но иногда содержат символы Unicode. Ваша схема может включать следующие 3 поля:В этой модели вы только выбираете из
[URL]
вычисляемого столбца. Для вставки и обновления вы определяете, какое поле использовать, видя, изменяет ли преобразование входящее значение, которое должно иметьNVARCHAR
тип:Вы можете GZIP входящие значения в,
VARBINARY(MAX)
а затем распаковать на выходе:COMPRESS
иDECOMPRESS
функции, которые также являются GZip.Если вы используете SQL Server 2017 или новее, вы можете сделать таблицу Clustered Columnstore Index.
Хотя этот вариант пока не подходит, в SQL Server 2019 появилась встроенная поддержка UTF-8 в
VARCHAR
/CHAR
datatypes. В настоящее время в нем слишком много ошибок, чтобы его можно было использовать, но если они исправлены, то это вариант для некоторых сценариев. Пожалуйста, ознакомьтесь с моим постом « Поддержка UTF-8 в SQL Server 2019: Спаситель или Лжепророк? », Где подробно рассматривается новая функция.источник
Для вашего приложения подходит nvarchar, потому что размер базы данных невелик. Сказать «всегда используйте nvarchar» - это чрезмерное упрощение. Если вам не нужно хранить такие вещи, как кандзи или другие сумасшедшие персонажи, используйте VARCHAR, это займет гораздо меньше места. Мой предшественник на моей нынешней работе разработал что-то, используя NVARCHAR, когда это было не нужно. Недавно мы переключили его на VARCHAR и сэкономили 15 ГБ только на этой таблице (это было очень записано). Кроме того, если у вас есть индекс для этой таблицы, и вы хотите включить этот столбец или создать составной индекс, вы просто увеличили размер файла индекса.
Просто будьте внимательны в своем решении; в разработке SQL и определениях данных, похоже, редко встречается «ответ по умолчанию» (конечно, кроме обхода курсоров любой ценой).
источник
Поскольку ваше приложение небольшого размера, использование nvarchar по сравнению с varchar существенно не увеличится, и вы избавите себя от возможных головных болей в будущем, если у вас возникнет необходимость в хранении данных Unicode.
источник
Вообще говоря; Начните с самого дорогого типа данных, который имеет наименьшие ограничения. Поместите это в производство . Если производительность начинает вызывать проблемы, выясните, что на самом деле хранится в этих
nvarchar
столбцах. Есть ли там персонажи, которые не подходятvarchar
? Если нет, переключитесь на varchar. Не пытайтесь предварительно оптимизировать, пока не узнаете, где боль. Я предполагаю, что выбор между nvarchar / varchar - это не то, что замедлит ваше приложение в обозримом будущем. Будут и другие части приложения, где настройка производительности даст вам гораздо больше прибыли .источник
За последние несколько лет все наши проекты использовали NVARCHAR для всего, так как все эти проекты многоязычны. Импортированные данные из внешних источников (например, файл ASCII и т. Д.) Преобразуются в Unicode перед вставкой в базу данных.
Мне еще не приходилось сталкиваться с проблемами, связанными с производительностью больших индексов и т. Д. Индексы используют больше памяти, но память дешевая.
Независимо от того, используете ли вы хранимые процедуры или создаете SQL на лету, убедитесь, что все строковые константы имеют префикс N (например, SET @foo = N'Hello world. ';), Поэтому константа также является Unicode. Это исключает любое преобразование строкового типа во время выполнения.
YMMV.
источник
Я могу говорить по своему опыту, остерегайтесь
nvarchar
. Если это абсолютно не требуется, этот тип поля данных снижает производительность в большой базе данных. Я унаследовал базу данных, которая вредит производительности и пространству. Мы смогли уменьшить размер базы данных 30 ГБ на 70%! Были сделаны некоторые другие модификации, чтобы помочь с производительностью, но я уверен, что ониvarchar
значительно помогли с этим. Если ваша база данных имеет потенциал для увеличения таблиц до миллиона записей, держитесь подальшеnvarchar
любой ценой.источник
Я часто занимаюсь этим вопросом на работе:
FTP-фиды инвентаря и цены - описания предметов и другой текст были в nvarchar, когда varchar работал нормально. Преобразование их в varchar уменьшило размер файла почти вдвое и действительно помогло с загрузкой.
Вышеописанный сценарий работал нормально, пока кто-то не вставил специальный символ в описание предмета (возможно, товарный знак, не помню)
Я до сих пор не использую nvarchar каждый раз над varchar. Если есть какие-либо сомнения или потенциал для специальных символов, я использую nvarchar. Я нахожу, что я использую varchar в основном, когда я на 100% контролирую то, что заполняет поле.
источник
Почему во всей этой дискуссии не упоминалось о UTF-8? Возможность хранить полный диапазон символов Юникода не означает, что нужно всегда выделять два байта на символ (или «кодовую точку», чтобы использовать термин UNICODE). Все ASCII - это UTF-8. Проверяет ли SQL Server для полей VARCHAR (), что текст является строгим ASCII (т. Е. Бит нулевого старшего байта)? Я надеюсь, что нет.
Если затем вы хотите хранить Unicode и хотите совместимости со старыми приложениями, поддерживающими только ASCII, я думаю, что использование VARCHAR () и UTF-8 было бы волшебной палочкой: он использует больше места только тогда, когда это необходимо.
Для тех из вас, кто не знаком с UTF-8, могу я порекомендовать учебник для начинающих .
источник
N
есть типов XML и префиксов). У вас нет выбора использования UTF-8. Кроме того, кодировки Unicode (UTF-8, UCS-2 / UTF-16 и UTF-32) не могут быть применены к полям VARCHAR.Будут исключительные случаи, когда вы захотите сознательно ограничить тип данных, чтобы убедиться, что он не содержит символов из определенного набора. Например, у меня был сценарий, когда мне нужно было сохранить доменное имя в базе данных. Интернационализация доменных имен не была надежной в то время, поэтому было лучше ограничить ввод на базовом уровне и помочь избежать возможных проблем.
источник
Если вы используете
NVARCHAR
только потому, что этого требует системная хранимая процедура, наиболее часто встречающееся явление необъяснимоsp_executesql
, а ваш динамический SQL очень длинный, вам лучше с точки зрения производительности выполнять все строковые манипуляции (конкатенация, замена и т. Д.) ПриVARCHAR
последующем преобразовании конечный результатNVARCHAR
и ввод его в параметр proc. Так что нет, не всегда пользуюсьNVARCHAR
!источник