Hatena::ブログ(Diary)

xmallocのプログラミングノート

2010年07月29日

MySQLにインストールされたCHARACTER SETとCOLLATIONの確認方法とカラム別の設定方法

MySQLはVARCHAR型のカラムに対して、(CREATE DATABASE等で指定された)デフォルトのキャラクタセットと照合順序を使用して文字列検索を行います。

CREATE DATABASE mydb DEFAULT CHARACTER SET utf8;

上のように定義したデータベースのキャラクタセットはutf8となり、照合順序はutf8_general_ciとなります。

噛み砕いて言うと、このデータベースではデフォルトでVARCHAR等のカラムのキャラクタセットはutf8となり、utf8なので1文字のサイズは3バイトとなり、文字列型カラムの比較では大文字小文字を区別しなくなります。(_ciはcase insensitiveの略です。)



だいたいの場合上の設定で問題無いですが、たまにカラムごとにキャラクタセットと照合順序を変更したくなります。

例えばVARCHARカラムにエスケープ済みURLを保存したい場合、1文字3バイトは冗長です。インデクスを使用する場合MySQLの制限でインデクス列の合計サイズが1000バイト以下でないといけないので、utf8のままですとVARCHAR(333)あたりが上限となり、URLを保存するカラムとしては微妙に短い気がします。また大文字小文字を区別しないのもURLとしては問題ありです。

で、カラムごとにキャラクタセットと照合順序を変更するにはCHARACTER SETとCOLLATE構文を使用します。例の続きで、URL用カラムならこんな感じにしてます。

CREATE TABLE url_data
(url VARCHAR(1000) CHARACTER SET ascii COLLATE ascii_bin);

ちなみにテーブル単位でキャラクタセットと照合順序を指定することもできますが使ったことないです。

CREATE TABLE url_data
(url VARCHAR(1000))
CHARACTER SET ascii COLLATE ascii_bin;


キャラクタセットと照合順序を変更するには、それぞれサーバで指定可能な値を調べる必要があります。

ログインしているMySQLデータベースでどういったキャラクタセットがサポートされているかは、SHOW CHARACTER SET命令で確認できます。Default collationがそのキャラクタセットのデフォルト照合順序です。COLLATEを指定せずにCHARACTER SETだけ指定するとDefault collationが照合順序となります。

mysql> SHOW CHARACTER SET;
+----------+-----------------------------+---------------------+--------+
| Charset  | Description                 | Default collation   | Maxlen |
+----------+-----------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |      2 | 
| dec8     | DEC West European           | dec8_swedish_ci     |      1 | 
| cp850    | DOS West European           | cp850_general_ci    |      1 | 
| hp8      | HP West European            | hp8_english_ci      |      1 | 
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |      1 | 
| latin1   | cp1252 West European        | latin1_swedish_ci   |      1 | 
| latin2   | ISO 8859-2 Central European | latin2_general_ci   |      1 | 
| swe7     | 7bit Swedish                | swe7_swedish_ci     |      1 | 
| ascii    | US ASCII                    | ascii_general_ci    |      1 | 
| ujis     | EUC-JP Japanese             | ujis_japanese_ci    |      3 | 
| sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |      2 | 
| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |      1 | 
| tis620   | TIS620 Thai                 | tis620_thai_ci      |      1 | 
| euckr    | EUC-KR Korean               | euckr_korean_ci     |      2 | 
| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |      1 | 
| gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |      2 | 
| greek    | ISO 8859-7 Greek            | greek_general_ci    |      1 | 
| cp1250   | Windows Central European    | cp1250_general_ci   |      1 | 
| gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |      2 | 
| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |      1 | 
| armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci |      1 | 
| utf8     | UTF-8 Unicode               | utf8_general_ci     |      3 | 
| ucs2     | UCS-2 Unicode               | ucs2_general_ci     |      2 | 
| cp866    | DOS Russian                 | cp866_general_ci    |      1 | 
| keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  |      1 | 
| macce    | Mac Central European        | macce_general_ci    |      1 | 
| macroman | Mac West European           | macroman_general_ci |      1 | 
| cp852    | DOS Central European        | cp852_general_ci    |      1 | 
| latin7   | ISO 8859-13 Baltic          | latin7_general_ci   |      1 | 
| cp1251   | Windows Cyrillic            | cp1251_general_ci   |      1 | 
| cp1256   | Windows Arabic              | cp1256_general_ci   |      1 | 
| cp1257   | Windows Baltic              | cp1257_general_ci   |      1 | 
| binary   | Binary pseudo charset       | binary              |      1 | 
| geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  |      1 | 
| cp932    | SJIS for Windows Japanese   | cp932_japanese_ci   |      2 | 
| eucjpms  | UJIS for Windows Japanese   | eucjpms_japanese_ci |      3 | 
+----------+-----------------------------+---------------------+--------+
36 rows in set (0.00 sec)

