|
|
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Здесь N - это не количество видимых символов, а ограничение на максимальное количество байт в строке, т.е MaxBytes = N * 4; Т.е. если я определю поле как VARCHAR(1000) (что достаточно много, если использовать WIN1251), то пользователь сможет записать туда только 4000 байт юникода, и не байтом больше. Проблема вот в чём - в общем случае я не знаю что конкретно пользователь будет записывать в такое поле. Может это будет просто русский текст, или английский, или европейский. А может китайский или японский. А может математическая формула. А может там будут символы из фонетического алфавита , а может это будет индийский текст , или вот такое арабское письмо с диактриками . Т.е в общем случае я не знаю что там будет, и оценить например сколько будет занимать в байтах банальное ФИО в арабском письме (чтобы потом разделить это на 4 и прописать результат в VARCHAR(N)), я не могу. У меня ещё проблема усугубляется тем, что я даю пользователям создавать поля в БД, и писать логику к ним. Представьте - арабский пользователь идёт в админку создавать поле для хранения ФИО, выбирает таблицу, указывает название нового поля, выбирает тип "string" и тут ему предлагают ввести максимальную длину этого поля в символах (допустим у них там есть такое понятие как символ-место, в чём я не уверен)..., он прикинул - максимум 100 символов, на ФИО. А в реальности создаётся поле не на 100 символов, а на 400 байт юникода, в которые вполне могут не войти даже 20 символов его языка. И что с этим делать - я не знаю. Создавать все поля как VARCHAR(8000)? Это не вариант, т.к. у меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255) - тормоза существенные. Создавать стринговые поля как блобы? Это тем более не вариант :) Вопрос: если бы вы были пользователем программы (например арабским пользователем), которая позволяла бы вам создавать поля, то как бы вы хотели чтобы вас программа ограничивала - максимальной длиной в символах или количеством байт? :) Чисто попробуйте глазами пользователя посмотреть :) Моё имхо как потенциального юникодно-арабского пользователя такое: "я готов указать только тип данных (строка)". Как программист я конечно понимаю что на данном этапе развития firebird у меня варианта только три: либо блобы, либо VARCHAR(8000), либо мучать пользователей. Вопрос - что делать? Ни один из этих вариантов не кажется конструктивным :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 10:17:53 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeу меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255) Странно, мой опыт в 4096 не показывал тормозов... Ну да ладно. Раз уж даешь пользователю создавать поля, то и давай право выбирать максимум символов. Задал жесткое ограничение, к примеру, в 4096, а пользователь в праве выбрать любое меньшее значение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 10:21:33 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeВопрос - что делать?Во-первых понять доку. пока на лицо ее непонимание. Если ты задал в базе поле длиной 100 символов и юникоде, то туда можно запихнуть до 100 символов в любом алфавите который поддерживается УТФ8. Ограничение в том, что в однобайтной кодировке длину варчара можно делать до 32к, то в юникоде только 8к ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 10:40:36 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeВопрос - что делать? в ФБ для юникода используется UTF8 , а у него длина символов плавающая, от 1 до 6 (реально 3, 4 - слишком редкие, 5 и 6 пока не используются). Поэтому предугадать длину вводимой строки невозможно, и, да, надо тупо умножать на 3. Ну или на 4 ( музыкальные символы, редкие китайские иероглифы, вымершие формы письменности ). NickDeeА в реальности создаётся поле не на 100 символов, а на 400 байт юникода, в которые вполне могут не войти даже 20 символов его языка. что? 20 символов "его языка" по любому кодируются максимум в 80 байт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 11:10:36 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeЗдесь N - это не количество видимых символов, а ограничение на максимальное количество байт в строкеС чего ты это взял ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 11:43:42 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
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. --------------------------------------------------- ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 12:25:29 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Это вот из этой темы: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags Короче я после исследований уже не стал бы закладываться что одно символ-место - это максимум 4 байта :) В некоторых языках к одному символу можно приделать несколько чёрточек в разных местах, и смысл (или прочтение) символа изменится, а размер его увеличится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 12:49:53 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
wadmanNickDeeу меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255) Странно, мой опыт в 4096 не показывал тормозов... Ну да ладно. Вот: 10592614 :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 12:58:16 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeehvladС чего ты это взял ? Из экспериментов с юникодом. Вот скриншот из IBExpert. Первый столбец - размер в байтах. Третья строка не влезает в VARCHAR(250):У тебя первая строка имеет размер 258 октетов(байт), что уже опровергает твоё заявление: hvladNickDeeЗдесь N - это не количество видимых символов, а ограничение на максимальное количество байт в строке Вообще-то, в rdb$character_sets есть кол-во байт на символ, пользуйся и не ставь кривых экспериментов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 13:17:14 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeВот: 10592614 :)Тебе там про "пальцем в небо" уже говорилось ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 13:19:55 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeКороче я после исследований уже не стал бы закладываться что одно символ-место - это максимум 4 байта :) В некоторых языках к одному символу можно приделать несколько чёрточек в разных местах, и смысл (или прочтение) символа изменится, а размер его увеличится. Если не придумывать лишних сущностей типа "символ-место", то все будет нормально. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 13:37:02 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
IBExpert, Что-то в новом IBExpert 2013.11.7.1 все шаблоны поломались. Создаю процедуру - заголовок есть тела (begin end) нет, тоже самое и для триггеров и автоинкрементных полей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 13:44:43 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Симонов ДенисIBExpert, Что-то в новом IBExpert 2013.11.7.1 все шаблоны поломались. Создаю процедуру - заголовок есть тела (begin end) нет, тоже самое и для триггеров и автоинкрементных полей. Ну, это не здесь обсуждать надо. Сообщение в конфе я только что увидел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 13:53:46 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
IBExpert, OK ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 13:58:36 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
hvladNickDeeпропущено... Из экспериментов с юникодом. Вот скриншот из IBExpert. Первый столбец - размер в байтах. Третья строка не влезает в VARCHAR(250):У тебя первая строка имеет размер 258 октетов(байт), что уже опровергает твоё заявление: Там тип VARCHAR(5000). А вот третья строка не влезла в VARCHAR(250), как я и сказал. И понятно почему. Потому как в VARCHAR(250) можно поместить только 1000 байт, а там 1008. А первая строка (на 285 октетов-байт) в VARCHAR(250) прекрасно разместилась. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 14:59:48 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
hvladNickDeeВот: 10592614 :)Тебе там про "пальцем в небо" уже говорилось Говорилось, а ниже ( 10593127 ) ты объяснил в чём на самом деле проблема: hvladNickDee2. Скорость работы с такими варчарами. Лично я увидел многократное ускорение от того, что вместо описания udf-функции Код: sql 1. для varchar-полей всех длин, использовал отдельно для полей varchar(256) и ниже вот такое объявление: Код: sql 1. Эта функция используется в триггере для логирования изменений данных поля. Причём обратите внимание, на скорость повлияло именно изменение define udf в базе, а сама процедура WriteAny в dll-ке осталась той же.Это особенности MM. Небольшие куски памяти выделяются из своих пулов, это быстро. А вот 32K уже будет запрошено через VirtualAlloc, это медленно. Так что VARCHAR(256) и VARCHAR(32762) - это иногда две больше разницы, независимо от "пальцем в небо" :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 15:07:10 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeehvladпропущено... У тебя первая строка имеет размер 258 октетов(байт), что уже опровергает твоё заявление: Там тип VARCHAR(5000). А вот третья строка не влезла в VARCHAR(250), как я и сказал. И понятно почему. Потому как в VARCHAR(250) можно поместить только 1000 байт, а там 1008. А первая строка (на 285 октетов-байт) в VARCHAR(250) прекрасно разместилась. Если что, вот табличка: Код: sql 1. 2. 3. 4. 5. Вот такой запрос Код: sql 1. показывает результат: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 15:15:53 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeА вот третья строка не влезла в VARCHAR(250), как я и сказал. И понятно почему. Потому как в VARCHAR(250) можно поместить только 1000 байт, а там 1008. Если твоя софтина раскладывает композитные символы на части при сохранении в БД, это проблема твоей софтины, а не БД. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 15:27:58 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovЕсли твоя софтина раскладывает композитные символы на части при сохранении в БД, это проблема твоей софтины, а не БД.Полностью нормализованное представление - совершенно нормальный подход. Важно только помнить, что составные символы - неотъемлемая часть юникода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 15:46:10 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
kdvв ФБ для юникода используется UTF8 , а у него длина символов плавающая, от 1 до 6 (реально 3, 4 - слишком редкие, 5 и 6 пока не используются)И не будут. Стандарт юникода явно ограничил множество кодовых точек семнадцатью битовыми плоскостями. Т.е. не более четырёх байт в любой из utf8/16/32.20 символов "его языка" по любому кодируются максимум в 80 байт.Некоторые "символы языка" состоят из нескольких кодовых точек. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 15:50:29 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Хм. Получается что VARCHAR(N) - означает всё-таки N юникодных символов :) Просто одно знакоместо может состоять из десятка-двух юникодных символов (думаю можно и больше). Теперь дошло :) Т.е 'строка' войдёт в varchar(6), а если там поставить ударение на последнюю букву, то уже не войдёт, т.к. получится уже 7 юникодных символов ('строка' + символ ударения). А если добавить по ударению к каждой букве (что юникод не запрещает), то получившаяся строка уместится только в VARCHAR(12). Так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 16:03:40 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeПолучается что VARCHAR(N) - означает всё-таки N юникодных символов :)Кодовых точек (code points). А символы (symbols) - уровнем выше и могут состоять из нескольких кодовых точек. И даже из разного количества при разных уровнях нормализации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 16:10:27 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovNickDeeА вот третья строка не влезла в VARCHAR(250), как я и сказал. И понятно почему. Потому как в VARCHAR(250) можно поместить только 1000 байт, а там 1008. Если твоя софтина раскладывает композитные символы на части при сохранении в БД, это проблема твоей софтины, а не БД. Это делает firebird, чтобы проверить не превышает ли юникод-строка ограничение в N юникодных символов. Если я правильно понимаю, то единственный способ сделать такую проверку - это декодировать utf-8 строку. Долго, но ничего не поделаешь :) Или всё-таки проверяет количество байт? Я вот попытался в VARCHAR(250) запихнуть строку на 300 байт обычного текста (300 ansi символов) - не проканало, а на 285 байт юникодного - проканало. Т.е. либо UTF-8 строка честно декодируется сервером для извлечения кол-ва символов, либо я чего-то не понимаю :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 16:11:56 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovNickDeeПолучается что VARCHAR(N) - означает всё-таки N юникодных символов :)Кодовых точек (code points). А символы (symbols) - уровнем выше и могут состоять из нескольких кодовых точек. И даже из разного количества при разных уровнях нормализации. Т.е. более точным будет при создании пользователем поля запрашивать у него не количество символов, а количество кодовых точек (code points) :) Я вот чувствовал что количество символов тут не подходит :) Думаю что в доке к FB нужно написать, что N в VARCHAR(N) - это максимальное количество code points, а ни как не символов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 16:27:08 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeТак? Не так. Знак "а с чертой" может быть представлена как двумя "кодовыми точками", так и одной. NickDeeЭто делает firebird, чтобы проверить не превышает ли юникод-строка ограничение в N юникодных символов. Нет, Firebird ничего подобного не делает. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 16:28:38 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=38485713&tid=1564083]: |
0ms |
get settings: |
10ms |
get forum list: |
20ms |
check forum access: |
6ms |
check topic access: |
6ms |
track hit: |
210ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
65ms |
get tp. blocked users: |
1ms |
| others: | 234ms |
| total: | 563ms |

| 0 / 0 |
