VARCHAR похож на 90-е?

  1. VARCHAR не хранит символы Юникода.
  2. NVARCHAR хранит символы Юникода.
  3. Современные приложения всегда должны быть совместимы с Unicode.
  4. NVARCHAR занимает в два раза больше места для его хранения.
  5. Пункт 4 не имеет значения, потому что место для хранения стоит очень недорого.

Ergo: при проектировании баз данных SQL Server сегодня всегда следует использовать NVARCHAR.

Это здравое рассуждение? Кто-нибудь не согласен с каким-либо из посылок? Есть ли какие-то причины выбрать VARCHAR вместо NVARCHAR сегодня?

Смотрите тоже это stackoverflow.com/q/35366/27535

gbn 08.09.2011 21:51

Это здравое рассуждение нет, в первую очередь из-за неверных предпосылок. Пункт 3 является слишком общим заявлением. Пункт 4 частично устарел, так как в SQL Server 2008 было введено сжатие PAGE и ROW, а в 2008 R2 добавлено (автоматическое / негласное) сжатие Unicode (но сжатие доступно только в Enterprise Edition). Пункт 5 до абсурда неверен. Подробности см. В моем ответе: stackoverflow.com/a/32871477/577765

Solomon Rutzky 30.09.2015 20:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
47
2
10 641
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Я не эксперт в этом вопросе. Но по какой причине вы не могли использовать UTF-8, чтобы получить комбинацию небольшого пространства и юникода?

Microsoft SQL Server (по крайней мере 2000 и 2005) не поддерживает хранение символьных данных в UTF-8.

Mike Henry 23.11.2008 09:05

В любом случае, не является ли UTF-8 просто ASCII?

Booji Boy 23.11.2008 09:20

Только для кодовых точек, попадающих в диапазон ASCII - в остальном все совсем иначе.

1800 INFORMATION 23.11.2008 09:21

Точнее, кодовые точки UTF-8 0–127 идентичны ASCII.

Powerlord 24.11.2008 08:50

База данных МОЖЕТ использовать UTF-8 как способ хранения Unicode. Я не понимаю, почему это может быть ударом по производительности (скажем, для поиска). Однако вопрос касается NVARCHAR ... что MS SQL вызывает строку Unicode UCS-2 (которая представляет собой фиксированные два байта на символ Unicode).

Dan H 29.08.2012 07:32

@MikeHenry: Что он делает с символами, у которых установлен старший бит байта? Одним из критериев проектирования для UTF-8 было то, что единственный способ, которым последовательность байтов, представляющая допустимую строку UTF-8, может появиться в байтах последовательности для другой строки, - это если вторая строка содержит первую.

supercat 13.12.2014 23:27

@BoojiBoy Нет, UTF-8, UCS-2 / UTF-16 и UTF-32 - это всего лишь 3 разных способа кодирования одного и того же спектра кодовых точек Unicode (более 1 миллиона адресуемых, в настоящее время отображено чуть более 120 тыс.). ASCII (собственно) - это просто значения 0–127, а расширенный ASCII (через кодовые страницы) содержит их плюс изменяющийся набор символов для значений 128–255.

Solomon Rutzky 30.09.2015 20:16

@DanH Некоторые базы данных могут использовать UTF-8, но SQL Server хранит все данные Unicode в UCS-2 / UTF-16. Это касается типов с префиксом XML и N. VARCHAR - это, в частности, 8-битный ASCII (но может работать с 3 разными двухбайтовыми наборами символов). Это отличается от Oracle, который имеет NVARCHAR как «Unicode-Только» и VARCHAR как имеющий возможность выполнять UTF-8.

Solomon Rutzky 30.09.2015 20:19

Я бы сказал, что все еще есть веские причины не использовать nvarchar.

  • Место для хранения ограничено, например, на общем хосте или в базе данных. В самом деле огромный.
  • Производительность имеет решающее значение.
  • Разработка Brownfield (т.е. в базе данных есть таблицы, использующие varchar).
  • Вы интегрируетесь с другой старой системой, которая понимает только однобайтовые символы и / или varchar.

