powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
25 сообщений из 65, страница 2 из 3
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486209
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovNickDeeЭто делает firebird, чтобы проверить не превышает ли юникод-строка
ограничение в N юникодных символов.
Нет, Firebird ничего подобного не делает.
Т.е. проверяет по количеству байт, т.е. тот же N*4?
Он либо проверяет по количеству символов, либо по количеству байт.

Эксперимент. Подключаюсь к базе с win1251.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE TABLE T (
    U10  VARCHAR(10) CHARACTER SET UTF8 COLLATE UTF8
);

insert into T (U10) values ('1234567890'); -- ok (10 символов, 10 байт в utf8)
insert into T (U10) values ('12345678901'); -- failed (11 символов, 11 байт в utf8)
-------------
Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
-------------

insert into T (U10) values ('АБВГДЕЁЖЗИ'); -- ok (10 символов, 20 байт в utf8)
insert into T (U10) values ('АБВГДЕЁЖЗИЙ'); -- failed (11 символов, 22 байта в utf8)
-------------
Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
-------------


Т.е. сервер не ругнулся на 20 байт, но ругнулся на 11.
Он может так ругнуться только если считает не байты, а символы (т.е. парсит utf8-строку).
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486220
IBExpert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeОн может так ругнуться только если считает не байты, а символы (т.е. парсит utf8-строку).

В данном случае ты ему подсовываешь 11 символов win1251, чтобы он упихал их в VARCHAR(10). Ему даже парсить и конвертировать ничего не надо для того, чтобы дать тебе отлуп.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486255
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IBExpertNickDeeОн может так ругнуться только если считает не байты, а символы (т.е. парсит utf8-строку).

В данном случае ты ему подсовываешь 11 символов win1251, чтобы он упихал их в VARCHAR(10). Ему даже парсить и конвертировать ничего не надо для того, чтобы дать тебе отлуп.
Возможно. Но когда я подключаюсь через UTF8 в IBExpert, то:
1. При галке "Do NOT perform conversion from to UTF8" я получаю:
-----------------
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Malformed string.
-----------------
даже при
Код: sql
1.
insert into T (U10) values ('АБВГДЕЁЖЗИ');



2. Без галки "Do NOT perform conversion from to UTF8" я при
Код: sql
1.
insert into T (U10) values ('АБВГДЕЁЖЗИ');

получаю вставленную запись, и она нормально отображается в гриде.
А при
Код: sql
1.
insert into T (U10) values ('АБВГДЕЁЖЗИЙ');

я получаю:
-------------
Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
-------------

Т.е. сервер таки честно считает количество UTF8 символов.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486260
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeТ.е. сервер таки честно считает количество UTF8 символов.
Пардон - не символов, а unicode code points :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486285
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeВопрос - что делать? Ни один из этих вариантов не кажется конструктивным :)выбирать из нескольких зол меньшую. почему куча текстовых блобов не нравится? или чрезмерно длинные строковые поля?
можешь еще в какой-нить sqlite податься - там у тебя будет для хранения строк один-единый тип TEXT и все, никакой длины. никакой информации о хранении данных, впрочем, тоже))
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486294
IBExpert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDee,

1. VARCHAR(10) CHARACTER SET UTF8 - это 10 символов UTF8 . А не каких-то других символов.
Символ UTF8 - это последовательность от 1 до 4-х байт (теоретически - до 6).

2. Когда ты подсовываешь серверу строку win1251, он знает, что в этой кодировке каждый символ представлен одним байтом. Соответственно, достаточно сравнить длину подсунутой строки с декларированной длиной поля, чтобы дать тебе отлуп или обрабатывать строку дальше.

3. Когда ты подсовываешь серверу некую последовательность байт и намекаешь, что это последовательность символов UTF8, он, разумеется, проверяет, так ли это на самом деле. У символов UTF8 жесткая структура, которая легко валидируется. На этом этапе и длина строки в символах UTF8 легко вычисляется.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486311
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IBExpertУ символов UTF8 жесткая структура, которая легко валидируется. На этом этапе и длина строки в символах UTF8 легко вычисляется.Дак я про это же и говорю - вычисляется разбором строки.

IBExpertСимвол UTF8 - это последовательность от 1 до 4-х байт (теоретически - до 6). В firebird в системных таблицах это 4 байта. И по стандарту тоже 4.
Википедия своими таблицами на 6 байт конечно вводит в заблуждение.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486319
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeСоздавать все поля как VARCHAR(8000)? Это не вариант, т.к. у меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255) - тормоза существенные. Создавать стринговые поля как блобы? Это тем более не вариантУ тебя сортировки по этим гамаль-абдель-ибн-хаттаб-аль-трампампам - предполагаются ?
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486356
IBExpert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeВ firebird в системных таблицах это 4 байта. И по стандарту тоже 4.

