powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
25 сообщений из 65, страница 1 из 3
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485578
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здесь N - это не количество видимых символов, а ограничение на максимальное количество байт в строке, т.е MaxBytes = N * 4;
Т.е. если я определю поле как VARCHAR(1000) (что достаточно много, если использовать WIN1251), то пользователь сможет записать туда только 4000 байт юникода, и не байтом больше.
Проблема вот в чём - в общем случае я не знаю что конкретно пользователь будет записывать в такое поле.
Может это будет просто русский текст, или английский, или европейский. А может китайский или японский. А может математическая формула. А может там будут символы из фонетического алфавита , а может это будет индийский текст , или вот такое арабское письмо с диактриками .
Т.е в общем случае я не знаю что там будет, и оценить например сколько будет занимать в байтах банальное ФИО в арабском письме (чтобы потом разделить это на 4 и прописать результат в VARCHAR(N)), я не могу.

У меня ещё проблема усугубляется тем, что я даю пользователям создавать поля в БД, и писать логику к ним. Представьте - арабский пользователь идёт в админку создавать поле для хранения ФИО, выбирает таблицу, указывает название нового поля, выбирает тип "string" и тут ему предлагают ввести максимальную длину этого поля в символах (допустим у них там есть такое понятие как символ-место, в чём я не уверен)..., он прикинул - максимум 100 символов, на ФИО. А в реальности создаётся поле не на 100 символов, а на 400 байт юникода, в которые вполне могут не войти даже 20 символов его языка.
И что с этим делать - я не знаю. Создавать все поля как VARCHAR(8000)? Это не вариант, т.к. у меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255) - тормоза существенные. Создавать стринговые поля как блобы? Это тем более не вариант :)

Вопрос: если бы вы были пользователем программы (например арабским пользователем), которая позволяла бы вам создавать поля, то как бы вы хотели чтобы вас программа ограничивала - максимальной длиной в символах или количеством байт? :) Чисто попробуйте глазами пользователя посмотреть :)
Моё имхо как потенциального юникодно-арабского пользователя такое: "я готов указать только тип данных (строка)". Как программист я конечно понимаю что на данном этапе развития firebird у меня варианта только три: либо блобы, либо VARCHAR(8000), либо мучать пользователей.
Вопрос - что делать? Ни один из этих вариантов не кажется конструктивным :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485584
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeу меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255)
Странно, мой опыт в 4096 не показывал тормозов... Ну да ладно.

Раз уж даешь пользователю создавать поля, то и давай право выбирать максимум символов. Задал жесткое ограничение, к примеру, в 4096, а пользователь в праве выбрать любое меньшее значение.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485611
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeВопрос - что делать?Во-первых понять доку. пока на лицо ее непонимание.
Если ты задал в базе поле длиной 100 символов и юникоде, то туда можно запихнуть до 100 символов в любом алфавите который поддерживается УТФ8.
Ограничение в том, что в однобайтной кодировке длину варчара можно делать до 32к, то в юникоде только 8к
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485654
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeВопрос - что делать?
в ФБ для юникода используется UTF8 , а у него длина символов плавающая, от 1 до 6 (реально 3, 4 - слишком редкие, 5 и 6 пока не используются). Поэтому предугадать длину вводимой строки невозможно, и, да, надо тупо умножать на 3. Ну или на 4 ( музыкальные символы, редкие китайские иероглифы, вымершие формы письменности ).

