Programming SHOT BAR へようこそ。
最近ちゃっぴ様のエントリで話題に上がった「入力可能な最大byte数を超えた場合のUIはどうあるべきか」という議題について考えて見たいと思います。
通用しなくなった「全角・半角」
かつてShift_JISが日本語の文字コードとして主流だったころ、「全角・半角」という概念は IT業界人ではなくとも知られるほどに浸透しました。今でも携帯電話ではShift_JISが用いられ「全角・半角」という概念が受け継がれています。
この「全角・半角」というものには2つの側面があります。
ひとつは文字のレンダリング幅、もうひとつは文字のbyte数です。
レンダリング幅についてはTrueTypeフォントの普及で等幅ではなくなりました。 1989年にApple社が開発し、Mac OS 7.0から搭載されたようですが、普及したのはWindows95のシステム標準フォントとなった1996年以降ではないでしょうか。普及してからすでに10年以上の年月が経っています。
文字のbyte数についてはShift_JISではいわゆる半角では1byte、いわゆる全角では2byteとなっており、等幅フォントと併用すると見た目の横幅と byte数が一致するという非常に利便性の高い特徴を備えていました。
一変したのはUnicodeの登場以降です。Unicodeの制定は1993年。 1996年にJavaがリリースされましたが、言語の内部コードにUnicodeが採用されました。当時としては非常に先駆的であったと思います。 Java以降のプログラミング言語では内部文字コードにUnicodeを採用しているものが多いですね。
Windows NT4.0ではUnicodeを扱えたようですがWindowsでは1994年にリリースされたWindows NT 3.1からOS内部コードがUnicodeとなりました。しかしWindows 95/98/MEではOSとしてのUnicodeサポートは無く別途ライブラリを用いる必要がありました。
UnicodeベースのOSが一般的なユーザに用いられるようになったのはWindows2000からです。
このUnicode、符号化の際にはUTF-8およびUTF-16が多く用いられていると思いますが、 UTF-8では1byteから4byteまでの可変長コードとなり、日本語の文字は主に3byteになるなど Shift_JISの特徴とはまるで違います。またUTF-8ではASCII文字に関しては1byteで表現され互換性を持っているのに対し、UTF-16ではこれらも2byteで表現されるなど、もはや「全角・半角」時代のbyte数換算は通用しなくなりました。
どのようなUIがよいのか
文字列を入力するUIを考えた場合、ユーザに対して分かりやすい制限は、入力欄のレンダリング幅そのものを入力上限とすることではないでしょうか。先に述べた文字のレンダリング幅側からの制限で対応しようというものです。
画面にしろ、帳票にしろ、表示するには物理的な空間を必要とします。スペースが無いから折り返して表示するなどの手法もありますが、 HTMLなどにみられる可変なレイアウトでの画面の崩れには辟易していませんか?
「入力」という行為はそもそもどこかに「出力」するために行っているわけです。出力する側に都合をつけてもらうのはそれほどおかしな考えではありません。
(Webシステムではやるべきではないですが)出力のフォントが決められており、文字サイズも決まっているのであれば、与えられた空間に入るだけの文字を入力させるUIがユーザにとっては非常に分かりやすい。
DBの容量は入力に十分なだけ確保しておくことが望ましいでしょう。 文字のbyte数という側面はユーザにとっては関係のない出来事です。出来るだけ隠蔽したい。ただし、合字などの存在がありますから、スペースに対して非常に多量のbyte数の入力が可能となってしまいます。最大で何byte入力される可能性があるのか推測することは困難です。
そのため、現実的な制限として「レンダリング幅の許す範囲内で、文字数上限XX文字以内での入力が可能」という仕様とする必要があるのではないでしょうか。合字の文字数をばらしてカウントする必要があるという点でユーザへの不便を解消し切れませんが、byte数のカウントが人間にはもはや不可能となった中で人間でもカウント可能な値としたところが最大限の対応です。
DBの容量を気にする方もいると思います。しかし近年、ムーアの法則に追従するように、メモリもストレージも飛躍的に大容量化し、また低価格化しました。 1byteの価値が激減したのですから1byteを削ることに労力を費やすことも割に合わなくなっています。システム要件に見合わなくなるほどのコスト高でしょうか?レコードの見込み件数とbyte数でストレージのコストを算出してみてください。
サロゲートペアへの対応
文字数の問題にはサロゲートペアというものもあるわけですが、これはUTF-16での問題です。
現在のUnicodeは21ビットのコードポイントを持つわけですが、16ビットでは当然ながら表現できません。そこでShif_JISのように2つの文字の組み合わせを使いこの21ビットのコードポイントを16ビット、 32ビットの可変長コードで表現しようというものです。
そのため、本来の21ビットのUnicodeのコードポイントに変換してから処理する分にはなんら問題は発生しません。 UTF-8の場合は7ビットまでのコードポイントは1byteのコード、11ビットまでは2byte、16ビットまでは3byte、 21ビットまでは4byteとなりますから、16ビットを超えるコードポイントを持つ (UTF-16ではサロゲートペアで表現される)文字について4byteで符号化します。
UTF-32での符号化であれば常に4byteでの固定長です。
このあたりはプログラミング上のテクニック的な話題であり、 ユーザに対してサロゲートペアかどうかを意識させてはなりません。
合字、合成文字への対応
中様の Unicodeの結合文字は最大何文字くっつけられる?にて紹介されていますが、ハングルやアラビア語、タイ語といった言語の文字や、音符などの記号では複数の文字を合わせてレンダリングするということが行われます。
これらはレンダリング幅では問題ないのですが、byte数を非常に多く消耗します。そして、その入力限界に来た際にどのように警告するのがユーザに分かりやすいか、という話題が残ります。
先にも述べましたが、文字数のカウントはユーザに負担を求めることのできるぎりぎりのラインだと思います。少なくともこれらの文字が「複数の文字の合成だからその文字数分だけカウントしなければならない」というルールをユーザに理解してもらう必要があります。
投稿日時 : 2007年9月13日 14:46