照合順序の確認はSHOW COLLATIONです。_ciで終わるCollationはcase insensitive比較、_binで終わるCollationがバイナリとして比較です。MySQL4とかだと_csで終わる照合順序もあったと思いますが、5.1だと無いっぽいです。

mysql> SHOW COLLATION;
+----------------------+----------+-----+---------+----------+---------+
| Collation            | Charset  | Id  | Default | Compiled | Sortlen |
+----------------------+----------+-----+---------+----------+---------+
| big5_chinese_ci      | big5     |   1 | Yes     | Yes      |       1 | 
| big5_bin             | big5     |  84 |         | Yes      |       1 | 
| dec8_swedish_ci      | dec8     |   3 | Yes     | Yes      |       1 | 
| dec8_bin             | dec8     |  69 |         | Yes      |       1 | 
| cp850_general_ci     | cp850    |   4 | Yes     | Yes      |       1 | 
| cp850_bin            | cp850    |  80 |         | Yes      |       1 | 
| hp8_english_ci       | hp8      |   6 | Yes     | Yes      |       1 | 
| hp8_bin              | hp8      |  72 |         | Yes      |       1 | 
| koi8r_general_ci     | koi8r    |   7 | Yes     | Yes      |       1 | 
| koi8r_bin            | koi8r    |  74 |         | Yes      |       1 | 
| latin1_german1_ci    | latin1   |   5 |         | Yes      |       1 | 
| latin1_swedish_ci    | latin1   |   8 | Yes     | Yes      |       1 | 
| latin1_danish_ci     | latin1   |  15 |         | Yes      |       1 | 
| latin1_german2_ci    | latin1   |  31 |         | Yes      |       2 | 
| latin1_bin           | latin1   |  47 |         | Yes      |       1 | 
| latin1_general_ci    | latin1   |  48 |         | Yes      |       1 | 
| latin1_general_cs    | latin1   |  49 |         | Yes      |       1 | 
| latin1_spanish_ci    | latin1   |  94 |         | Yes      |       1 | 
| latin2_czech_cs      | latin2   |   2 |         | Yes      |       4 | 
| latin2_general_ci    | latin2   |   9 | Yes     | Yes      |       1 | 
| latin2_hungarian_ci  | latin2   |  21 |         | Yes      |       1 | 
| latin2_croatian_ci   | latin2   |  27 |         | Yes      |       1 | 
| latin2_bin           | latin2   |  77 |         | Yes      |       1 | 
| swe7_swedish_ci      | swe7     |  10 | Yes     | Yes      |       1 | 
| swe7_bin             | swe7     |  82 |         | Yes      |       1 | 
| ascii_general_ci     | ascii    |  11 | Yes     | Yes      |       1 | 
| ascii_bin            | ascii    |  65 |         | Yes      |       1 | 
| ujis_japanese_ci     | ujis     |  12 | Yes     | Yes      |       1 | 
| ujis_bin             | ujis     |  91 |         | Yes      |       1 | 
| sjis_japanese_ci     | sjis     |  13 | Yes     | Yes      |       1 | 
| sjis_bin             | sjis     |  88 |         | Yes      |       1 | 
| hebrew_general_ci    | hebrew   |  16 | Yes     | Yes      |       1 | 
| hebrew_bin           | hebrew   |  71 |         | Yes      |       1 | 
| tis620_thai_ci       | tis620   |  18 | Yes     | Yes      |       4 | 
| tis620_bin           | tis620   |  89 |         | Yes      |       1 | 
| euckr_korean_ci      | euckr    |  19 | Yes     | Yes      |       1 | 
| euckr_bin            | euckr    |  85 |         | Yes      |       1 | 
| koi8u_general_ci     | koi8u    |  22 | Yes     | Yes      |       1 | 
| koi8u_bin            | koi8u    |  75 |         | Yes      |       1 | 
| gb2312_chinese_ci    | gb2312   |  24 | Yes     | Yes      |       1 | 
| gb2312_bin           | gb2312   |  86 |         | Yes      |       1 | 
| greek_general_ci     | greek    |  25 | Yes     | Yes      |       1 | 
| greek_bin            | greek    |  70 |         | Yes      |       1 | 
| cp1250_general_ci    | cp1250   |  26 | Yes     | Yes      |       1 | 
| cp1250_czech_cs      | cp1250   |  34 |         | Yes      |       2 | 
| cp1250_croatian_ci   | cp1250   |  44 |         | Yes      |       1 | 
| cp1250_bin           | cp1250   |  66 |         | Yes      |       1 | 
| gbk_chinese_ci       | gbk      |  28 | Yes     | Yes      |       1 | 
| gbk_bin              | gbk      |  87 |         | Yes      |       1 | 
| latin5_turkish_ci    | latin5   |  30 | Yes     | Yes      |       1 | 
| latin5_bin           | latin5   |  78 |         | Yes      |       1 | 
| armscii8_general_ci  | armscii8 |  32 | Yes     | Yes      |       1 | 
| armscii8_bin         | armscii8 |  64 |         | Yes      |       1 | 
| utf8_general_ci      | utf8     |  33 | Yes     | Yes      |       1 | 
| utf8_bin             | utf8     |  83 |         | Yes      |       1 | 
| utf8_unicode_ci      | utf8     | 192 |         | Yes      |       8 | 
| utf8_icelandic_ci    | utf8     | 193 |         | Yes      |       8 | 
| utf8_latvian_ci      | utf8     | 194 |         | Yes      |       8 | 
| utf8_romanian_ci     | utf8     | 195 |         | Yes      |       8 | 
| utf8_slovenian_ci    | utf8     | 196 |         | Yes      |       8 | 
| utf8_polish_ci       | utf8     | 197 |         | Yes      |       8 | 
| utf8_estonian_ci     | utf8     | 198 |         | Yes      |       8 | 
| utf8_spanish_ci      | utf8     | 199 |         | Yes      |       8 | 
| utf8_swedish_ci      | utf8     | 200 |         | Yes      |       8 | 
| utf8_turkish_ci      | utf8     | 201 |         | Yes      |       8 | 
| utf8_czech_ci        | utf8     | 202 |         | Yes      |       8 | 
| utf8_danish_ci       | utf8     | 203 |         | Yes      |       8 | 
| utf8_lithuanian_ci   | utf8     | 204 |         | Yes      |       8 | 
| utf8_slovak_ci       | utf8     | 205 |         | Yes      |       8 | 
| utf8_spanish2_ci     | utf8     | 206 |         | Yes      |       8 | 
| utf8_roman_ci        | utf8     | 207 |         | Yes      |       8 | 
| utf8_persian_ci      | utf8     | 208 |         | Yes      |       8 | 
| utf8_esperanto_ci    | utf8     | 209 |         | Yes      |       8 | 
| utf8_hungarian_ci    | utf8     | 210 |         | Yes      |       8 | 
| ucs2_general_ci      | ucs2     |  35 | Yes     | Yes      |       1 | 
| ucs2_bin             | ucs2     |  90 |         | Yes      |       1 | 
| ucs2_unicode_ci      | ucs2     | 128 |         | Yes      |       8 | 
| ucs2_icelandic_ci    | ucs2     | 129 |         | Yes      |       8 | 
| ucs2_latvian_ci      | ucs2     | 130 |         | Yes      |       8 | 
| ucs2_romanian_ci     | ucs2     | 131 |         | Yes      |       8 | 
| ucs2_slovenian_ci    | ucs2     | 132 |         | Yes      |       8 | 
| ucs2_polish_ci       | ucs2     | 133 |         | Yes      |       8 | 
| ucs2_estonian_ci     | ucs2     | 134 |         | Yes      |       8 | 
| ucs2_spanish_ci      | ucs2     | 135 |         | Yes      |       8 | 
| ucs2_swedish_ci      | ucs2     | 136 |         | Yes      |       8 | 
| ucs2_turkish_ci      | ucs2     | 137 |         | Yes      |       8 | 
| ucs2_czech_ci        | ucs2     | 138 |         | Yes      |       8 | 
| ucs2_danish_ci       | ucs2     | 139 |         | Yes      |       8 | 
| ucs2_lithuanian_ci   | ucs2     | 140 |         | Yes      |       8 | 
| ucs2_slovak_ci       | ucs2     | 141 |         | Yes      |       8 | 
| ucs2_spanish2_ci     | ucs2     | 142 |         | Yes      |       8 | 
| ucs2_roman_ci        | ucs2     | 143 |         | Yes      |       8 | 
| ucs2_persian_ci      | ucs2     | 144 |         | Yes      |       8 | 
| ucs2_esperanto_ci    | ucs2     | 145 |         | Yes      |       8 | 
| ucs2_hungarian_ci    | ucs2     | 146 |         | Yes      |       8 | 
| cp866_general_ci     | cp866    |  36 | Yes     | Yes      |       1 | 
| cp866_bin            | cp866    |  68 |         | Yes      |       1 | 
| keybcs2_general_ci   | keybcs2  |  37 | Yes     | Yes      |       1 | 
| keybcs2_bin          | keybcs2  |  73 |         | Yes      |       1 | 
| macce_general_ci     | macce    |  38 | Yes     | Yes      |       1 | 
| macce_bin            | macce    |  43 |         | Yes      |       1 | 
| macroman_general_ci  | macroman |  39 | Yes     | Yes      |       1 | 
| macroman_bin         | macroman |  53 |         | Yes      |       1 | 
| cp852_general_ci     | cp852    |  40 | Yes     | Yes      |       1 | 
| cp852_bin            | cp852    |  81 |         | Yes      |       1 | 
| latin7_estonian_cs   | latin7   |  20 |         | Yes      |       1 | 
| latin7_general_ci    | latin7   |  41 | Yes     | Yes      |       1 | 
| latin7_general_cs    | latin7   |  42 |         | Yes      |       1 | 
| latin7_bin           | latin7   |  79 |         | Yes      |       1 | 
| cp1251_bulgarian_ci  | cp1251   |  14 |         | Yes      |       1 | 
| cp1251_ukrainian_ci  | cp1251   |  23 |         | Yes      |       1 | 
| cp1251_bin           | cp1251   |  50 |         | Yes      |       1 | 
| cp1251_general_ci    | cp1251   |  51 | Yes     | Yes      |       1 | 
| cp1251_general_cs    | cp1251   |  52 |         | Yes      |       1 | 
| cp1256_general_ci    | cp1256   |  57 | Yes     | Yes      |       1 | 
| cp1256_bin           | cp1256   |  67 |         | Yes      |       1 | 
| cp1257_lithuanian_ci | cp1257   |  29 |         | Yes      |       1 | 
| cp1257_bin           | cp1257   |  58 |         | Yes      |       1 | 
| cp1257_general_ci    | cp1257   |  59 | Yes     | Yes      |       1 | 
| binary               | binary   |  63 | Yes     | Yes      |       1 | 
| geostd8_general_ci   | geostd8  |  92 | Yes     | Yes      |       1 | 
| geostd8_bin          | geostd8  |  93 |         | Yes      |       1 | 
| cp932_japanese_ci    | cp932    |  95 | Yes     | Yes      |       1 | 
| cp932_bin            | cp932    |  96 |         | Yes      |       1 | 
| eucjpms_japanese_ci  | eucjpms  |  97 | Yes     | Yes      |       1 | 
| eucjpms_bin          | eucjpms  |  98 |         | Yes      |       1 | 
+----------------------+----------+-----+---------+----------+---------+
126 rows in set (0.00 sec)