Это максимум. Твои '1234567890' физически будут лежать именно так, занимая ровно 10 байт, а не 40.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486370
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидNickDeeСоздавать все поля как VARCHAR(8000)? Это не вариант, т.к. у меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255) - тормоза существенные. Создавать стринговые поля как блобы? Это тем более не вариантУ тебя сортировки по этим гамаль-абдель-ибн-хаттаб-аль-трампампам - предполагаются ?
Сортировки скорей всего будут. Но это не мне решать :)
Можно сделать чтобы сервер сортировал, можно сделать чтобы грид сортировал. Это настраиваемо. Но по-умолчанию - сервер.
Предполагаю что сервер лучше знает правильную сортировку для UTF8, и лучше это поручить ему. Возможно заблуждаюсь :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486375
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IBExpertNickDeeВ firebird в системных таблицах это 4 байта. И по стандарту тоже 4.

Это максимум. Твои '1234567890' физически будут лежать именно так, занимая ровно 10 байт, а не 40.
Да я знаю что это максимум. И что ansi-символ в utf8 занимает 1 байт, а кириллический - 2.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486395
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeПредполагаю что сервер лучше знает правильную сортировку для UTF8, и лучше это поручить ему.Не забудь учесть, что на производительность сортировки влияет именно объявленная длина поля, а не фактическое число символов, которое в нём хранится. Кроме того, в undo-лог записи попадают также с паддингом варчаров до объявленной длины ( Тынц ).
Так что если твоя апликуха даёт клиенту возможность завести поле для хранения "запиши то - сам пока не знаю что", то это явная ошибка.
А для ФИО, мну кажется, достаточно 125 символов ==> это будет varchar(500).
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486448
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDee Википедия своими таблицами на 6 байт конечно вводит в заблуждение.та же вики говорит, что в utf8 суррогатных пар нет. это логично, ведь в utf8 куда большее пространство можно затолкать, чем в utf16

Как я вижу ситуацию, о которой ты печешься в стартовом посте (теория, не проверял в реале). Прога пишет юзеру "в это поле можно вбить не больше 30 символов". Юзер, видя это сообщение, со спокойной душой вбивает 30 символов из "кудрявых" диапазонов юникода. Вбивает он их в DBEdit, который имеет кодировку utf16, та превращает текст в кучку суррогатных пар - UnicodeString длиной, скажем, 50 символов. Если у DBEdit задано свойство MaxLength=30 (Delphi проявит интеллект, ага) - случится фейл. Если нет - либа для работы с Firebird (ну или ты вручную, на худой конец) выдернет из DBEdit 50-симвльную строку в utf16, конвертнет ее в utf8, у которой длина будет как раз те самые "реальные" 30 символов и запишет в БД без исключений. Т.е. в теории проблем никаких нет. Вопрос - насколько хорошо в реале отрабатывает функция MultiByteToWideChar, которая по умолчанию занимается преобразованием utf16 -> utf8, сможет ли она максимально упаковать суррогатные пары, чтобы не вылезти за лимит, или будут нужны доп.ужимки с нормализацией и предварительной проверкой длины utf8-строки во время ввода в DBEdit
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486476
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeДа я знаю что это максимум. И что ansi-символ в utf8 занимает 1 байтНе ansi. А US-ASCII.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486485
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fd00chта же викиХоспидя ...
Ну почитайте вы уже первоисточник . Там всё доходчиво.
А utf8, utf16 и utf32 имеют одну и ту же "информационную ёмкость". Но из этих трёх вариантов только utf8:
1. Полностью совместима с библиотекой стандартных функций языка C;
2. Является байтовой и не зависит от порядка следования этих самых байт в словах.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486494
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fd00chNickDee Википедия своими таблицами на 6 байт конечно вводит в заблуждение.та же вики говорит, что в utf8 суррогатных пар нет. это логично, ведь в utf8 куда большее пространство можно затолкать, чем в utf16

