Чи має бути кодування символів, крім UTF-8 (а може бути, UTF-16 / UTF-32)?


31

Моє домашнє тварина переглядає стільки програмних проектів, які мають гори коду для підтримки набору символів. Не зрозумійте мене неправильно, я весь за сумісність, і я радий, що текстові редактори дозволяють відкривати та зберігати файли в декількох наборах символів. Мене дратує те, як розповсюдження не універсальних кодувань символів позначається "належною підтримкою Unicode", а не "проблемою".

Наприклад, дозвольте мені вибрати PostgreSQL та підтримку його набору символів . PostgreSQL має справу з двома типами кодування:

  • Кодування клієнта: використовується в спілкуванні між клієнтом і сервером.
  • Кодування сервера: використовується для внутрішнього зберігання тексту в базі даних.

Я можу зрозуміти, чому добре підтримувати багато кодувань клієнтів. Це дозволяє клієнтам, які не працюють в UTF-8, спілкуватися з PostgreSQL, не потребуючи перетворення. Що я не отримую: чому PostgreSQL підтримує кілька кодувань сервера ? Файли баз даних (майже завжди) несумісні з однієї версії PostgreSQL до наступної, тому сумісність між версіями тут не є проблемою.

UTF-8 - єдиний стандартний набір символів, сумісний з ASCII, який може кодувати всі кодові точки Unicode (якщо я помиляюся, повідомте мені про це). Я вважаю, що UTF-8 - найкращий набір символів, але я готовий миритися з іншими універсальними наборами символів, такими як UTF-16 та UTF-32.

Я вважаю, що всі не універсальні набори символів повинні бути застарілими. Чи є якась вагома причина, чому вони не повинні?


4
@mario: Початкове визначення UTF-8 дозволяло до 6 байт. Пізніше це було штучно обмежено лише для покриття символів, які UTF-16 може підтримувати.
dan04

6
Принаймні PostgreSQL навмисно має справу з кількома кодовими символами. Досить стикатися з випадковою сумішшю UTF-8 та Windows-1252, тому що когось просто не хвилювало.
dan04

5
@ dan04: Робота з російськими текстами колись була болем, оскільки вони використовували декілька кодувань, які були суттєво різними, і, як правило, просто зламали речі для роботи, використовуючи різні шрифти (які часто брешуть про кодування, яке використовується у їх метаданих). Загалом жахливий безлад. Я підозрюю, що вони прибрали, хоча, ймовірно, перейшовши на UTF-8, - оскільки кількість запитів на підтримку з цього напрямку знизилася.
Стипендіати Дональ

3
Теоретичний діапазон Unicode становить від 0 до 0x10ffff. Нічого більше. Ось що говорить стандарт Unicode. UTF-8 обробляє все Unicode і завжди буде. Він не охоплює гіпотетичний діапазон кодування, який не є Unicode, але охоплює весь Unicode.
gnasher729

Відповіді:


16

Оскільки ви згадали про PostgreSQL, я можу сказати з деяким авторитетом, що головна причина вбивства, чому кодування на стороні сервера, які не UTF8 підтримуються настільки детально, полягає в тому, що японцям це потрібно. Мабуть, ідентичне перетворення в обидва кінці між Unicode та різними японськими «застарілими» кодуваннями не завжди можливо, і в деяких випадках таблиці конверсій навіть відрізняються між постачальниками. Це насправді збиває з пантелику, але, мабуть, так. (Широка підтримка набору символів також є однією з причин, чому PostgreSQL настільки популярний в Японії.)

Оскільки ми говоримо про систему баз даних, одне з головних завдань - це можливість надійно зберігати та витягувати дані, як це визначено користувачем, тому перетворення набору символів з втратами іноді не пролетить. Якщо ви мали справу з веб-браузером, скажімо, де важливо лише те, чи результат виглядає нормально, ви, ймовірно, можете піти з підтримки менших кодувань, але в системі бази даних у вас є додаткові вимоги.

Деякі інші причини, згадані в інших відповідях, також застосовуються в якості підтверджуючих аргументів. Але поки японці наклали вето, підтримку налаштування символів не можна зменшити.