以上、使用頻度が少なくてよく忘れるのでブログにメモでした。

より詳しくはMySQL :: MySQL 5.1 リファレンスマニュアル :: 9.3 デフォルトのキャラクタセットおよび照合順序の指定をどうぞ。

2010年07月26日

ブログ書けない病

というのにかかったようです。途中まで書いた下書きが結構溜まってますが、なんとなく公開する気になれません。

そんだけ。

2010年07月13日

DOMモジュールをテンプレートエンジン代わりに使う三つの利点+1

PHP5からPHP標準添付のDOMモジュールもlibxml2ベースのものになって、htmlも処理できるようになったのでだいぶ使いやすくなったと思う。DOMを使うと文書構造にアクセスして編集できるので、テンプレートエンジンの代わりとしてそれなりに利用されてても良いと思うんだけど少なくとも個人的観測範囲内だと全ったくもって流行ってなかったりして*1大変残念なので、PHPDOMモジュールテンプレートエンジン代わりに使う利点をまとめてみました。



1.インスコ不要

最初に書いたけど、PHP5のDOMモジュールインスコしなくても標準で使える。もう少し具体的に言うと--disable-dom configureオプションを付けてビルドしてなかったら使える、ってことなのでその辺のレン鯖でも普通は動くので便利です。

インスコ不要なものはデプロイするときに「あれ入れた?」「忘れたー」「あれは入れた?」「忘れたー」「あっちは」「うーん知らない」「氏ね」ループに陥らなくて精神的に大変よろしいと思います。



