powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
65 сообщений из 65, показаны все 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
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
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38488906
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Методы решения мне видятся исключительно организационые:
1) Забить (более мягкий вариант - добавлять всяких разъяснений, почему буква с закорючкой идет за два символа)
2) Втихую делать длину поля на N% больше
3) Вообще не ограничивать размеры полей в БД
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38488907
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvladты проверял возможность такого сценария ?
Нет, чистое теоретизирование.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489112
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvladFr0sT-Brutal,

ты проверял возможность такого сценария ?
Сейчас проверил, оказался прав (хотя и не сомневался)
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489241
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-BrutalСейчас проверил, оказался прав (хотя и не сомневался)И можно узнать подробности этой проверки ?
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489294
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SET SQL DIALECT 3;

SET NAMES UTF8;

CREATE DATABASE 'test'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE 16384
DEFAULT CHARACTER SET UTF8 COLLATION UTF8;

CREATE TABLE TABLE2 (
    ID   INTEGER,
    STR  VARCHAR(4)
);



В ИБЭ ввожу "Иван" - ОК, "Ива́н" - SQL error code = -303.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.

И это, в общем-то, абсолютно правильно, т.к. а́ здесь - это "а"+"ударение", а не "а с ударением". Т.е. все верно и ожидаемо, но это я к тому, что есть дофига подобных модификаторов, на самом деле занимающих место символа в строке, и на это надо как-то закладываться
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489380
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-BrutalВ ИБЭ ввожу "Иван" - ОК, "Ива́н" - SQL error code = -303.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.

И это, в общем-то, абсолютно правильно, т.к. а́ здесь - это "а"+"ударение", а не "а с ударением". Т.е. все верно и ожидаемо, но это я к тому, что есть дофига подобных модификаторов, на самом деле занимающих место символа в строке, и на это надо как-то закладываться1. Какой чарсет коннекта в IBE ?
2. Как вводятся данные ? Параметры или строковый литерал ?
3. Как я могу ввести такие данные ?
4. Как это воспроизвести с isql ?

Пока что я не могу быть уверен, что проблема не в клиентском приложении.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489400
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-BrutalВ ИБЭ ввожу "Иван" - ОК, "Ива́н" - SQL error code = -303.
Я в FARе ввожу "Ивáн" и получаю файл размеров 11 байт. Вычитая три байта BOM, получаем ровно 8 байт, что легко влазит в CHAR(4). Так что вся проблема в том как IBE перекодирует твою строку в utf-8.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489416
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Формы нормализации .

P.S. Составные символы это не придурь, а реальность.
Нет в юникоде "одного кода на символ".
Очень хотели сделать, но "не шмогла я, мужик, не шмогла".
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489419
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-BrutalВ ИБЭ ввожу "Иван" - ОК, "Ива́н" - SQL error code = -303.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.Что-то странно. Я создал вот это:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
$ isql -x utf8test.fdb

SET SQL DIALECT 3;

/* CREATE DATABASE 'utf8test.fdb' PAGE_SIZE 4096 DEFAULT CHARACTER SET UTF8; */

/* Table: T, Owner: SYSDBA */
CREATE TABLE T (S VARCHAR(4));

И затем делаю в UTF8-консоли линуха:
Код: plaintext
1.
2.
3.
4.
5.
$ isql utf8test.fdb -n -ch utf8 -i ivan.sql

S
======
Иван

скрипт с иваном в чарсете UTF8 - см аттач. Там в строке 8 знаков
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489429
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvlad,

1. utf8 + RUSSIAN_CHARSET
2. тупо paste в грид
3. я набрал в ворде (ударение вводится через alt+0769 на цифровой клаве)
4. что-то совсем нет желания воспроиводить через комстроку, проблема-то не моя :)

авторЯ в FARе ввожу "Ивáн"
Угу, при конвертации где-то буквы нормализовываются (а́ на á - смотреть в хексе!). У меня это 0x0430 0x0301 и 0x00E1.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489439
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем, еще раз, грубо: есть символы "а с ударением", а есть символ "а" и символ "ударение над предыдущим символом". Последний есть "модификатор" (официального названия не знаю - возможно, Bazil подскажет) - и их реально много (штрихи, тильды, черточки, точки, кружочки, да еще сверху/снизу). И то, что при отображении занимает одно знакоместо - может в строке занимать десяток юникодных символов (code point, точнее).
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489565
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal"Ива́н" - SQL error code = -303.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.ну в Edit с MaxLength=4 этот Иван закономерно не влазит...
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38489965
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
fd00ch, это частный случай применения в среде, которую здесь никто не знает ©. Причем даже там могут применяться и гриды, и обычные edit, и другие редакторы, не подтягивающие maxlength из метаданных. А ТС, например, вообще говорил об админке, а значит, подразумевается веб.

В любом случае, ФБ тут ни при чем, а вопрос скорее в проектировании системы. Я бы сделал тихое увеличение указанной юзером длины на 50%.

С этими юникодными кунштюками всплывает другая проблема, уже посерьезнее, а именно - поиск по таким полям. Но это опять же вопрос проектирования ПО.
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38490904
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutalfd00ch, это частный случай применения в среде, которую здесь никто не знает ©ты про винду?
...
Рейтинг: 0 / 0
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
    #38491426
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Про Дельфи
...
Рейтинг: 0 / 0
65 сообщений из 65, показаны все 3 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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