|
|
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
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. Т.е. сервер не ругнулся на 20 байт, но ругнулся на 11. Он может так ругнуться только если считает не байты, а символы (т.е. парсит utf8-строку). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 16:51:20 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeОн может так ругнуться только если считает не байты, а символы (т.е. парсит utf8-строку). В данном случае ты ему подсовываешь 11 символов win1251, чтобы он упихал их в VARCHAR(10). Ему даже парсить и конвертировать ничего не надо для того, чтобы дать тебе отлуп. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 16:55:45 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
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. 2. Без галки "Do NOT perform conversion from to UTF8" я при Код: sql 1. получаю вставленную запись, и она нормально отображается в гриде. А при Код: sql 1. я получаю: ------------- Arithmetic overflow or division by zero has occurred. arithmetic exception, numeric overflow, or string truncation. string right truncation. ------------- Т.е. сервер таки честно считает количество UTF8 символов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 17:13:16 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeТ.е. сервер таки честно считает количество UTF8 символов. Пардон - не символов, а unicode code points :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 17:14:20 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeВопрос - что делать? Ни один из этих вариантов не кажется конструктивным :)выбирать из нескольких зол меньшую. почему куча текстовых блобов не нравится? или чрезмерно длинные строковые поля? можешь еще в какой-нить sqlite податься - там у тебя будет для хранения строк один-единый тип TEXT и все, никакой длины. никакой информации о хранении данных, впрочем, тоже)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 17:25:43 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDee, 1. VARCHAR(10) CHARACTER SET UTF8 - это 10 символов UTF8 . А не каких-то других символов. Символ UTF8 - это последовательность от 1 до 4-х байт (теоретически - до 6). 2. Когда ты подсовываешь серверу строку win1251, он знает, что в этой кодировке каждый символ представлен одним байтом. Соответственно, достаточно сравнить длину подсунутой строки с декларированной длиной поля, чтобы дать тебе отлуп или обрабатывать строку дальше. 3. Когда ты подсовываешь серверу некую последовательность байт и намекаешь, что это последовательность символов UTF8, он, разумеется, проверяет, так ли это на самом деле. У символов UTF8 жесткая структура, которая легко валидируется. На этом этапе и длина строки в символах UTF8 легко вычисляется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 17:28:22 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
IBExpertУ символов UTF8 жесткая структура, которая легко валидируется. На этом этапе и длина строки в символах UTF8 легко вычисляется.Дак я про это же и говорю - вычисляется разбором строки. IBExpertСимвол UTF8 - это последовательность от 1 до 4-х байт (теоретически - до 6). В firebird в системных таблицах это 4 байта. И по стандарту тоже 4. Википедия своими таблицами на 6 байт конечно вводит в заблуждение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 17:38:43 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeСоздавать все поля как VARCHAR(8000)? Это не вариант, т.к. у меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255) - тормоза существенные. Создавать стринговые поля как блобы? Это тем более не вариантУ тебя сортировки по этим гамаль-абдель-ибн-хаттаб-аль-трампампам - предполагаются ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 17:41:47 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeВ firebird в системных таблицах это 4 байта. И по стандарту тоже 4. Это максимум. Твои '1234567890' физически будут лежать именно так, занимая ровно 10 байт, а не 40. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 17:55:42 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
ТаблоидNickDeeСоздавать все поля как VARCHAR(8000)? Это не вариант, т.к. у меня уже есть опыт с заданием стринговых полей по-дефолту как VARCHAR(255) - тормоза существенные. Создавать стринговые поля как блобы? Это тем более не вариантУ тебя сортировки по этим гамаль-абдель-ибн-хаттаб-аль-трампампам - предполагаются ? Сортировки скорей всего будут. Но это не мне решать :) Можно сделать чтобы сервер сортировал, можно сделать чтобы грид сортировал. Это настраиваемо. Но по-умолчанию - сервер. Предполагаю что сервер лучше знает правильную сортировку для UTF8, и лучше это поручить ему. Возможно заблуждаюсь :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 18:01:25 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
IBExpertNickDeeВ firebird в системных таблицах это 4 байта. И по стандарту тоже 4. Это максимум. Твои '1234567890' физически будут лежать именно так, занимая ровно 10 байт, а не 40. Да я знаю что это максимум. И что ansi-символ в utf8 занимает 1 байт, а кириллический - 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 18:04:02 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeПредполагаю что сервер лучше знает правильную сортировку для UTF8, и лучше это поручить ему.Не забудь учесть, что на производительность сортировки влияет именно объявленная длина поля, а не фактическое число символов, которое в нём хранится. Кроме того, в undo-лог записи попадают также с паддингом варчаров до объявленной длины ( Тынц ). Так что если твоя апликуха даёт клиенту возможность завести поле для хранения "запиши то - сам пока не знаю что", то это явная ошибка. А для ФИО, мну кажется, достаточно 125 символов ==> это будет varchar(500). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 18:13:41 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 18:42:46 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeДа я знаю что это максимум. И что ansi-символ в utf8 занимает 1 байтНе ansi. А US-ASCII. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 19:08:51 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
fd00chта же викиХоспидя ... Ну почитайте вы уже первоисточник . Там всё доходчиво. А utf8, utf16 и utf32 имеют одну и ту же "информационную ёмкость". Но из этих трёх вариантов только utf8: 1. Полностью совместима с библиотекой стандартных функций языка C; 2. Является байтовой и не зависит от порядка следования этих самых байт в словах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 19:14:53 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
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. Либо прописал бы проверку в триггере с вменяемым сообщением. Но не помню чтобы у меня было желание специально ограничить VARCHAR, кроме разве что для нужд хранения GUID и MD5-хэшей. Т.е если бы был эффективный резиновый тип, я бы в 99% случаев использовал бы его. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 19:20:22 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
ТаблоидNickDeeПредполагаю что сервер лучше знает правильную сортировку для UTF8, и лучше это поручить ему.Не забудь учесть, что на производительность сортировки влияет именно объявленная длина поля, а не фактическое число символов, которое в нём хранится. Кроме того, в undo-лог записи попадают также с паддингом варчаров до объявленной длины ( Тынц ). Про это есть тикеты в трекере? :) Я вообще удивляюсь. Вроде все знают что проблема с длинными варчарами есть, но блин ведут себя так, будто проблем нет :) И главное когда другие советуют использовать гигантские VARCHAR(32000), то никто из разработчиков что-то не вспоминает что там есть "нюансы", и не говорит что вот там, там и там разложены грабельки :) Вот что мешает подсказать? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 19:46:56 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeкогда другие советуют использовать гигантские VARCHAR(32000), то никто из разработчиков что-то не вспоминает что там есть "нюансы", и не говорит что вот там, там и там разложены грабельки :) Вот что мешает подсказать? :) Надежда, что тот, кому такое подсказывают (кстати, я таких подсказок что-то не припомню) - не полный дебил и понимает последствия. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 19:57:34 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovNickDeeкогда другие советуют использовать гигантские VARCHAR(32000), то никто из разработчиков что-то не вспоминает что там есть "нюансы", и не говорит что вот там, там и там разложены грабельки :) Вот что мешает подсказать? :) Надежда, что тот, кому такое подсказывают (кстати, я таких подсказок что-то не припомню) - не полный дебил и понимает последствия. Я не понимал последствий, но интуитивно чувствовал что они будут, и что мне не понравится :) Сейчас понимаю лучше. Кто без интуиции, тем конечно в firebird лучше не идти :) Или нужно хорошо изучать sql.ru и ibase.ru, и обязательно проверять все утверждения :) Короче путь джедая :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 20:37:11 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeи обязательно проверять все утверждения :)Когда они относятся к тому, что крутится или планирует крутиться в твоём продакшене - обязательно. Проверить лично, никому не доверять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 20:52:11 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
PS. К тому же, когда пальцами промнёшь клаву, набирая все эти recreate table(. . .) и прочая, то полученные результаты в башке застревают не на 2-3 дня, а на гораздо более долгий срок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 20:54:29 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeУ меня нет DBEdit :)что это меняет? у тебя другой наследник от TCustomEdit, который так же хранит введенный текст в utf16 и имеет свойство MaxLength NickDeeИ в первом посте не про то, чтобы ограничить пользователя. Там про создание поля юзером через админку.ну создал он. а дальше, при заполнении - см. мой текст NickDeeТ.е если бы был эффективный резиновый тип, я бы в 99% случаев использовал бы его.резиновый текстовый блоб - чем не эффективный? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 22:33:45 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
NickDeeКто без интуиции, тем конечно в firebird ІТ лучше не идти :) Или нужно хорошо изучать sql.ru и ibase.ru документацию, и обязательно проверять все утверждения :) Короче путь джедая :) Исправленному - верить © ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2013, 23:36:16 |
|
||
|
VARCHAR(N) CHARACTER SET UTF8. Какой нужен N?
|
|||
|---|---|---|---|
|
#18+
Кмк, ТС-а тревожит следующий сценарий: 1) Юзер создает поле Имя с длиной 4 символа 2) Юзер вводит "Ива́н" и получает отлуп с формулировкой "Строка не влезла" 3) Юзер приобретает когнитивный диссонанс ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.12.2013, 14:21:53 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=38486743&tid=1564083]: |
0ms |
get settings: |
6ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
171ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
39ms |
get tp. blocked users: |
1ms |
| others: | 199ms |
| total: | 438ms |

| 0 / 0 |