Как я вижу ситуацию, о которой ты печешься в стартовом посте (теория, не проверял в реале). Прога пишет юзеру "в это поле можно вбить не больше 30 символов". Юзер, видя это сообщение, со спокойной душой вбивает 30 символов из "кудрявых" диапазонов юникода. Вбивает он их в DBEdit, который имеет кодировку utf16, та превращает текст в кучку суррогатных пар - UnicodeString длиной, скажем, 50 символов. Если у DBEdit задано свойство MaxLength=30 (Delphi проявит интеллект, ага) - случится фейл. Если нет - либа для работы с Firebird (ну или ты вручную, на худой конец) выдернет из DBEdit 50-симвльную строку в utf16, конвертнет ее в utf8, у которой длина будет как раз те самые "реальные" 30 символов и запишет в БД без исключений. Т.е. в теории проблем никаких нет. Вопрос - насколько хорошо в реале отрабатывает функция MultiByteToWideChar, которая по умолчанию занимается преобразованием utf16 -> utf8, сможет ли она максимально упаковать суррогатные пары, чтобы не вылезти за лимит, или будут нужны доп.ужимки с нормализацией и предварительной проверкой длины utf8-строки во время ввода в DBEdit
У меня нет DBEdit :)
И в первом посте не про то, чтобы ограничить пользователя. Там про создание поля юзером через админку.
Если бы был резиновый varchar, и если бы пользователь хотел специально ограничить длину заданным количеством code points , то я бы создал constraint на поле:
Код: sql
1.
ALTER TABLE T ADD F VARCHAR CHARACTER SET UTF8 CHECK (character_length(F) < 100)

Либо прописал бы проверку в триггере с вменяемым сообщением.
Но не помню чтобы у меня было желание специально ограничить VARCHAR, кроме разве что для нужд хранения GUID и MD5-хэшей.
Т.е если бы был эффективный резиновый тип, я бы в 99% случаев использовал бы его.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486536
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидNickDeeПредполагаю что сервер лучше знает правильную сортировку для UTF8, и лучше это поручить ему.Не забудь учесть, что на производительность сортировки влияет именно объявленная длина поля, а не фактическое число символов, которое в нём хранится. Кроме того, в undo-лог записи попадают также с паддингом варчаров до объявленной длины ( Тынц ).
Про это есть тикеты в трекере? :)
Я вообще удивляюсь. Вроде все знают что проблема с длинными варчарами есть, но блин ведут себя так, будто проблем нет :)
И главное когда другие советуют использовать гигантские VARCHAR(32000), то никто из разработчиков что-то не вспоминает что там есть "нюансы", и не говорит что вот там, там и там разложены грабельки :) Вот что мешает подсказать? :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486556
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeкогда другие советуют использовать гигантские VARCHAR(32000), то никто из
разработчиков что-то не вспоминает что там есть "нюансы", и не говорит что вот там, там и
там разложены грабельки :) Вот что мешает подсказать? :)
Надежда, что тот, кому такое подсказывают (кстати, я таких подсказок что-то не припомню) -
не полный дебил и понимает последствия.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486613
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovNickDeeкогда другие советуют использовать гигантские VARCHAR(32000), то никто из
разработчиков что-то не вспоминает что там есть "нюансы", и не говорит что вот там, там и
там разложены грабельки :) Вот что мешает подсказать? :)
Надежда, что тот, кому такое подсказывают (кстати, я таких подсказок что-то не припомню) -
не полный дебил и понимает последствия.

Я не понимал последствий, но интуитивно чувствовал что они будут, и что мне не понравится :)
Сейчас понимаю лучше.
Кто без интуиции, тем конечно в firebird лучше не идти :) Или нужно хорошо изучать sql.ru и ibase.ru, и обязательно проверять все утверждения :) Короче путь джедая :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486623
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeи обязательно проверять все утверждения :)Когда они относятся к тому, что крутится или планирует крутиться в твоём продакшене - обязательно. Проверить лично, никому не доверять.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486624
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PS. К тому же, когда пальцами промнёшь клаву, набирая все эти recreate table(. . .) и прочая, то полученные результаты в башке застревают не на 2-3 дня, а на гораздо более долгий срок.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486699
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeУ меня нет DBEdit :)что это меняет? у тебя другой наследник от TCustomEdit, который так же хранит введенный текст в utf16 и имеет свойство MaxLength
NickDeeИ в первом посте не про то, чтобы ограничить пользователя. Там про создание поля юзером через админку.ну создал он. а дальше, при заполнении - см. мой текст
NickDeeТ.е если бы был эффективный резиновый тип, я бы в 99% случаев использовал бы его.резиновый текстовый блоб - чем не эффективный? :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486743
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeКто без интуиции, тем конечно в firebird ІТ лучше не идти :) Или нужно хорошо изучать sql.ru и ibase.ru документацию, и обязательно проверять все утверждения :) Короче путь джедая :)
Исправленному - верить ©
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38488896
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кмк, ТС-а тревожит следующий сценарий:
1) Юзер создает поле Имя с длиной 4 символа
2) Юзер вводит "Ива́н" и получает отлуп с формулировкой "Строка не влезла"
3) Юзер приобретает когнитивный диссонанс
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38488898
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal,

ты проверял возможность такого сценария ?
...
Рейтинг: 0 / 0
25 сообщений из 65, страница 2 из 3
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]