Отже, через ці кодування перетворення тексту в UTF-8 і назад взагалі втрачає? Навіть якщо повернення назад буде здійснено негайно (а не через 6 місяців)?
Joey Adams

Джої Адамс: Мабуть, так.
Пітер Ейзентрав

3
Google для "Хань об'єднання", щоб дізнатися, чому
Петро Вікторін

7

Дві очевидні причини: залежно від даних, які ви зберігаєте, перетворення в інший формат може зайняти небагато часу та додаткового місця. Якщо ви зберігаєте 400 мегабайт інформації, подвоєння потреб у пам’яті не є великою справою - але якщо ви зберігаєте 400 терабайт, це починає означати трохи більше. Перетворення 400 терабайт даних з (скажімо) Shift-JIS в UTF-x також може зайняти трохи часу.

Це стає особливо важким, якщо у вас є (наприклад) гарантії безперервного часу, які говорять про те, що база даних буде доступна для всіх, але скажімо, 10 хвилин з будь-якого року, і у вас є база даних, яка оновлюється кілька сотень разів на секунду. Зауважте, що в такій ситуації все-таки можна керувати великими конверсіями, але це не те, що слід робити з легкістю. У деяких випадках може легко пройти роки планування, щоб підготуватися до такого перетворення.

Якщо ви починали з бази даних, яка (наприклад) підтримує лише ASCII, можливо, буде вагома причина для дискусії про те, чи є сенс додавати підтримку для всіх цих кодувань - але якщо ви вже підтримуєте їх, від випадання мало що виграти підтримка для них.

Зауважте, зокрема, що ви, мабуть, отримаєте майже нічого на шляху спрощення коду чи чогось подібного. Вони все одно потребуватимуть всіх процедур перетворення, щоб у будь-якому разі вирішувати конверсії між клієнтом та сервером. Таким чином, відмова від підтримки означатиме відмову від одного (другорядного) виклику функції на шляху "запису на диск" та "читання з диска", але мало (якщо нічого іншого). Якби ви підтримували навіть два кодування на диску, ви навіть не отримали цього - у вас все одно буде функціонувати виклик там, тому все, що ви дійсно зробили б, було б обмеження кола кодувань, підтримуваних цією функцією.

Принаймні, якби я розробляв це, я, ймовірно, напишу ядро ​​бази даних для роботи в UCS-4, а потім матиму підпрограми перетворення між ядром та диском, а також між ядром та користувачем. Я хотів би використовувати один і той же набір підпрограм в обох випадках, так що самий простий маршрут буде дозволити дисковий сховище використовувати точно такий же набір кодувань , як клієнти можуть використовувати.


1
Shift-JIS - це несинхронізація, що робить пошук громіздким. Ви б отримали значне спрощення, не підтримуючи його.
dan04

@ dan04: якщо у вас вже є перевірені часом рути пошуку / індексації для Shift-JIS, перехід на UTF-8 або навіть UCS2, мабуть, покращить продуктивність незначно. Для нової бази даних ви можете вибрати краще, зручніше і регулярніше кодування, як-от UCS2 або UTF-16.
9000

@ dan04: якби ти міг уникнути, якщо не підтримав це взагалі, ти би заробив зовсім небагато. Поки ти підтримуєш його, коли йдеш від клієнтів, ти будеш застряг у більшості своїх неподобств ...
Джеррі Труну

5

Існує кілька проблем із збереженням UTF-8 на сервері:

  1. Яка межа VARCHAR(20)стовпця? Це 20 байт чи 20 "символів" (а в Unicode, що таке "символ", якщо брати до уваги поєднання символів, лігатур тощо)? Гірше, що ж CHAR(20)де насправді потрібно резервувати весь можливий простір: я вірю в MySQL, він резервує 4-кратну кількість байтів для стовпчиків, кодованих UTF-8 (тобто 80 байт за CHAR(20)), просто для обробки найгіршого випадку.
  2. Вам потрібно здійснювати постійні перетворення кодування між кодуванням сервера та кодуванням вашого клієнта. Ви можете стверджувати, що ви також хочете припинити підтримку декількох кодування клієнтів, але якщо ви цього не зробите, то всі рядки потрібно постійно конвертувати. Якщо ви можете зіставити кодування вашого сервера та кодування клієнта, конверсії не потрібні.
  3. Як зазначають інші, UTF-8 є досить ефективним для зберігання англійського тексту, але він дуже неефективний для інших мов - зокрема східноазіатських мов. Ви можете дозволити використовувати UTF-16 або UTF-8 як костюми, я думаю. Або стискати текст, але це робить індексацію та пошук неефективними.