Однако в новой разработке, вероятно, следует использовать nvarchar esp. поскольку 64-битные системы становятся нормой. Кроме того, компании (даже небольшие) теперь более глобальны.

Какое отношение имеет 64-битная версия к nvarchar?

Jeremy 10.05.2011 02:38

символы двойной ширины занимают вдвое больше памяти, но это не вызывает беспокойства в 64-битных системах, поскольку они могут адресовать гораздо больший объем оперативной памяти, чем 32-битные системы. 32-разрядный SQL Server в 32-разрядной Windows (все еще довольно распространенный в '08) мог использовать только 2 ГБ ОЗУ (без прыжков через обручи)

Booji Boy 10.05.2011 16:36

Хранение дешевле, чем когда-либо раньше, но все же, если вы можете хранить вдвое больше данных на одном жестком диске, это привлекательно, не правда ли?

Также есть оперативная память для кэширования и твердотельные накопители, которые намного дороже жестких дисков. Когда у вас миллионы строк, полезно использовать более компактные форматы данных.

Ваш пункт 3 недействителен. Системы, которые предназначены только для использования в одной стране, не должны беспокоиться о юникоде, а некоторые используемые языки / продукты не поддерживают юникод полностью или частично. Например, TurboTax предназначен только для США (и даже с канадской версией с французским остается только LATIN-1), поэтому им не нужно беспокоиться о Unicode и, вероятно, не поддерживать его (я не знаю, есть они или нет, но даже если они это сделают, это всего лишь пример).

«Современные приложения всегда должны быть совместимы с Unicode».

вероятно, более корректно выражается как:

«Современные приложения всегда должны быть совместимы с Unicode, если ничего особенного не требуется для правильной обработки Unicode, а ранее существующая кодовая база или любая другая часть приложения не нуждается в обновлении специально для ее поддержки»

Я думаю, что я всегда буду уделять больше внимания боли потенциального обновления до Unicode, чем боли, связанной с использованием слишком большого объема памяти.

Edward Tanguay 23.11.2008 09:29

@Edward, это было бы бизнес-решение, а не техническое. Наша компания (и она БОЛЬШАЯ) по-прежнему поставляет некоторые приложения, использующие базы данных только на английском языке, потому что это наш желаемый рынок.

paxdiablo 23.11.2008 10:28

Как член неанглоязычной страны (да, их довольно много), где язык содержит диакритические знаки, я могу сказать, что приложения должны быть совместимы с Unicode.

PiRX 23.11.2008 10:35

Я не понимаю, почему TurboTax должен быть только на английском языке, даже если бы это был только США ...

Neil Williams 23.11.2008 12:53

LATIN-1 также обрабатывает французский и испанский языки, поэтому Unicode в этом продукте очень мало используется. И PiRX, Unicode вполне может быть самым простым в использовании в вашей ситуации, но если бы для ваших распространенных языков было что-то вроде LATIN-1, то Unicode также не потребовался бы.

MetroidFan2002 24.11.2008 04:22

Это кажется ошибочным предположением. Что произойдет, если ваше приложение, предназначенное только для США, должно хранить имя гражданина США, родившегося в другой стране, с не-ASCII символом в его имени? Глупо предполагать, что только потому, что приложение используется только в США или, может быть, в Канаде, юникод не понадобится.

jalf 23.01.2009 06:05

Тогда очевидно, что этот символ не будет введен. Чтобы перевернуть ваше утверждение, глупо предполагать, что только потому, что могут быть нечастые выбросы, существующие продукты и приложения следует разрабатывать так, чтобы учитывать крайности, а не вероятности. В данном случае это ЯГНИ.

MetroidFan2002 29.01.2009 00:28

Зачем мне добавлять поддержку Unicode в приложение, используемое двумя людьми в моем офисе? 50 часов работы, 0 льгот. Не все делают коробочные программы.

Jeff Davis 12.05.2010 17:53

Point 4 doesn't matter because storage space is extremely inexpensive.

это не просто хранилище, а пропускная способность - процессор, память, резервное копирование, восстановление, передача. Сохранить.

Ссылки на это в моем ответе здесь: stackoverflow.com/questions/35366/…

gbn 08.09.2011 21:52

Хранение как «NVARCHAR» в базе данных не означает, что данные отправляются «по сети» в кодировке Unicode UCS-2. Он может передаваться по сети и быть представлен в памяти приложения как UTF-8 ..., который «большую часть времени является одним байтом на символ».

Dan H 29.08.2012 07:15
Ответ принят как подходящий

Вы сопоставляете тип данных с данными, которые будут храниться в столбце. С помощью аналогичного аргумента вы могли бы сказать, почему бы не хранить все данные в столбцах NVARCHAR, потому что числа и даты могут быть представлены как строки цифр.

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

Есть ли способ для вашего сервера базы данных использовать UTF-8 в качестве кодировки? Затем вы получаете преимущества небольшого объема памяти для загрузки в основном ASCII и возможность хранить что-либо в диапазоне Unicode, так что расширение возможно.

Я бы попросил вашего поставщика базы данных поддержать UTF-8 в качестве кодировки для типа SQL VARCHAR. Я не знаю, как это делают другие серверы БД, но я знаю, что вы можете использовать UTF-8 в полях VARCHAR и TEXT, по крайней мере, в MySQL и PostgreSQL.

Все, что было сказано, единственная причина, по которой нет использует поле в кодировке UTF-16, - это если вам нужно взаимодействовать с приложениями, которые не работают при вводе UTF-16. Это будет большинство устаревших приложений, которые были разработаны для обработки текстовых кодировок ASCII или ISO-8815, которые лучше обрабатывали бы UTF-8.

MS SQL Server не поддерживает UTF8. Он использует UCS-2, который примерно эквивалентен UTF-16 для символов в базовой многоязычной плоскости (BMP). Я не знаю, существует ли хак, чтобы заставить его поддерживать UTF-8, но я сомневаюсь в этом.

Triynko 26.04.2011 00:10

В этом случае, вероятно, лучше всего было бы обернуть доступ к базе данных с помощью конвертера набора символов, чтобы он возвращал значения UTF-8 в приложение и отправлял значения UTF-16 в базу данных. По крайней мере, так бы я поступил, если бы работал с системой, в которой мне самому приходилось беспокоиться о кодировке символов. Если вам не нужно беспокоиться о кодировке символов (например, Python 3 или что-то, что заботится о нем прозрачно), тогда, я полагаю, это не имеет особого значения ...

Michael Trausch 24.05.2011 18:57

Как отмечали другие, дело не только в стоимости хранения.

Длина столбца влияет на количество строк на странице. Меньшее количество строк на странице означает, что меньшее количество может поместиться в ваши кеши, что снижает производительность. Я предполагаю, что в MSSQL индексируемый столбец NVARCHAR будет занимать больше места в индексе. Это означает меньшее количество записей индекса на блок, следовательно, больше блоков в индексе, следовательно, больше запросов при сканировании (или поиске) индексов, что также замедляет индексированный доступ.

Таким образом, вы теряете производительность по всем направлениям. Если вам действительно все равно (или вы можете измерить производительность и, конечно, довольны), то это нормально. Но если у вас есть настоящая потребность в хранении символов Юникода, конечно, используйте NVARCHAR.

Я могу сказать, что удобство обслуживания, достигаемое за счет использования NVARCHAR во всей базе данных, перевешивает любые затраты на производительность.

Я считаю, что сравнение nvarchars дороже, чем varchars, поэтому оно вполне допустимо и даже предпочтительнее в тех местах, где вам действительно не нужны возможности Unicode, то есть для некоторых внутренних идентификаторов.

А стоимость памяти еще имеет значение. Если у вас есть миллиарды строк, эти «маленькие» различия довольно быстро становятся большими.

На такие вопросы всегда есть один и тот же ответ: По-разному. Не существует магического правила, которому следует слепо следовать. Даже использование GOTO в современных языках программирования может быть оправдано: Выгодно ли когда-нибудь использовать goto на языке, поддерживающем циклы и функции? Если да, то почему?

Итак, ответ: используйте свою голову и подумайте о конкретной ситуации. В этом конкретном случае имейте в виду, что вы всегда можете преобразовать из varchar в nvarchar в базе данных, если окажется, что ваши требования изменились.

Я видел столбцы nvarchar, преобразованные в varchar, по двум причинам:

  1. Приложение использует MSSQL выражать Версия с размером базы данных 4 ГБ предел. Переход на стандарт MSSQL Издание было бы слишком дорого, если бы есть много развертываний баз данных, как в однопользовательских веб-приложениях или приложения со встроенной СУБД. Более дешевая версия SQL2008 Web Edition мог бы здесь помочь.

  2. nvarchar (4000) недостаточно но ты не нужен столбец ntext. Так что вы преобразовать в varchar (8000). Тем не мение, в большинстве случаев вам, вероятно, следует преобразовать в nvarchar (max).

Вы должны выбрать VARCHAR вместо NVARCHAR для многих различных типов столбцов, и выбор будет для каждого столбца.

Типичные столбцы, которые не потребуют дополнительных накладных расходов, связанных с NVARCHAR, будут:

Столбцы ID-типа: номерные знаки, SSN, идентификаторы карты пациента и т. д.

Столбцы кодов: коды международных валют (USD, UKP и т. д.), Коды стран ISO (США, Великобритания и т. д.), Коды языков (en-us и т. д.), Коды сегментов учета и т. д.

Почтовый индекс и столбцы почтового индекса.

Я видел базу данных, в которой индексы (индексы? ... разные дискуссии) были больше данных. Если можно обойтись с половиной требований к хранилищу (varchar) в индексе, то предполагается, что это равняется удвоенной плотности совпадений данной страницы и более эффективному факторингу заполнения, ведущему к более быстрому извлечению / записи / блокировке данных и меньшим требованиям к хранилищу ( уже упоминалось).

Я склоняюсь к тому, чтобы "использовать NVARCHAR" по умолчанию ... но @CadeRoux имеет хороший аргумент: если вы УВЕРЕНЫ, что данные никогда не будут содержать ничего, кроме ASCII - например, номерной знак США - VARCHAR может сэкономить вам немного Стоимость.

Я бы сказал, что оборотной стороной его удачно поставленного заявления является «ИСПОЛЬЗУЙТЕ NVARCHAR» для всего, что будет иметь имена (люди, улицы, места) или текст на естественном языке (электронная почта, чат, статьи, сообщения в блогах, подписи к фотографиям). В противном случае столбец «имя» не сможет правильно кодировать «Франсуа» или «Хосе», а в текстовых столбцах не будет текста с «иностранными» диакритическими знаками или, если на то пошло, очень распространенными американскими символами, такими как центрирующий знак «¢», знак абзаца «¶», маркер «•». (Потому что ни один из них не является Символы ASCII, и нет хорошего стандартного способа поместить их в поле VARCHAR. Поверьте мне: вы навредите себе.)

В ЛЮБОМ проекте, над которым я работал, меня НИКОГДА не ругали за использование NVARCHAR, потому что я «тратил слишком много денег компании на дисковое пространство». И если бы мне пришлось переделывать код или схему БД (особенно в действующей производственной системе), затраты, потраченные на повторную установку, ЛЕГКО перевесили бы «экономию» от покупки диска, который был на 50% меньше.

Чтобы действительно понять этот вопрос, вам действительно нужно понимать типичные кодировки ASCII, Unicode и Unicode (например, UCS-2 и UTF-8).

NVARCHAR (12) занимает 24 байта и может содержать любые 12 символов в BMP или любые 6 символов за его пределами. 8-битный прозрачный VARCHAR (24), используемый с подходящими методами доступа, может содержать 24 символа ASCII, любые 12 символов в самой нижней части BMP, любые 8 в BMP или любые 6 вне BMP; в качестве альтернативы он может использоваться для хранения любой комбинации из 8 символов с использованием кодировки, которая хранит 3 байта на символ, например с MSB, установленным в первом байте каждого набора триплетов и очищенным в двух других.

supercat 13.12.2014 23:32

Другие вопросы по теме