NickDeeА в реальности создаётся поле не на 100 символов, а на 400 байт юникода, в которые вполне могут не войти даже 20 символов его языка.
что? 20 символов "его языка" по любому кодируются максимум в 80 байт.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485713
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeЗдесь N - это не количество видимых символов, а ограничение на максимальное количество байт в строкеС чего ты это взял ?
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485773
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladNickDeeЗдесь N - это не количество видимых символов, а ограничение на максимальное количество байт в строкеС чего ты это взял ?
Из экспериментов с юникодом.
Вот скриншот из IBExpert. Первый столбец - размер в байтах.
Третья строка не влезает в VARCHAR(250):
---------------------------------------------------
Incompatible column/host variable data type.
Dynamic SQL Error.
SQL error code = -303.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
---------------------------------------------------
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485822
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это вот из этой темы: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags
Короче я после исследований уже не стал бы закладываться что одно символ-место - это максимум 4 байта :) В некоторых языках к одному символу можно приделать несколько чёрточек в разных местах, и смысл (или прочтение) символа изменится, а размер его увеличится.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485844
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanNickDeeу меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255)
Странно, мой опыт в 4096 не показывал тормозов... Ну да ладно.
Вот: 10592614 :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485878
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeehvladС чего ты это взял ?
Из экспериментов с юникодом.
Вот скриншот из IBExpert. Первый столбец - размер в байтах.
Третья строка не влезает в VARCHAR(250):У тебя первая строка имеет размер 258 октетов(байт), что уже опровергает твоё заявление:
hvladNickDeeЗдесь N - это не количество видимых символов, а ограничение на максимальное количество байт в строке
Вообще-то, в rdb$character_sets есть кол-во байт на символ, пользуйся и не ставь кривых экспериментов
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485885
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeВот: 10592614 :)Тебе там про "пальцем в небо" уже говорилось
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38485927
IBExpert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeКороче я после исследований уже не стал бы закладываться что одно символ-место - это максимум 4 байта :) В некоторых языках к одному символу можно приделать несколько чёрточек в разных местах, и смысл (или прочтение) символа изменится, а размер его увеличится.

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

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

Что-то в новом IBExpert 2013.11.7.1 все шаблоны поломались. Создаю процедуру - заголовок есть тела (begin end) нет, тоже самое и для триггеров и автоинкрементных полей.

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

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

Из экспериментов с юникодом.
Вот скриншот из IBExpert. Первый столбец - размер в байтах.
Третья строка не влезает в VARCHAR(250):У тебя первая строка имеет размер 258 октетов(байт), что уже опровергает твоё заявление:
Там тип VARCHAR(5000).
А вот третья строка не влезла в VARCHAR(250), как я и сказал. И понятно почему. Потому как в VARCHAR(250) можно поместить только 1000 байт, а там 1008.
А первая строка (на 285 октетов-байт) в VARCHAR(250) прекрасно разместилась.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486048
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladNickDeeВот: 10592614 :)Тебе там про "пальцем в небо" уже говорилось
Говорилось, а ниже ( 10593127 ) ты объяснил в чём на самом деле проблема: hvladNickDee2. Скорость работы с такими варчарами. Лично я увидел многократное ускорение от того, что вместо описания udf-функции
Код: sql
1.
DECLARE EXTERNAL FUNCTION WSC_ INTEGER, INTEGER, VARCHAR(32762) BY DESCRIPTOR, VARCHAR(32762) BY DESCRIPTOR RETURNS INTEGER BY VALUE ENTRY_POINT 'WriteAny' ...


для varchar-полей всех длин, использовал отдельно для полей varchar(256) и ниже вот такое объявление:
Код: sql
1.
DECLARE EXTERNAL FUNCTION WSC_256 INTEGER, INTEGER, VARCHAR(256) BY DESCRIPTOR, VARCHAR(256) BY DESCRIPTOR RETURNS INTEGER BY VALUE ENTRY_POINT 'WriteAny' ...


Эта функция используется в триггере для логирования изменений данных поля. Причём обратите внимание, на скорость повлияло именно изменение define udf в базе, а сама процедура WriteAny в dll-ке осталась той же.Это особенности MM. Небольшие куски памяти выделяются из своих пулов, это быстро.
А вот 32K уже будет запрошено через VirtualAlloc, это медленно.