Сказавши все це, я згоден з вами: застарілі кодування здебільшого безглузді, а Unicode - це, як правило, найкраще кодування для всіх нових програм. Якби я сьогодні писав сервер бази даних з нуля, я б підтримував тільки Unicode і взагалі не підтримував би застаріле кодування.

Різниця полягає в тому, що PostgreSQL та більшість інших серверів баз даних, які використовуються сьогодні, існували раніше, ніж Unicode був життєздатним варіантом. Тож у них вже була підтримка застарілих кодувань (вони, звичайно, не були тоді, як наслідок) і просто не так багато сенсу виривати весь цей код з значних ідеологічних причин.


10
"але це дуже неефективно для інших мов - східноазіатських мов, зокрема" Навіть на практиці? Розгляньте цю сторінку китайської Вікіпедії . Незважаючи на те, що на ньому відображено надзвичайно багато китайських символів, у джерелі сторінки символи ASCII переповнюють їх майже 7: 1.
Joey Adams

2
Якщо N у вашому стовпці CHAR (N) є частиною чітко визначеного формату ідентифікатора (наприклад, для VIN визначено рівно 17 символів), то, ймовірно, не потрібно поєднувати символи чи лігатури. Якщо ні, то N - це лише довільна межа, яку слід щедро трактувати, щоб уникнути обрізання даних.
dan04

5
@Joey Adams: це стосується HTML та XML, де розмітка сама по собі складає велику частку тексту (і тому я вважаю, що UTF-8 є хорошим вибором для Інтернету), але у базі даних ви часто не зберігаєте HTML. Зрештою, це лише коефіцієнт у дві (або менші) різниці, що насправді не так вже й багато.
Дін Хардінг

5
Пункт №2 у цій відповіді не має значення: він застосовується, чи використовується Unicode чи ні. Пункт №3 кулі абсолютно перебільшує неефективність та її масштаби. У той же час ця відповідь значно ініціює проблеми, спричинені застарілими кодуваннями. Неважко припустити, що проблема не така вже й велика, якщо все, що ви коли-небудь використовуєте у своєму житті, - це англійська мова.
Тімві

2
@Dean: Я не знав, що не можна коментувати відповідь, не публікуючи жодної власної.
Тімві

3

Універсальні (а саме однобайтові) кодування мають своє місце: У системах, які:

  • Не вистачає пам'яті, щоб зберігати базу даних символів Unicode.
  • Мати однобайтовий шрифт, жорстко закодований в ПЗУ.
  • Не майте доступу до Інтернету, щоб забезпечити джерело файлів, кодованих різним чином.

Це актуально сьогодні для деяких типів вбудованих пристроїв. Але на робочому столі, так і в серверній кімнаті, кодування без Unicode має бути давно застарілим тепер.


3
У мене раніше були такі домашні комп’ютери. Я позбувся більшості з них на початку 80-х.
Девід Торнлі

2

UTF-8 - найкращий для вас егоцентричний 1 динамік англійської мови. Якби ви були японцями, приблизно 99% ваших персонажів брали б 3-4 байти замість двох в UTF-16.

Не латинські діалекти дійсно страждають від UTF-8 на рівні розміру. Не забувайте, що протягом декількох років більшість ваших клієнтів можуть бути китайцями, а в китайській мові є мільйони символів. Ви не можете це ефективно підтримувати з UTF-8.

В іншому випадку, я ненавиджу, коли у мене є текстові документи, які не в UTF- чого - то . Я часто виходжу зі свого шляху, якщо потрібно мати правильне кодування. У моїй книзі кодування Unicode мертві.