2.デザイナー/コーダーへの説明が楽

どのテンプレートエンジンにしろ、だいたいそれ用の構文があったりします。無いやつもあるけどだいたいあります。特にSmartyとか人気のやつはだいたいあります。

いずれにしてもテンプレートエンジンを使うとなったら、「ここはテンプレートエンジンの構文なんで変えないでくださいね」「そこも同じなんで以下同文」「あーそれも同じなんで以下同文」「だからそこ変えるんじゃねーよボケ」という不毛な説明を延々と繰り返すハメになることを覚悟する必要がある。世の中には大変素晴らしい企業さんもあるようで、そういう説明が要らないところもあるみたいですが、うち場合デザイナーがいない上、デザイナー/コーダー=お客さんってプロジェクトが大半なので、単に可否の問題でなく営業的な問題であまりこの辺を強く言えない事情もあったりします。なので物分かりのあまり良くないお客さんの場合は延々と不毛な説明するとかえってややこしいので、htmlもらってこっちでテンプレートに変換する退屈な作業を延々と繰り返してます。

でもDOMなら不毛な説明も退屈な作業も不要。id属性とかclass属性とか、テンプレートとして使用する要素がhtmlそのものなので向こうも分かるはず。さすがにこの程度も分からない奴とは一緒に仕事できないのです。