Так что VARCHAR(256) и VARCHAR(32762) - это иногда две больше разницы, независимо от "пальцем в небо" :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486056
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeehvladпропущено...
У тебя первая строка имеет размер 258 октетов(байт), что уже опровергает твоё заявление:
Там тип VARCHAR(5000).
А вот третья строка не влезла в VARCHAR(250), как я и сказал. И понятно почему. Потому как в VARCHAR(250) можно поместить только 1000 байт, а там 1008.
А первая строка (на 285 октетов-байт) в VARCHAR(250) прекрасно разместилась.
Если что, вот табличка:
Код: sql
1.
2.
3.
4.
5.
CREATE TABLE FFFFFF (
    ID          INTEGER NOT NULL,
    S1          VARCHAR(5000),
    X           VARCHAR(250)
);


Вот такой запрос
Код: sql
1.
select octet_length(S1), S1, octet_length(X), X from FFFFFF


показывает результат:
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486068
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeА вот третья строка не влезла в VARCHAR(250), как я и сказал. И понятно
почему. Потому как в VARCHAR(250) можно поместить только 1000 байт, а там 1008.

Если твоя софтина раскладывает композитные символы на части при сохранении в БД, это
проблема твоей софтины, а не БД.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486100
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovЕсли твоя софтина раскладывает композитные символы на части при сохранении в БД, это
проблема твоей софтины, а не БД.Полностью нормализованное представление - совершенно нормальный подход.
Важно только помнить, что составные символы - неотъемлемая часть юникода.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486105
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvв ФБ для юникода используется UTF8 , а у него длина символов плавающая, от 1 до 6 (реально 3, 4 - слишком редкие, 5 и 6 пока не используются)И не будут.
Стандарт юникода явно ограничил множество кодовых точек семнадцатью битовыми плоскостями. Т.е. не более четырёх байт в любой из utf8/16/32.20 символов "его языка" по любому кодируются максимум в 80 байт.Некоторые "символы языка" состоят из нескольких кодовых точек.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486131
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм.
Получается что VARCHAR(N) - означает всё-таки N юникодных символов :)
Просто одно знакоместо может состоять из десятка-двух юникодных символов (думаю можно и больше).
Теперь дошло :)

Т.е 'строка' войдёт в varchar(6), а если там поставить ударение на последнюю букву, то уже не войдёт, т.к. получится уже 7 юникодных символов ('строка' + символ ударения). А если добавить по ударению к каждой букве (что юникод не запрещает), то получившаяся строка уместится только в VARCHAR(12). Так?
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486143
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeПолучается что VARCHAR(N) - означает всё-таки N юникодных символов :)Кодовых точек (code points).
А символы (symbols) - уровнем выше и могут состоять из нескольких кодовых точек. И даже из разного количества при разных уровнях нормализации.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486146
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovNickDeeА вот третья строка не влезла в VARCHAR(250), как я и сказал. И понятно
почему. Потому как в VARCHAR(250) можно поместить только 1000 байт, а там 1008.

Если твоя софтина раскладывает композитные символы на части при сохранении в БД, это
проблема твоей софтины, а не БД.

Это делает firebird, чтобы проверить не превышает ли юникод-строка ограничение в N юникодных символов.
Если я правильно понимаю, то единственный способ сделать такую проверку - это декодировать utf-8 строку. Долго, но ничего не поделаешь :)
Или всё-таки проверяет количество байт? Я вот попытался в VARCHAR(250) запихнуть строку на 300 байт обычного текста (300 ansi символов) - не проканало, а на 285 байт юникодного - проканало.
Т.е. либо UTF-8 строка честно декодируется сервером для извлечения кол-ва символов, либо я чего-то не понимаю :)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486173
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovNickDeeПолучается что VARCHAR(N) - означает всё-таки N юникодных символов :)Кодовых точек (code points).
А символы (symbols) - уровнем выше и могут состоять из нескольких кодовых точек. И даже из разного количества при разных уровнях нормализации.
Т.е. более точным будет при создании пользователем поля запрашивать у него не количество символов, а количество кодовых точек (code points) :)
Я вот чувствовал что количество символов тут не подходит :)

Думаю что в доке к FB нужно написать, что N в VARCHAR(N) - это максимальное количество code points, а ни как не символов.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38486176
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeТак?
Не так. Знак "а с чертой" может быть представлена как двумя "кодовыми точками", так и одной.

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


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