1. Не сприймайте егоцентричну участь особисто. Мені хотілося зробити барвисту ілюстрацію, і я цього не маю на увазі.


3
@Matthew - 4x явно в 4 рази більше, ніж x (для позитивного x). Я не бачу, наскільки асимптотичні позначення тут доречні. Я ніколи не бачив жорсткого диска, який рекламувався з асимптотичним темпом зростання. Зазвичай розмір залишається однаковим протягом усього терміну експлуатації накопичувача.
Steve314

3
Мільйони символів ніяк не вмістяться в Unicode. Відповідно до статті Вікіпедії, наразі існує близько шістдесяти тисяч персонажів Хана. Оскільки Unicode - це не лише китайський, це означає, що досить велика кількість китайських символів займе чотири байти в UTF-16, що є таким чином, скільки UTF-8 отримує сьогодні. Було б цікаво побачити статистику довжин китайських текстів у UTF-8 та UTF-16.
Девід Торнлі

6
@David:> 99% всіх японських та китайських текстів використовують символи, для яких потрібні лише 2 байти в UTF-16 і 3 в UTF-8. Персонажі, яких потрібно більше, дуже рідкісні та / або історичні.
Тімві

8
Майте на увазі, що японці та китайці зазвичай використовують менше символів за кожне слово. Я працюю з додатком, який має великі файли мови англійською, японською та китайською мовами, усі закодовані у utf-8. Китайський файл насправді найменший, тоді як японський файл приблизно на 15% більший, ніж англійський оригінал.
Gort the Robot

3
Дурниці. Все, що займає два байти в UTF-16, займає не більше 3 байт у UTF-8. У UTF-8 чотири байти - це 4 байти в UTF-16. Немає "мільйонів" китайських ієрогліфів, і очевидно, вони б не вписалися в 16 біт.
gnasher729

1

Юнікод принципово порушений і навряд чи коли-небудь буде виправлений. Його потрібно замінити чимось кращим, чимось справді універсальним. Якщо що-небудь потребує депресії, це Unicode.

Приклади проблем із програмою Unicide:

  • UTF8 - це розумний злом, але більшість програм на базі UTF16 зламана. Більшість програм Windows, які підтримують Unicode, використовують UTF16, включаючи саму ОС. Найпоширеніша проблема - це не підтримка більше, ніж основна площина, тобто багатослівні символи.

  • Об’єднання Хань - це незручне лихо. Неможливо змішати японський / китайський / корейський текст в одному документі без зайвих метаданих, і важко визначити, який шрифт слід використовувати.

  • Комбінаційні персонажі - ще одна катастрофа. Більш розумні схеми кодування відображають один символ на один код, що робить обробку рядків відносно здоровими. Unicode не робить. Unicode навіть не є послідовним - Хан символи - це переважно комбінації, але не кодуються як такі, де є європейські комбінаційні символи.

  • Імена деяких людей не можуть бути записані правильно в Unicode, або вони дуже схильні до неправильного відображення через вищезазначені проблеми. Це може мати серйозні наслідки, наприклад, при спробі сісти на літак з паспортом, який не відповідає тому, що (неправильно) надруковано в квитку.

Через ці проблеми та багато іншого, багато програм, які не є англійською мовою, не можуть використовувати Unicode і покладаються на локальні кодування символів. Особливо це стосується японського та китайського програмного забезпечення.

В ідеалі Unicode слід застаріти. Кодування символів TRON є досить хорошою заміною для Unicode і значною мірою сумісно для існуючого програмного забезпечення, яке не оновлюється.


Ваша заява, що неможливо змішати різні варіанти символів (японський / корейський / китайський), здається, застаріла після 15 років, стандарт Unicode 3.2 2002 року. Підтримка варіантів підтримки Unicode, кодові точки, які після кодової точки han чітко вказують, яку форму повинні відображатися. Також комбінаторні символи визначаються як "поєднання діакритичних знаків" з базовими символами (a °), так і спеціальними гліфами (å), процес їх перетворення навпаки - "нормалізація". Отже, ні, Unicode принципово не порушений.
Торстен С.