3.DOMなんで覚えるのも簡単

DOMなんでJavaScriptかじってたら多少は知ってるはず・・・て言うかウェブ関係のプログラミングやってれば知らないのはかなり問題。知らんと思ってる人もgetElementByIdとかcreateElementとかがDOMだと言われれば「へぇー、これって2年くらい前に流行ってたよね、2年くらい前に見たわ」と返事してくれることでしょう。

という感じでたぶんDOM自体は知ってると思うので、簡単なサンプルも載せときます。


まずテンプレートとしてexam1.htmlを作ります。モジュールの仕様の関係で、doctypeとmetaタグによるcharsetの指定を省略すると挙動が変わるので省略しないように。

<!doctype HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  </head>
  <body>
    <div id="message"></div>
  </body>
</html>

次にexam1.htmlを読み込んでid="message"のdivの中身を"あいうえお"に書き換えるスクリプトを作ります。

<?php
$doc = new DOMDocument();
$doc->loadHTMLFile("exam1.html");
$message = $doc->getElementById("message");
$message->appendChild($doc->createTextNode("あいうえお"));
echo $doc->saveHtml();
?>

このスクリプトを動かすと以下の出力が得られます。

<!DOCTYPE HTML>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
<body>
    <div id="message">あいうえお</div>
  </body>
