как nvarchar (max) будет хранить данные в базе данных, будет ли это быстро, если некоторые данные меньше 4000 символов?

8

Я должен разработать CMS, которая будет поддерживать два языка английский, арабский. Эта CMS будет своего рода сайтом публикации статей. При разработке и анализе я обнаружил, что некоторые статьи имеют длину более 8000 символов. В моей таблице есть столбец

PageID int,
PageTitleEnglish nvarchar(200),
PageTitleArabic nvarchar(200),
PageDescEnglish nvarchar(500),
PageDescArabic nvarchar(500),
PageBodyEnglish nvarchar(max)
PageBodyArabic nvarchar(max)

Если я сохраню PageBody как nvarchar (4000), то я ограничусь 4000 символами, и если мне придется хранить арабскую версию, тогда мне понадобится 16000 байт (поскольку арабский - это Unicode и занимает в 3 раза больше места, чем ASCII).

Так что я остался только с возможностью определения PageBody как nVarchar (max) , это будет иметь обратную сторону с точки зрения производительности. Мой реальный вопрос: если некоторые данные в столбце PageBody меньше 4000 символов, будут ли они храниться в MS SQL, чем данные во встроенном столбце или отдельно в базе данных.

Я также искал это в Google, но не нашел никакого соответствующего ответа и как я могу улучшить производительность в таком сценарии.

Любые предложения для наилучшей практики для такой конструкции многоязычной CMS приветствуются.

Мне нужно поддерживать только два языка арабский и английский

Обучение
источник
У вас всегда будет английский и арабский? Или, может быть, только один дополнительный? Если так, то всегда ли будет обязательным? Вы ожидаете больше языков позже?
ГБН

Ответы:

9

nvarchar(max)Значение будет сохранено « в построчно » , если она достаточно коротким.

Поведение по умолчанию может быть изменено с помощью sp_tableoption , опции «большие значения вне строки». Я бы не стал беспокоиться. Механизм БД справится с этим самостоятельно.

Что касается дизайна, есть несколько способов сделать это на основе вашей модели:

  • У вас всегда будет английский и арабский?
  • Можно ли по желанию? Если так, то всегда ли будет обязательным?
  • Вы ожидаете больше языков позже?

1. Отдельные таблицы

То есть вы можете разделить отдельные языки на разные таблицы.
Это позволяет сопоставления на уровне таблицы, а не на уровне столбца

Это позволяет больше строк на страницу и больше шансов на хранение LOB в строке

PageParent

  • PageID int,
  • PageOtherInfo ...

PageEnglish (заметьте, что с varchar здесь все в порядке)

  • PageID int,
  • PageTitleEnglish varchar (200),
  • PageDescEnglish varchar (500),
  • PageBodyEnglish varchar (max)

PageArabic

  • PageID int,
  • PageTitleArabic nvarchar (200),
  • PageDescArabic nvarchar (500),
  • PageBodyArabic nvarchar (max)

2. Отдельные ряды

Или иметь столбец languageID для поддержки нескольких языков.
Это имеет тот недостаток, что сортировка будет исправлена ​​для всех языков, что означает плохую сортировку / фильтрацию

PageParent

  • PageID int,
  • PageOtherInfo ..

страница

  • PageID int,
  • LanguageCode,
  • PageTitle nvarchar (200),
  • PageDesc nvarchar (500),
  • PageBody nvarchar (max)
ГБН
источник
4
  • MS SQL Server имеет фиксированный размер страницы 8 КБ.
  • Строка никогда не разделяется на несколько страниц, но несколько строк могут совместно использовать одну страницу.
  • Однако nvarchar (max) и другие BLOB-данные могут храниться вне строки / страницы.

Это означает, что для того, чтобы все поместилось в один ряд, сумма всех размеров должна быть меньше 8К. Если этого не произойдет, SQL Server будет хранить большие двоичные объекты вне строки / страницы.

Являются ли объемы данных настолько большими, что это действительно вызывает проблемы с производительностью?

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

Арджан Эйнбу
источник