Ви ілюструєте багато недоліків. Деякі мови використовують комбінаційні символи, деякі - ні, і Unicode не може визначити, якому він надає перевагу. Як я зазначив, більшість програмного забезпечення, яке стверджує, що підтримує Unicode, так чи інакше не розуміє цих проблем, і відображатиме його неправильно навіть із селекторами. Не слід очікувати, що програмісти будуть мовними експертами, що є іншим фундаментальним недоліком у Unicode.
користувач

0

Можливо, для письма, але не для читання.

Існує багато існуючого вмісту, який використовує ці кодування, а деякі кодування, такі як base64, нікуди не діваються, оскільки деякі текстові протоколи наказують їм як способи вбудовування двійкових даних.

Справжньою проблемою є автоматичне виявлення кодувань, що призводить до захисту дірок. Я б не проти бачити, як деякі незрозумілі кодування, такі як UTF-7, просто зникають.

Автоматичне виявлення також має тенденцію погано справлятися із вмістом, створеним наївним об'єднанням рядків байтів.


7
Base64 - не кодування символів.
dan04

0

Я можу погодитись, що кодування символів за замовчуванням для баз даних та нових програм має бути якимось варіантом UTF. Я особисто вирішив би UTF-16, оскільки це здається розумним компромісом щодо простору та складності (більше, ніж UTF-8). Однак, деякі кодування символів все ж мають сенс у певних випадках.

  • Якщо ви зберігаєте / передаєте текст base64, вам потрібен лише ASCII, і ви навіть можете піти з 7-бітових закодованих протоколів, таких як електронна пошта. Додаткові накладні витрати UTF-8 не потрібні.
  • На цих старих кодуваннях символів побудовано декілька файлів та існуючих даних, важливо мати можливість їх читання.

Зауважте, що існує 4 стандартних алгоритму нормалізації UTF. Якщо вас турбують символи з кількома кодами, ви можете використовувати один з двох алгоритмів нормалізації, які згортають їх у еквівалентний символ однокодової точки. Різниця між ними пов'язана з логічною еквівалентністю та фізичною еквівалентністю символів.


1
Чи можете сказити, будь ласка, чому вони поступили?
Берін Лорич

3
Я не сказав, але вся суть base64 полягає в передачі двійкових даних по текстовому каналу. Якби ви могли вибрати, яке кодування використовувати на цьому каналі, ви б взагалі не використовували текстове кодування. Навіть якщо ваш канал дійсно звичайний ASCII, база 64 використовує лише 6 з 7 біт - це вже значні витрати.
Steve314

Я сподіваюся, що хтось не просто прочитав пункти. Це були винятки з використання UTF. І ви невірно ставитесь до бази 64, використовуючи лише 6 з 8 байтів. Перший набір символів ASCII - це недруковані контрольні символи, що змушує деяких символів у base64 використовувати 7 з 8 байтів. Це навмисно уникає високого біта, оскільки всі ці символи не гарантовано існують на кожній кодовій сторінці, тоді як символи від 0-127 є.
Берін Лорич

2
@Berin - (1) ні, але те, що "я згоден", не дуже багато без пунктів, а (2) база 64 має 64 "цифри". 64 цифри - це 6 біт, тому що 2 ^ 6 == 64. Як ви уявляєте, що в 7-бітовому кодовому просторі (або 8 біт, або навіть 8 байт, якщо потрібно) є окремим від того, скільки даних насправді є. Уникнення недрукувальних символів тощо є причиною накладних витрат - це не означає, що накладні дані не існують. Виберіть канал, призначений для двійкових даних, і накладних даних немає.
Steve314

3
Майте на увазі, що base64 був придуманий для надсилання двійкових даних по текстовому каналу. Він, як відомо, неефективний (3: 4 розширення), але стосується технічних обмежень у певних варіантах транспорту. Спадщина буде електронною поштою та форумами UseNet, але більш сучасним додатком було б вбудовування бінарних даних у XML. Іноді належного каналу не існує , і вам доведеться працювати через обмеження існуючих.
Берін Лорич
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.