</html>

ところどころ改行とスペースが詰められるは、まあそういう仕様なんで諦めてください。スペース入れたいときは&nbsp;使った方が良いですよ、ということです。

もっと詳しいことはPHP: DOM - Manualからどうぞ。



+1.ドキュメントに直接アクセスできる

うちだけの話かもしれないので+1にしたけど、例えばhtmlフォームのラベルとか、ユーザーなんだかデザイナーなんだかよく分からない人が適当にいじくりたいという要望がたまにあります。それでまあフォームの場合、そのラベルをエラーメッセージに埋め込みたいとか言う話になるので、コンフィギュレーションファイルを用意したり結局プログラムで二重持ちしたりしてることがありますが、色々なやましい問題がこの辺で噴出します。

そこでDOMの出番ですよ、と。テンプレートDOMにしとけば、htmlから適当な要素の値を抜いてくれば良いだけですので、この手の問題は全部解決です。


例えばこんな感じのexam2.htmlがあって、

<!doctype HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p id="error" style="display:none"></p>
    <form method="post">
      <label for="username">ユーザー</label>
      <input type="text" id="username" name="username" />
      <input type="submit" />
    </form>
  </body>
</html>

usernameが未入力ならlabelを含んだエラーメッセージを表示する場合はこんなスクリプトで解決できます。

<?php
$doc = new DOMDocument();
$doc->loadHTMLFile("exam2.html");
if (isset($_POST['username']) && !$_POST['username']) {
    $username = $doc->getElementById('username');
    $labels = $doc->getElementsByTagName('label');
    for ($i = 0; $i < count($labels); $i++) {
        $label = $labels->item($i);
        if ($label->getAttribute('for') == $username->getAttribute('id')) {
            $mesg = "{$label->textContent}が未入力です。";
            $error = $doc->getElementById('error');
            $error->removeAttribute('style');
            $error->appendChild($doc->createTextNode($mesg));
            break;
        }
    }
}
echo $doc->saveHtml();
?>

エラーメッセージを含む出力はこんな感じ。ちゃんとメッセージにlabel for="username"の値が表示されます。

<!DOCTYPE HTML>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
<body>
    <p id="error">ユーザーが未入力です。</p>
    <form method="post">
      <label for="username">ユーザー</label>
      <input type="text" id="username" name="username"><input type="submit">
</form>
  </body>

</html>


ということで、騙されたと思って一度騙されてください。

*1DOMテンプレート代わりに使うといったことを書いてるブログは確認してますが、流行ってないってところに力点置いてます

2010年05月12日

WordPress3.0の最も重要な5つの新機能

WordPress 3.0: The 5 Most Important New FeaturesにてWordPress3.0の新機能が紹介されていましたので、ざっくりご紹介させて頂こうと思います。


1. Custom Post Types

By default, WordPress lets you publish two types of content: “Posts” and “Pages.” In version 3.0, you can define additional content types with their own attributes. For example, if you’re running a WordPress site for a design agency, you might create a custom post type to display portfolio items, another for employee pages, and another for client testimonials. From there, you can customize your theme to better suit each individual post type.

WordPress 3.0: The 5 Most Important New Features

現在のWordPressで投稿できるのは、Posts(通常のブログ記事)とPages(ブログと別扱いの固定ページ)の二種類ですが、WordPress3.0ではユーザーが定義した種類のコンテンツも投稿できるようになるそうです。テーマをコンテンツの種類ごとにカスタマイズできるようになるとのことで、サイト構築の楽しみが広がりそうです。


2. Menu Management

Menu management is one of the most exciting and talked about features in WordPress 3.0. This feature gives you full control over your site’s navigation menus. With an easy drag and drop interface, users can create menus that include any mixture of links to internal pages, external URLs, categories, you name it. Then you can embed these custom menus as a widget wherever your theme allows.

