На работе, в одной из таблиц в базе данных MS SQL, заметил, что поле используемое для хранения комментария имеет не совсем подходящий тип - NCHAR(250), вместо NVARCHAR(250). Напомню, что данные в полях типа CHAR и NCHAR всегда одной (фиксированной) длины - при сохранении переданный текст дополняется справа (в конце) пробелами до указанной длины поля.
Бывают ситуации, когда это удобно, но в данном случае я посчитал, что это было сделано по ошибке.
В итоге, после уточнения информации (не было ли в данном случае какого-то хитрого расчёта) изменил тип поля на NVARCHAR соответствующей длины и сделал усечение лишних пробелов с правой стороны для уже введённых данных. Пример запроса:
-
- IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS AS c
- WHERE c.TABLE_SCHEMA = 'dbo' AND c.TABLE_NAME = 'TableName' AND c.COLUMN_NAME = 'Comment' AND c.DATA_TYPE = 'nchar')
- BEGIN
- BEGIN
- ALTER TABLE [dbo].[TableName]
- ALTER COLUMN Comment NVARCHAR(250)
- END
-
- UPDATE [dbo].[TableName] SET
- Comment = RTRIM(Comment)
- WHERE Comment IS NOT NULL
- END
- GO
-- Замена NCHAR -> NVARCHAR
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS AS c
WHERE c.TABLE_SCHEMA = 'dbo' AND c.TABLE_NAME = 'TableName' AND c.COLUMN_NAME = 'Comment' AND c.DATA_TYPE = 'nchar')
BEGIN
BEGIN
ALTER TABLE [dbo].[TableName]
ALTER COLUMN Comment NVARCHAR(250)
END
UPDATE [dbo].[TableName] SET
Comment = RTRIM(Comment)
WHERE Comment IS NOT NULL
END
GO
Когда же наткнулся на такую же ситуацию в другой таблице решил подойти к вопросу более комплексно и по возможности устранить все такие дефекты. Для этого получил список всех таблиц, в которых есть поля указанного типа:
- SELECT * FROM INFORMATION_SCHEMA.COLUMNS AS c
- WHERE
-
-
-
- (c.DATA_TYPE = 'char' OR c.DATA_TYPE = 'nchar')
SELECT * FROM INFORMATION_SCHEMA.COLUMNS AS c
WHERE
-- при необходимости можно ограничить минимальную длину таких полей,
-- если есть места, где их использование уместно (обычно какие-то коды или артикулы)
--c.CHARACTER_MAXIMUM_LENGTH > 10 AND
(c.DATA_TYPE = 'char' OR c.DATA_TYPE = 'nchar')
Конечно же, можно было попробовать объединить эти два запроса так, чтобы в итоге автоматически формировался "корректировочный" запрос для каждого такого поля в каждой таблице (с учётом остальных параметров), но так как у нас их было не много, сделал всё вручную. Хотя, по правде сказать, не без "косячка" - в одной из таблиц исходное поле было с признаком NOT NULL и сначала при изменении типа поля я этот признак пропустил, но вовремя заметил ошибку и скорректировал запрос. Так что будьте внимательны.
Таким образом удалось немного сократить объём базы данных, так как перестали храниться ненужные пробелы в конце каждого комментария. И хотя в данном случае выигрыш вряд ли был значителен или хотя бы заметен, но в другой ситуации - при большем размере поля или довольно большом количестве строк/записей - это может быть не так. Тут сразу вспомнились таблицы в базе данных одного из прежних моих работодателей, где только использование оптимальных типов для хранения данных позволило сократить размер таблицы более чем в два раза (полностью сохранив исходные данные).