WordPress 3.0: The 5 Most Important New Features

「メニュー管理は最も刺激的で多くの人の話題に登ったWordPress3.0の機能」だそうです。なんか盛り上がってますねw

WordPress3.0では、(jQueryを使った)ドラッグアンドドロップUIで、サイドメニューの管理が完全に行えるようになるようです。2.8辺りでサイドバーウィジェットはだいぶ使いやすくなったと思いますが、細かい制御のためにテキストウィジェットを入れまくってる方も多いのではないでしょうか。この辺の管理が楽になるのは期待ですね。

元記事の方にメニュー管理ページのキャプチャがありますので、興味ある方はご覧ください。


3. Custom Taxonomies

While this new feature may seem a bit complex to non-developers, it certainly brings WordPress 3.0 closer to a true CMS. Custom taxonomies allow you to create additional pieces of meta information. By default, there are “Categories” and “Tags.” Now we can add additional types, with the option of being hierarchical or not.

WordPress 3.0: The 5 Most Important New Features

メタ情報としてカテゴリとタグ以外のユーザー定義タクソノミを使用できるようになるようです。個人的にはタグ以外は邪魔なので要らないとか思ってたりするのですが、

Let’s say you’re a film fanatic and you use your WordPress blog to post reviews and rate new movies. You can create a custom taxonomy for “Rating (Rating),” then add R, PG-13, PG, G to every review.

WordPress 3.0: The 5 Most Important New Features

もしあなたが熱狂的な映画ファンで、WordPressを使って新作映画のレビューとレイティングをしたいとしましょう。カスタムタクソノミとして"Rating"を作成し、R、PG-13、PG、Gといったレーティングををすべてのレビューに付けることができます。

とのように、WordPressを本当のCMSにするためにこの機能が必要なのだそうです。


4. New Default Theme: “Twentyten”

Twentyten is the long-overdue default theme packaged with new installations of WordPress 3.0.

WordPress 3.0: The 5 Most Important New Features

新しいデフォルトテーマとして"Twentyten"が採用されます。こちらについては、四の五の言うよりもキャプチャを見てもらった方が早いでしょう。

f:id:xmalloc:20100512011402j:image

http://ja.blog.wordpress.com/2010/04/27/new-theme-twenty-ten/

シンプルでカッコいいテーマですね。Twentytenの作者のMatt Thomasによるテーマの紹介記事の和訳がhttp://ja.blog.wordpress.com/2010/04/27/new-theme-twenty-ten/にありますので、詳しくはそちらをどうぞ。


5. Multi-site

You can’t discuss WordPress 3.0 without mentioning the new multi-site capabilities. That is, you can manage several different websites (with different domains and/or sub-domains) all with a single installation of WordPress. What was previously known as WordPress MU (Multi-User) is now merged with the core WordPress system in 3.0. Enabling multi-site capabilities likely isn’t something for the average user, as it requires some tinkering with the code and configuring server settings. That said, the average user likely isn’t interested in having multi-site capabilities.

WordPress 3.0: The 5 Most Important New Features

WordPress MUの機能が3.0にマージされたようで、一度インストールすれば同じサーバ上に複数のドメイン/サブドメインのWordPressインスタンスを立ち上げれるとのことです。ちょうどMUを試してみようと思っていたのですが、3.0のリリースを待つことにします。



現在WordPress3.0はBeta2の状態です。正式リリースが待ち遠しいですね。

2010年05月10日

システム開発の生産性向上に必要なのはとりあえず仕様変更は断るという空気

冷静に考えたら一日8時間勤務って正気の沙汰じゃないよな 働くモノニュース : 人生VIP職人ブログwww見てたらこんなことが書いてあった。

226 名前: アカザ(不明なsoftbank):2010/05/10(月) 09:24:37.48 ID:/PwxzPkK

これはシステム開発限定の話だが、

海外の場合、最初にどのようなソフトを作るか完全に決めてから作る。

開発中に仕様を変更するような事はしない。

日本の場合、作っている最中にどんどん仕様が変更されていく。

せっかく作っても、その部分を削って別の物を作るため、生産性は下がり、

納期に間に合わせるために一日の労働時間が長くなる。

http://workingnews.blog117.fc2.com/blog-entry-2823.html

海外のことはよく分からないけど*1、仕様変更がよくあることや、それで生産性が下がることは実感としてあります。で、仕様変更が起こらないようにするにはどうすればいいかと考えてみたら、「仕様変更?ありえねーwww」と気軽に言える空気があれば解決するんじゃないかと思うようになりました。以下、その考えるに至った経緯。

  1. 仕様変更を発生させるのはお客さん。お客さんが仕様変更を発生させるのは、お客さんにシステム開発の知識が不足してるから
  2. ならお客さんを、仕様変更が発生したら開発に支障を来すってことを教育すればいいよね
  3. ただ教育が必要みたいなことは前から言われてるけどできてない。お客さん側を変えるのは現実的に困難っぽいから、開発側でなんとかしないといけない
  4. と言っても(教育が無理な以上)お客さんから仕様変更が発生すること自体に変化はないから、できることは仕様変更を断るだけ
  5. そういえば、仕様変更が断りにくいのって何で?
  6. 営業的な理由とか?断ったら次の仕事貰えなくなるかもしれないし
  7. 社内的圧力とか?営業的な理由とだいたい同じだねこれ
  8. いずれにしても「とりあえず断る」って選択肢はあんまり無いよね・・・選択肢っていうか、条件反射的にどう反応するかの問題のような気もするし、「とりあえず断る」って空気になればみんな断るんじゃねーの?
  9. までも「とりあえず断る」だけじゃ営業的な理由が解決できないな。「とりあえず断る」のを難しくしてるのはひどい案件でも請けちゃう同業者がいるからだろう
  10. その辺は生産性を価格競争力とかに転嫁して同業者と勝負←今ここ

仕様変更を断ると生産性があがる、生産性が上がれば会社自体の競争力は強まる。ここまでは話の流れとして問題は無いと思うのですが、よく考えてみればその競争力を生かせる人材が営業方面にいるかどうかも問題になるかもしれません。「細かい仕様変更を受けます」というのが唯一の売りになってるような会社もありますし、顧客側からそういったことを求められることも往々にしてあります。私自身もその辺を断っていたら仕事にならないという考えも無いこともないです。そこは価格競争力でどうこうという話になるのでしょうが、価格を下げるには受注量を増やさないといけないのですが、うちみたいな中小零細でそんな戦略取れるのかね・・・という気もしてきましたのでもうちょっと考えますが、深く考えずに仕様変更を受けてるような気がそこはかとなくしてます。

私の会社の問題は別途検討するとして、業界全体で仕様変更はとりあえず受けないというのが常識になってもらうっていうのも良さそうです。「仕様変更しろ」→「お断りします」→「なら他に頼むぞ!」→「どうぞどうぞ」→「他も受けてくれましぇ〜ん」みたいな流れが普通になる、で全然問題ないんですけど。


いずれにしても、仕様変更を断ることを積極的に考えないといけないような気がします。知ってる限りじゃ無茶な仕様変更はデスマで応えるというのが一般的だと思うのですが、結局それは社員に無茶させてるだけですし、サービス残業じゃなくて普通に残業扱いにしてるところだと赤字になる訳ですし。

デスマ前提の無茶な要求を受け入れる、ってのは会社がそういった体制になってると思います。開発だけじゃなくて経営や営業とかがそういう流れの中で仕事を動かしてるからデスマになる。デスマさせたらPMにペナルティ付くような会社とかだと、会社全体がデスマしない方向で仕事を動かしてるはずです・・・そんな会社実在するのかどうか分からないので「あったら」の話ですがw

いずれにしても仕様変更を受けないためにはそれなりの体制が必要、それなりの体制ってのは単に「会社内の常識がそうなってる」っていうだけでもいいんじゃないの?というのが言いたいことでした。

*1:よく分からないというか、海外でも仕様変更とかそれなりにあるんじゃねーの?と思ってたので