今年は、波乱の多い年でした。
プロジェクトが途中分解してしまい、次が決まらない初めての待機期間もありました。
下半期には仕事が増えるいう噂を信じてましたが、反対に減っている現実。政権が変わることで逆に冷えてしまったようです。
今では、「後数年は悪化し続ける」と云う人が増加している現実。うー。寒。 皆様も風邪を召さないように気を付けて下さい。
それにしても、大手Sierが内製モードに入ったけれど、人の管理スキルは高いけれども、開発スキルが不足して、品質に悪影響しているという、現場の悲鳴が聞こえてくる昨今です。
IT業界だけ発展することはあり得ません。ITは産業の縁の下の道具に過ぎません。基幹業務が発展してこそのIT業界です。
一介の開発者が叫んでも時代の流れは変わらないかもしれませんが、叫ばないと尚更変わりません。
開発スタイルが大きく変わりそうなIT業界なのに、受け入れる社会構造が不調ならば、真価を発揮ないで終焉するかも知れません。
技術史とはそういうものかも。時代の景気の歯車と噛み合わ無ければ、良い物でも日の目をみないのかもしれません。
逆に、劣っているものでも時代の波に乗れば、スターダムに乗れます。技術者は、時代を読む目も必要だと思います。
来年は少なくとも前に進む事を願います。
2009/12/28
CodeDom プロバイダ型....を読み込めませんでした
asp.netアプリをコーディング中に、
「CodeDom プロバイダ型 "Microsoft.VJSharp.VJSharpCodeProvider, VJSharpCodeProvider, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" を読み込めませんでした。」
というエラーが出て、コンパイル不能状態に陥りました。
File/行/列の各欄がブランクのエラー報告なので、システム設定周りだと思い、調査する事に....
おかしなことに、同じソースを実行しても、上手く動作するときも有ります。
このプログラムは、ソース生成器の機能を持つのですが、特定データを処理した後のコンパイルで上記のメッセージがでて、コンパイル不能に陥ります。
うーん。謎は深まる。Compilerが読み込めない状況って、何だろう。
ソースの生成先は、同じアプリと同じ仮想フォルダー(~/data/temp/)に作成する仕様になっています。
データに依存するのでは...と追跡してみると。 「xxxx.java] と言う名前のFileを吐き出した後に、不能に陥ることが判りました。
だから 「VJ-compilerが読み込めない」になるんだ。原因は納得。
ソース生成器として、「java」ソースを書き出すときは、要注意です。
プロジェクトフォルダー以外のフォルダーに書き出せば回避できますが、レンタルサーバーの場合は、それもできません。
折角、クラスモジュールは{App_Code}で一本化しているのだから、データ用に {App_Data}を設定しておいて、その下では、拡張子は不問としてくれたら、スッキリするのですが。
それ以前に、aps.net(2008)は VB/C#の二種類しかないので、 .javaを言語ソースとみなすのは、不合理だと思う。
(*)このことで、数時間潰れたことは内緒です.....orz;
「CodeDom プロバイダ型 "Microsoft.VJSharp.VJSharpCodeProvider, VJSharpCodeProvider, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" を読み込めませんでした。」
というエラーが出て、コンパイル不能状態に陥りました。
File/行/列の各欄がブランクのエラー報告なので、システム設定周りだと思い、調査する事に....
おかしなことに、同じソースを実行しても、上手く動作するときも有ります。
このプログラムは、ソース生成器の機能を持つのですが、特定データを処理した後のコンパイルで上記のメッセージがでて、コンパイル不能に陥ります。
うーん。謎は深まる。Compilerが読み込めない状況って、何だろう。
ソースの生成先は、同じアプリと同じ仮想フォルダー(~/data/temp/)に作成する仕様になっています。
データに依存するのでは...と追跡してみると。 「xxxx.java] と言う名前のFileを吐き出した後に、不能に陥ることが判りました。
だから 「VJ-compilerが読み込めない」になるんだ。原因は納得。
ソース生成器として、「java」ソースを書き出すときは、要注意です。
プロジェクトフォルダー以外のフォルダーに書き出せば回避できますが、レンタルサーバーの場合は、それもできません。
折角、クラスモジュールは{App_Code}で一本化しているのだから、データ用に {App_Data}を設定しておいて、その下では、拡張子は不問としてくれたら、スッキリするのですが。
それ以前に、aps.net(2008)は VB/C#の二種類しかないので、 .javaを言語ソースとみなすのは、不合理だと思う。
(*)このことで、数時間潰れたことは内緒です.....orz;
2009/12/26
染料と顔料
インクジェット・プリンターの中には、黒インクを二種類搭載していて、染料と顔料の二種類を使い分ける機種があります。
染料と顔料の違いは、大雑把に言えば、粒の大きさの違いで、水に溶けて同化している染料と、溶けずに粒子状で存在する顔料ということになります。
(*)違いはわかるのですが、二種類搭載する必然性の説明にはなりません。感覚的には、RGBインクと同様に1種類の黒で良いような気もします。
色で染めるのだから「染」料= 染料は判ります。でも、粒が大きい材料=>「顔」料となるのが判らない。顔が大きいのではなさそうです。
陶器と磁器も、土を焼いて作るのは同じですが、
バクテリア作用でねばり気をおびた「陶土」を焼いて作るか
細かく砕けた石が、バクテリアなどの作用で粘土質になった「磁土」を焼いて作るかの違いがあります。
でも、粘土質になったものを「磁」土とするのが判らない。
「磁」がつくと「電磁波」が浮かび、波動物理や磁石/磁力を連想してしまいます。
顔料と「顔」、磁器と「磁力」は無援です。でも字面は共通です。あー・ややこしい。
染料と顔料の違いは、大雑把に言えば、粒の大きさの違いで、水に溶けて同化している染料と、溶けずに粒子状で存在する顔料ということになります。
(*)違いはわかるのですが、二種類搭載する必然性の説明にはなりません。感覚的には、RGBインクと同様に1種類の黒で良いような気もします。
色で染めるのだから「染」料= 染料は判ります。でも、粒が大きい材料=>「顔」料となるのが判らない。顔が大きいのではなさそうです。
陶器と磁器も、土を焼いて作るのは同じですが、
バクテリア作用でねばり気をおびた「陶土」を焼いて作るか
細かく砕けた石が、バクテリアなどの作用で粘土質になった「磁土」を焼いて作るかの違いがあります。
でも、粘土質になったものを「磁」土とするのが判らない。
「磁」がつくと「電磁波」が浮かび、波動物理や磁石/磁力を連想してしまいます。
顔料と「顔」、磁器と「磁力」は無援です。でも字面は共通です。あー・ややこしい。
2009/12/24
牛丼の味
世の中デフレだそうで、ファストフードが混んでます。
仕事関係の人と吉野屋に入ったとき、その人が「牛丼は吉野屋に限る。なか卯や松屋の牛丼は食べれない」(固有名詞ごめんなさい)と宣います。
私は、すき家も松屋も吉野屋も美味しさの違いが判りません。指摘されたら、味が違うような気がしますが、目隠しして利き飯(?)したら区別が付かないです。
その人は、言い当てる自信があるそうです。
300円と比較すれば、何れの牛丼も美味しいと思うのです。今は潰れて存在しませんが、大阪には「ビックリラーメン」なるものがあり、1杯180円のラーメンチェーン店がありました。(価格でビックリから命名)
7~900円のラーメンと比べると貧弱ですが、180円として味わうと、美味しかったです。
価格を基準にして、コストパフォーマンスで判断する私、安いだけでは食べない人、同じ帯域の商品なら質で判断する人(これが普通か)
物の評価基準は複数あるのだなぁ。と改めて思ったしだい。
(*)その前に、吉野屋、なか卯、松屋、すき家、各店牛丼が同じ味に感じる私の味覚に問題があるかも知れませんね。
仕事関係の人と吉野屋に入ったとき、その人が「牛丼は吉野屋に限る。なか卯や松屋の牛丼は食べれない」(固有名詞ごめんなさい)と宣います。
私は、すき家も松屋も吉野屋も美味しさの違いが判りません。指摘されたら、味が違うような気がしますが、目隠しして利き飯(?)したら区別が付かないです。
その人は、言い当てる自信があるそうです。
300円と比較すれば、何れの牛丼も美味しいと思うのです。今は潰れて存在しませんが、大阪には「ビックリラーメン」なるものがあり、1杯180円のラーメンチェーン店がありました。(価格でビックリから命名)
7~900円のラーメンと比べると貧弱ですが、180円として味わうと、美味しかったです。
価格を基準にして、コストパフォーマンスで判断する私、安いだけでは食べない人、同じ帯域の商品なら質で判断する人(これが普通か)
物の評価基準は複数あるのだなぁ。と改めて思ったしだい。
(*)その前に、吉野屋、なか卯、松屋、すき家、各店牛丼が同じ味に感じる私の味覚に問題があるかも知れませんね。
2009/12/22
LEDテレビとLED電球
薄型テレビは液晶型とプラズマ型の二種類だと、思っていたところに、LED型薄型テレビのCMが目につきました。
LEDは発光型の半導体なので、液晶に変わるものかと早合点しそうになりましたが、液晶のバックライトにLEDを使うという話なのね。
なので、液晶型の性能に依存するのでしょうね。
LED型電球も普及期に入りかけてますが、単価は結構高いです。吹き抜け天井の電球の交換に手間が掛かるので、LED型に変えれば助かるんでしょうが、価格面で二の足を踏んでます。
いままでの経験から、普及すれば価格が低下すると思われますので尚更です。踏ん切りを付ける時期は難しいですね。
LED電球は10年以上持つと言われていますが、製品ができて、日数が経っていないのに10年持つと言えるのかなぁ。
写真のCMで100年プリントというのがむありました。
このようなxx年間大丈夫というCMは、実測値でないので、データ的にはそうでしょうが、信憑性が伝わらないのは私が捻くれているからか?
電球の寿命は当たり外れが多く、同時期に交換しても半年で切れる球や3年持つ球もあります。幸運・不運があるのでしょうね。
でもLED電球は魅力的だなぁ。
LEDは発光型の半導体なので、液晶に変わるものかと早合点しそうになりましたが、液晶のバックライトにLEDを使うという話なのね。
なので、液晶型の性能に依存するのでしょうね。
LED型電球も普及期に入りかけてますが、単価は結構高いです。吹き抜け天井の電球の交換に手間が掛かるので、LED型に変えれば助かるんでしょうが、価格面で二の足を踏んでます。
いままでの経験から、普及すれば価格が低下すると思われますので尚更です。踏ん切りを付ける時期は難しいですね。
LED電球は10年以上持つと言われていますが、製品ができて、日数が経っていないのに10年持つと言えるのかなぁ。
写真のCMで100年プリントというのがむありました。
このようなxx年間大丈夫というCMは、実測値でないので、データ的にはそうでしょうが、信憑性が伝わらないのは私が捻くれているからか?
電球の寿命は当たり外れが多く、同時期に交換しても半年で切れる球や3年持つ球もあります。幸運・不運があるのでしょうね。
でもLED電球は魅力的だなぁ。
2009/12/19
先行の貨物列車が遅れたので当列車は6分遅れています。
JRに乗ったとき、5~10分ダイヤが乱れてました。そのとき社内放送で、タイトルの放送がありました。
「なんか、違うぞ」という感じがしました。(*)私の個人的な感覚なので、同意の方はいないかもしれません。
この言い方だと、遅れた責任は「貨物列車」にあるように受け止めたのです。「貨物列車」はなんらかの理由で遅れたのでしょう。
降車駅の掲示板によると、ある踏切が故障か無謀横断で降りた状態になって解除できなかったようです。
「貨物列車」は濡れ衣を着せられたと感じたのです。
車両内で子供が暴れているとき「暴れちゃ駄目。隣のおじさんに怒られるよ」と叱っているのも違和感があります。
「xxxだからyyyしてはいけない」「xxxだからyyyになった」と因果関係を明確にするべきでしょう。
「なんか、違うぞ」という感じがしました。(*)私の個人的な感覚なので、同意の方はいないかもしれません。
この言い方だと、遅れた責任は「貨物列車」にあるように受け止めたのです。「貨物列車」はなんらかの理由で遅れたのでしょう。
降車駅の掲示板によると、ある踏切が故障か無謀横断で降りた状態になって解除できなかったようです。
「貨物列車」は濡れ衣を着せられたと感じたのです。
車両内で子供が暴れているとき「暴れちゃ駄目。隣のおじさんに怒られるよ」と叱っているのも違和感があります。
「xxxだからyyyしてはいけない」「xxxだからyyyになった」と因果関係を明確にするべきでしょう。
2009/12/17
本屋もポイントカード
最近はポイントカードやマイレージカードを取り入れた店が増殖していますね。
カード類が増えて管理仕切れない現実です。
大阪駅前の旭屋がポイントカードを採用しました。1%還元のようです。
Book Oneでは5,000円以上の買い物で喫茶店での飲み物券が貰えます。これだと5%還元ですね。(原価でみれば違いますが)
ジュンク堂では10,000円以上でコーヒーが飲めます。2.5%還元になりますね。損得で見れば飲み物が有利ですが、現金が貯まるほうが良いのかも。
ポイント還元は、東京文化だと聞きました。大阪文化は、現金値引きでした。大阪本拠の家電量販店でも現金値引き交渉が有ったのですが、ボイントの店になってからは、値引き交渉が減ったとか。
この面でも、大阪文化が衰退するのかなぁ。
ボイント制度は、リピート客や囲い込みが狙いなんでしょうね。ボイント蓄積したカードが使わないで眠っているのも多々ありそうです。その分も収益計算しているのかな。
そういえば、携帯普及以前にテレフォンカードが氾濫していたとき、使わないで死蔵されたカードが多数あり、結果としてNTTの収益になったとか。
本の価格は再販制度で決められいます。これ自体の廃止論や是非論はありますが、価格維持を前提としている制度の元の本屋さんで、
ポイントカードを発行が、再販制度を崩す「蟻の一穴」になる危惧はないのでしょうか。
大型書店が乱立していますが、共倒れにならないのが不思議です。街角の小さな本屋さんも健在ですし、不思議な業界に見えます。
カード類が増えて管理仕切れない現実です。
大阪駅前の旭屋がポイントカードを採用しました。1%還元のようです。
Book Oneでは5,000円以上の買い物で喫茶店での飲み物券が貰えます。これだと5%還元ですね。(原価でみれば違いますが)
ジュンク堂では10,000円以上でコーヒーが飲めます。2.5%還元になりますね。損得で見れば飲み物が有利ですが、現金が貯まるほうが良いのかも。
ポイント還元は、東京文化だと聞きました。大阪文化は、現金値引きでした。大阪本拠の家電量販店でも現金値引き交渉が有ったのですが、ボイントの店になってからは、値引き交渉が減ったとか。
この面でも、大阪文化が衰退するのかなぁ。
ボイント制度は、リピート客や囲い込みが狙いなんでしょうね。ボイント蓄積したカードが使わないで眠っているのも多々ありそうです。その分も収益計算しているのかな。
そういえば、携帯普及以前にテレフォンカードが氾濫していたとき、使わないで死蔵されたカードが多数あり、結果としてNTTの収益になったとか。
本の価格は再販制度で決められいます。これ自体の廃止論や是非論はありますが、価格維持を前提としている制度の元の本屋さんで、
ポイントカードを発行が、再販制度を崩す「蟻の一穴」になる危惧はないのでしょうか。
大型書店が乱立していますが、共倒れにならないのが不思議です。街角の小さな本屋さんも健在ですし、不思議な業界に見えます。
2009/12/15
郵便番号簿のBulk Merge 取り込みと、 都道府県コード表作成のまとめ
数回に渡って郵便番号CSV Fileから47レコードの 都道府県コード表を作成するコストを書きました。
その都度、テストに使ったDBサーバーやクライアント端末が異なっていて、結果に一貫性がなかったのと、発端になった非推奨ソースがイビツだったことによりスッキリしない部分がありました。
今回の纏めでは、郵便番号CSV全件(郵便番号の重複を解消した自前の補正後データ: 118822件)を入力とします。
①全件作成
A:Bulk Merge で全件作成
MERGE INTO z_郵便番号 A USING OPENROWSET( BULK '補正郵便番号.CSV' ,FORMATFILE = '郵便番号.fmt' ) B
ON A.郵便番号 = B.郵便番号
WHEN MATCHED THEN UPDATE SET A.全国地方公共団体コード = B.全国地方公共団体コード,.....
WHEN NOT MATCHED THEN INSERT VALUES ( B.郵便番号 ,..........);
B: 言語でLoopで回す
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
項目移送()
Insert文実行()
}
sr.Close();
② なければ挿入式で 47行の都道府県表を作る
結果: Debugモード Releaseモード
①
A: 5秒 5秒
B: 91秒 89秒
改めて、Bulkモードの早さに驚いてます。約18倍の差。
言語で回せば 91秒/118822件= 0.76 mSecなのでそこそこの速度。
Bulkだと 5秒/118822件= 0.042mSec...これは早い。 挿入更新をバッチ化する価値は高そう。(トランザクションの関係で別も問題は発生しますが)
DebugモードとReleaseモードの差はないようです。
②-A
発端となったソースロジックでなく、テスト用に書き換えました。
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
try
{
Insert文実行()
}
catch{} ;/重複例外握りつぶし
}
sr.Close();
Debugモード Releaseモード
5492秒 395秒
以前と同様に高コストでしたが、 Relaseモードはまだましですね。Debugモードでの例外扱いが、如何に高く付くかが判りました。
②-B Select文で自前制御
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
try
{
int rc=(select Count(*) where ユニーク条件)
if(rc==0)
{
insert文実行()
}
}
}
sr.Close();
Debugモード Releaseモード
77秒 70秒
なぜか、DebugモードとReleaseモードに差がでました。
②-D のストアード利用より、低コストの結果がでたので以外でした。
②-C 自前でチェック用Hashで制御
if (!自前で重複チェック_DICT.ContainsKey(名))
{
自前で重複チェック_DICT.Add(名, 名);
Insert文発行()
}
Debugモード Releaseモード
2秒 2秒
②-D ストアードでノーマル処理:(挿入のみで更新はしないので Select文で判断)
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
try
{
declare @cnt int;
select @cnt = count(*) from J01_都道府県表 where 都道府県コード=@cd and 都道府県名称=@名称;
if @cnt=0
begin
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
end
}
}
sr.Close();
Debugモード Releaseモード
131秒 129秒
②-E ストアードで例外期待処理:
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
try
{
BEGIN TRY
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
END TRY
BEGIN CATCH
NOP
End CATCH
}
}
sr.Close();
Debugモード Releaseモード
175秒 172秒
ストアードの例外コストは低そうです。
こうやって見ると、データの特性によって、手法の在り方が変わるので、教科書的正解って見つからないのかも知れませんね。
RDBに任すのが正解とは限りませんね。ロジックで最速化を図った上で、DB操作するのが良いようです。
可読性が悪くなるという意見も聞こえて来そうですが。
その都度、テストに使ったDBサーバーやクライアント端末が異なっていて、結果に一貫性がなかったのと、発端になった非推奨ソースがイビツだったことによりスッキリしない部分がありました。
今回の纏めでは、郵便番号CSV全件(郵便番号の重複を解消した自前の補正後データ: 118822件)を入力とします。
①全件作成
A:Bulk Merge で全件作成
MERGE INTO z_郵便番号 A USING OPENROWSET( BULK '補正郵便番号.CSV' ,FORMATFILE = '郵便番号.fmt' ) B
ON A.郵便番号 = B.郵便番号
WHEN MATCHED THEN UPDATE SET A.全国地方公共団体コード = B.全国地方公共団体コード,.....
WHEN NOT MATCHED THEN INSERT VALUES ( B.郵便番号 ,..........);
B: 言語でLoopで回す
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
項目移送()
Insert文実行()
}
sr.Close();
② なければ挿入式で 47行の都道府県表を作る
結果: Debugモード Releaseモード
①
A: 5秒 5秒
B: 91秒 89秒
改めて、Bulkモードの早さに驚いてます。約18倍の差。
言語で回せば 91秒/118822件= 0.76 mSecなのでそこそこの速度。
Bulkだと 5秒/118822件= 0.042mSec...これは早い。 挿入更新をバッチ化する価値は高そう。(トランザクションの関係で別も問題は発生しますが)
DebugモードとReleaseモードの差はないようです。
②-A
発端となったソースロジックでなく、テスト用に書き換えました。
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
try
{
Insert文実行()
}
catch{} ;/重複例外握りつぶし
}
sr.Close();
Debugモード Releaseモード
5492秒 395秒
以前と同様に高コストでしたが、 Relaseモードはまだましですね。Debugモードでの例外扱いが、如何に高く付くかが判りました。
②-B Select文で自前制御
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
try
{
int rc=(select Count(*) where ユニーク条件)
if(rc==0)
{
insert文実行()
}
}
}
sr.Close();
Debugモード Releaseモード
77秒 70秒
なぜか、DebugモードとReleaseモードに差がでました。
②-D のストアード利用より、低コストの結果がでたので以外でした。
②-C 自前でチェック用Hashで制御
if (!自前で重複チェック_DICT.ContainsKey(名))
{
自前で重複チェック_DICT.Add(名, 名);
Insert文発行()
}
Debugモード Releaseモード
2秒 2秒
②-D ストアードでノーマル処理:(挿入のみで更新はしないので Select文で判断)
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
try
{
declare @cnt int;
select @cnt = count(*) from J01_都道府県表 where 都道府県コード=@cd and 都道府県名称=@名称;
if @cnt=0
begin
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
end
}
}
sr.Close();
Debugモード Releaseモード
131秒 129秒
②-E ストアードで例外期待処理:
StreamReader sr = new StreamReader(CSV-file)
while (true)
{
string text = sr.ReadLine(); if (text == null) break;
try
{
BEGIN TRY
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
END TRY
BEGIN CATCH
NOP
End CATCH
}
}
sr.Close();
Debugモード Releaseモード
175秒 172秒
ストアードの例外コストは低そうです。
こうやって見ると、データの特性によって、手法の在り方が変わるので、教科書的正解って見つからないのかも知れませんね。
RDBに任すのが正解とは限りませんね。ロジックで最速化を図った上で、DB操作するのが良いようです。
可読性が悪くなるという意見も聞こえて来そうですが。
2009/12/12
Bulk merge 報告
前々回のエントリーで宿題状態になっていた Bulk Mergeのコストの件です。
結論から書くと、「想定したテストケースでは、Bulk Mergeを適用できない」でした。
Bulk Mergeの書式は、
MERGE INTO 都道府県 A USING OPENROWSET( BULK 'd:\wk\都道府県.csv'
,FORMATFILE = 'd:\wk\都道府県.fmt' ) B
ON A.code = B.code
WHEN MATCHED THEN UPDATE SET A.name = B.name
WHEN NOT MATCHED THEN INSERT VALUES ( B.code , B.name);
です。直感的に理解できます。
(*) create table 都道府県
( code char(2) primary key,
name varchar(10)
)
とします。
CSV Fileの書式をFORMATFILEで指定してあげる必要があります。
当初、この書式を手作業で作成するものだと思っていて、手間取ったのですが、よくよく読むと、bcp機能でテーブルから自動作成してくれるではありませんか!!
bcp __検証.dbo.都道府県 format nul -T -c -t "," -f d:\wk\都道府県.fmt
これで、Bulk Mergeの準備は整いました。いざテスト。GO。
一意キーエラーで落ちる!!
なんで、落ちるの?、重複すれば置換してくれるのではないの?。
最小データでテストしてみました。
11,東京
22,大阪
問題なくOK.
11,東京
22,大阪
11,福岡
重複キー違反で落ちる....なんで???
bulk Mergeの元データ(CSV)内に重複キーのデータがあるときは、重複エラーを起こすようです。
なので、「郵便番号CSVから都道府県表を作る」というシナリオが成立しませんでした。
便利な構文でも制限はあるものですね。久々にハマりました。
視点を変えて、純粋に Bulk mergeのコストを計ろうとしたのでが、郵便番号CSV_Fileは 癖の強いデータでして、郵便番号がユニークじゃないのです。
地域名が長すぎる行は、複数行に割って格納されているので、このような構造になっています。
まずは、Bulk Mergeで使える CSVに整形するところからやって、後日エントリーします。
結論から書くと、「想定したテストケースでは、Bulk Mergeを適用できない」でした。
Bulk Mergeの書式は、
MERGE INTO 都道府県 A USING OPENROWSET( BULK 'd:\wk\都道府県.csv'
,FORMATFILE = 'd:\wk\都道府県.fmt' ) B
ON A.code = B.code
WHEN MATCHED THEN UPDATE SET A.name = B.name
WHEN NOT MATCHED THEN INSERT VALUES ( B.code , B.name);
です。直感的に理解できます。
(*) create table 都道府県
( code char(2) primary key,
name varchar(10)
)
とします。
CSV Fileの書式をFORMATFILEで指定してあげる必要があります。
当初、この書式を手作業で作成するものだと思っていて、手間取ったのですが、よくよく読むと、bcp機能でテーブルから自動作成してくれるではありませんか!!
bcp __検証.dbo.都道府県 format nul -T -c -t "," -f d:\wk\都道府県.fmt
これで、Bulk Mergeの準備は整いました。いざテスト。GO。
一意キーエラーで落ちる!!
なんで、落ちるの?、重複すれば置換してくれるのではないの?。
最小データでテストしてみました。
11,東京
22,大阪
問題なくOK.
11,東京
22,大阪
11,福岡
重複キー違反で落ちる....なんで???
bulk Mergeの元データ(CSV)内に重複キーのデータがあるときは、重複エラーを起こすようです。
なので、「郵便番号CSVから都道府県表を作る」というシナリオが成立しませんでした。
便利な構文でも制限はあるものですね。久々にハマりました。
視点を変えて、純粋に Bulk mergeのコストを計ろうとしたのでが、郵便番号CSV_Fileは 癖の強いデータでして、郵便番号がユニークじゃないのです。
地域名が長すぎる行は、複数行に割って格納されているので、このような構造になっています。
まずは、Bulk Mergeで使える CSVに整形するところからやって、後日エントリーします。
2009/12/10
売捌所
郵便切手・印紙・売捌所「xxx商店」という店を見かけました。ビジネス街の端っこですが、ほっとした感じがしました。
字面にレトロな響きがあります。店の様子からは切手や葉書の類の販売専門の個人商店のようです。
一昔前は、「大型スーパーが小売店を潰す」というので反対運動が有りました。でも結局は、寂れた商店街が増えてます。
コンビニ効果が大きいのか、経営改善なのか、売り場の大きな酒屋さんは、コンビニに転業する所もあります。
ファストフード店に転業してる小さ目の店もありました。
個人宅レベルの「なんでも屋」「よろず屋」さんを見かけなくなりました。
大資本系列の店が増えると、個人では歯が立たないというのが、現実なんでしょうか。
街角の「たばこ屋」さんが潰れないのが、妙に疑問に思うのです。
駄菓子屋さんや、小さな化粧品屋/薬局など、商売が成立するのか疑問に思える店が、以前はあちこちにありました。
そんな時代が「安定して良い時代だったなぁ」と回顧に浸るのでありました。
深刻な不況で開発仕事自体が減っている昨今ですが、売捌所のような店が残っていて欲しいなぁ。
字面にレトロな響きがあります。店の様子からは切手や葉書の類の販売専門の個人商店のようです。
一昔前は、「大型スーパーが小売店を潰す」というので反対運動が有りました。でも結局は、寂れた商店街が増えてます。
コンビニ効果が大きいのか、経営改善なのか、売り場の大きな酒屋さんは、コンビニに転業する所もあります。
ファストフード店に転業してる小さ目の店もありました。
個人宅レベルの「なんでも屋」「よろず屋」さんを見かけなくなりました。
大資本系列の店が増えると、個人では歯が立たないというのが、現実なんでしょうか。
街角の「たばこ屋」さんが潰れないのが、妙に疑問に思うのです。
駄菓子屋さんや、小さな化粧品屋/薬局など、商売が成立するのか疑問に思える店が、以前はあちこちにありました。
そんな時代が「安定して良い時代だったなぁ」と回顧に浸るのでありました。
深刻な不況で開発仕事自体が減っている昨今ですが、売捌所のような店が残っていて欲しいなぁ。
2009/12/07
ストアードでも例外期待は駄目
前回、例外を期待したコードのコスト高を書きました。
「ストアードにすぺき」とのコメントをいただきました。
ストアードでかいても、例外を期待したコードを書いてしまうと同じですね。
テストしてみました。今回も前回と同様、郵便番号.CSV (約12万行)から 都道府県表(47行)を作るものです。
①例外を期待した場合( してはいけない)
Create PROCEDURE [dbo].[#県名登録_例外] @cd varchar(2), @名称 varchar(10)
AS
BEGIN TRY
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
END TRY
BEGIN CATCH
update J01_都道府県表 set 都道府県コード=@cd,都道府県名称=@名称
where 都道府県コード=@cd and 都道府県名称=@名称;
End CATCH
結果:①117 秒
②select文で判断
Create PROCEDURE [dbo].[#県名登録_非例外] @cd varchar(2), @名称 varchar(10)
AS
declare @cnt int;
select @cnt = count(*) from J01_都道府県表 where 都道府県コード=@cd and 都道府県名称=@名称;
if @cnt=0
begin
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
end
else
begin
update J01_都道府県表 set 都道府県コード=@cd,都道府県名称=@名称
where 都道府県コード=@cd and 都道府県名称=@名称;
end
結果:②:29秒
③update文の結果で判断
Create PROCEDURE [dbo].[#県名登録_非例外_a] @cd varchar(2), @名称 varchar(10)
AS
declare @cnt int;
update J01_都道府県表 set 都道府県コード=@cd,都道府県名称=@名称 where 都道府県コード=@cd and 都道府県名称=@名称;
set @cnt=@@ROWCOUNT;
if @cnt=0
begin
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
end
結果③27秒
まとめると
①117秒
② 29秒
③ 27秒
.net言語(C#/VB)での例外処理した場合の比率は 36:4406で、 122倍のコスト高でしたが、
T-SQLでの比率は 29:117 で 4.03倍なので、言語に比べたら低い結果となりました。
それでも4倍高くつくので、例外を期待するのはやめたほうがよいでしょう。
select文をなくすことで、2秒の差がつきました。削減効果が小さいとはいえ、処理が減るので良いですね。
知恵を絞れば、もっと早くする工夫があるのでしょうね、既存のソースを引用するときは、チェックが必要です。
「ストアードにすぺき」とのコメントをいただきました。
ストアードでかいても、例外を期待したコードを書いてしまうと同じですね。
テストしてみました。今回も前回と同様、郵便番号.CSV (約12万行)から 都道府県表(47行)を作るものです。
①例外を期待した場合( してはいけない)
Create PROCEDURE [dbo].[#県名登録_例外] @cd varchar(2), @名称 varchar(10)
AS
BEGIN TRY
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
END TRY
BEGIN CATCH
update J01_都道府県表 set 都道府県コード=@cd,都道府県名称=@名称
where 都道府県コード=@cd and 都道府県名称=@名称;
End CATCH
結果:①117 秒
②select文で判断
Create PROCEDURE [dbo].[#県名登録_非例外] @cd varchar(2), @名称 varchar(10)
AS
declare @cnt int;
select @cnt = count(*) from J01_都道府県表 where 都道府県コード=@cd and 都道府県名称=@名称;
if @cnt=0
begin
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
end
else
begin
update J01_都道府県表 set 都道府県コード=@cd,都道府県名称=@名称
where 都道府県コード=@cd and 都道府県名称=@名称;
end
結果:②:29秒
③update文の結果で判断
Create PROCEDURE [dbo].[#県名登録_非例外_a] @cd varchar(2), @名称 varchar(10)
AS
declare @cnt int;
update J01_都道府県表 set 都道府県コード=@cd,都道府県名称=@名称 where 都道府県コード=@cd and 都道府県名称=@名称;
set @cnt=@@ROWCOUNT;
if @cnt=0
begin
insert into J01_都道府県表(都道府県コード,都道府県名称) values (@cd,@名称)
end
結果③27秒
まとめると
①117秒
② 29秒
③ 27秒
.net言語(C#/VB)での例外処理した場合の比率は 36:4406で、 122倍のコスト高でしたが、
T-SQLでの比率は 29:117 で 4.03倍なので、言語に比べたら低い結果となりました。
それでも4倍高くつくので、例外を期待するのはやめたほうがよいでしょう。
select文をなくすことで、2秒の差がつきました。削減効果が小さいとはいえ、処理が減るので良いですね。
知恵を絞れば、もっと早くする工夫があるのでしょうね、既存のソースを引用するときは、チェックが必要です。
2009/12/06
例外に依存するロジックは駄目ですよ
あるシステムの処理が遅いというので、追跡してみました。
元になるデータを順次読み取り、対応するデータが無ければ追加、有れば、更新という単純なものです。
最近のSQL Serverにも Oracle並の Merge文が可能になったので、便利になりました。このシステムでは、自力で処理していました。
遅い原因の一つが次のようなものでした。
while(!eof(元データ))
{
try
{
sql実行(update TABLE set xxx=@xxx , yyy=@yyy where ユニーク条件)
}
catch()
{
sql実行(insert into TABLE (xxx,yyy) values (@xxx,@yyy) )
}
}
業務要件の動作はしますが、駄目でしょう。
(*)これでもソースレビューは合格したらしいので、レビュワーな何をみているのでしょうね。
int cnt = sql実行(Select count(*) from TABLE where ユニーク条件)
if(cnt==0) sql実行( insert into TABLE (xxx,yyy) values (@xxx,@yyy))
else sql実行(update TABLE set xxx=@xxx , yyy=@yyy where ユニーク条件)
とすべきでしょう。(排他処理は省いてます)
駄目だと決めつけてますが、「行儀が悪い」というだけでは、根拠が薄いので、コスト確認してみました。
(例によって)郵便番号CSVデータを用いて、郵便番号CSVから都道府県表を作ります。
元になる郵便番号CSV
自治体コード5桁 都道府県名 市区名
01101,"北海道","札幌市中央区"
……………………
47382,"沖縄県","八重山郡与那国町"
このCSVデータは12万行あります。これを順次読み取り
都道府県表
コード 都道府県名
01 北海道
……………………
27 大阪府
……………………
47 沖縄県
の47行を作ります。
①事前に存在Checkした処理
while(true)
{
string text = sr.ReadLine(); if (text == null) break;
csv分解();
int cnt = sql実行(Select count(*) from TABLE where ユニーク条件)
if(cnt==0) sql実行( insert into TABLE (xxx,yyy) values (@xxx,@yyy))
else sql実行(update TABLE set xxx=@xxx , yyy=@yyy where ユニーク条件)
}
②例外を利用した処理
while(true)
{
string text = sr.ReadLine(); if (text == null) break;
csv分解();
try
{
sql実行(update TABLE set xxx=@xxx , yyy=@yyy where ユニーク条件)
}
catch()
{
sql実行(insert into TABLE (xxx,yyy) values (@xxx,@yyy) )
}
}
結果は
① 36秒
②4406秒
でした。100倍以上の開きがありました。例外が高コストな処理なのがよく判ります。
CSVデータは、[Provider=Microsoft.Jet.OLEDB.4.0;Data Source=xxx] で読み込めば ADO.NETとして処理できます。
そこで [Provider=Microsoft.Jet.OLEDB.4.0;Data Source=xxx] で接続し、
DataTable dt = (SQL実行)"select distinct left( right(str([F1] + 1000000),5),2) , F4 from KEN_ALL.CSV ";
foreach(DataRow dr in dt.Rows)
{
(SQL実行) ( insert into 都道府県表 (code ,名称) values (@code,@名称))
}
で実行しました。③
結果は
③3秒
でした。殆どがDistinct文の処理時間のようです。必要なデータを抽出時に絞ることが重要ですね。(Linqに通じる思想かな)
(*) CSV fileは DataTableに読み込めば、処理が単純になってスッキリ扱えるのでお気に入りなんですが、あまり知られてないのですよねぇ。
都道府県表を作るような処理の場合、重複チェックをDBに依存するのでなく自前で判定すればどうかも、試行しました。④
private List 自前で重複チェック_List = new List();
while(true)
{
string text = sr.ReadLine(); if (text == null) break;
csv分解();
if (!自前で重複チェック_List.Contains(名))
{
自前で重複チェック_List.Add(名);
sql文実行( insert into TABLE( xxx,yyy) values(@xxx,@yyy))
}
結果は
④1秒 (実値0.92秒)
でした。
まとめると(都道府県表をつくるという視点で)
① 36秒
②4406秒
③ 3秒
④ 1秒
最大格差は 4400倍!!。自分もビックリ。「事務データRDBで処理するのがベスト」との声もありますが、このケースのように、事前に対象データの絞り込みは言語で行うほうが良いケースもあります。
実装手段は複数あることが多いので、コスト比較して決定する必要があります。
商売の購入時に合見積もりを取るのと似てますね。
元になるデータを順次読み取り、対応するデータが無ければ追加、有れば、更新という単純なものです。
最近のSQL Serverにも Oracle並の Merge文が可能になったので、便利になりました。このシステムでは、自力で処理していました。
遅い原因の一つが次のようなものでした。
while(!eof(元データ))
{
try
{
sql実行(update TABLE set xxx=@xxx , yyy=@yyy where ユニーク条件)
}
catch()
{
sql実行(insert into TABLE (xxx,yyy) values (@xxx,@yyy) )
}
}
業務要件の動作はしますが、駄目でしょう。
(*)これでもソースレビューは合格したらしいので、レビュワーな何をみているのでしょうね。
int cnt = sql実行(Select count(*) from TABLE where ユニーク条件)
if(cnt==0) sql実行( insert into TABLE (xxx,yyy) values (@xxx,@yyy))
else sql実行(update TABLE set xxx=@xxx , yyy=@yyy where ユニーク条件)
とすべきでしょう。(排他処理は省いてます)
駄目だと決めつけてますが、「行儀が悪い」というだけでは、根拠が薄いので、コスト確認してみました。
(例によって)郵便番号CSVデータを用いて、郵便番号CSVから都道府県表を作ります。
元になる郵便番号CSV
自治体コード5桁 都道府県名 市区名
01101,"北海道","札幌市中央区"
……………………
47382,"沖縄県","八重山郡与那国町"
このCSVデータは12万行あります。これを順次読み取り
都道府県表
コード 都道府県名
01 北海道
……………………
27 大阪府
……………………
47 沖縄県
の47行を作ります。
①事前に存在Checkした処理
while(true)
{
string text = sr.ReadLine(); if (text == null) break;
csv分解();
int cnt = sql実行(Select count(*) from TABLE where ユニーク条件)
if(cnt==0) sql実行( insert into TABLE (xxx,yyy) values (@xxx,@yyy))
else sql実行(update TABLE set xxx=@xxx , yyy=@yyy where ユニーク条件)
}
②例外を利用した処理
while(true)
{
string text = sr.ReadLine(); if (text == null) break;
csv分解();
try
{
sql実行(update TABLE set xxx=@xxx , yyy=@yyy where ユニーク条件)
}
catch()
{
sql実行(insert into TABLE (xxx,yyy) values (@xxx,@yyy) )
}
}
結果は
① 36秒
②4406秒
でした。100倍以上の開きがありました。例外が高コストな処理なのがよく判ります。
CSVデータは、[Provider=Microsoft.Jet.OLEDB.4.0;Data Source=xxx] で読み込めば ADO.NETとして処理できます。
そこで [Provider=Microsoft.Jet.OLEDB.4.0;Data Source=xxx] で接続し、
DataTable dt = (SQL実行)"select distinct left( right(str([F1] + 1000000),5),2) , F4 from KEN_ALL.CSV ";
foreach(DataRow dr in dt.Rows)
{
(SQL実行) ( insert into 都道府県表 (code ,名称) values (@code,@名称))
}
で実行しました。③
結果は
③3秒
でした。殆どがDistinct文の処理時間のようです。必要なデータを抽出時に絞ることが重要ですね。(Linqに通じる思想かな)
(*) CSV fileは DataTableに読み込めば、処理が単純になってスッキリ扱えるのでお気に入りなんですが、あまり知られてないのですよねぇ。
都道府県表を作るような処理の場合、重複チェックをDBに依存するのでなく自前で判定すればどうかも、試行しました。④
private List
while(true)
{
string text = sr.ReadLine(); if (text == null) break;
csv分解();
if (!自前で重複チェック_List.Contains(名))
{
自前で重複チェック_List.Add(名);
sql文実行( insert into TABLE( xxx,yyy) values(@xxx,@yyy))
}
結果は
④1秒 (実値0.92秒)
でした。
まとめると(都道府県表をつくるという視点で)
① 36秒
②4406秒
③ 3秒
④ 1秒
最大格差は 4400倍!!。自分もビックリ。「事務データRDBで処理するのがベスト」との声もありますが、このケースのように、事前に対象データの絞り込みは言語で行うほうが良いケースもあります。
実装手段は複数あることが多いので、コスト比較して決定する必要があります。
商売の購入時に合見積もりを取るのと似てますね。
2009/12/04
携帯サイトアプリの画面遷移
携帯サイトはJavascriptもAJAXもCookieも使えません。
画面遷移に使えるコントロールは<&a href=''/> か の二種類程度しかありません。
{更新][削除}[戻る]など複数の分岐をボタンで行うとき、複数のsubmitボタンを配置することになります。
submitキーの反応は、pagePostBackとして自画面で受けます。そのとき、画面情報は Page.Request[] で取得できます。
幸せなことに、submitボタンが複数個あっても、押されたボタンのみが送られてきます。
(*)仕様的にそうするしかなったのでしょうが、画面情報を取得するという面では、Submitコントロールは別扱いなんでしょうね。
押されたsubmitキーの判別は、Page.Request[]を順次スキャンして、コントロール.Nameを調べるのが正攻法でしょう。
画面仕様によっては、データの量に応じてn個のsubmitキーを配置することもあります。
その際は、レコードIDをコントロール名に含めるなど、小技をつかって小細工することになります。
うーん。エレガントでないですね。なんかスマートな方法がないものでしょうか。
画面遷移に使えるコントロールは<&a href=''/> か の二種類程度しかありません。
{更新][削除}[戻る]など複数の分岐をボタンで行うとき、複数のsubmitボタンを配置することになります。
submitキーの反応は、pagePostBackとして自画面で受けます。そのとき、画面情報は Page.Request[] で取得できます。
幸せなことに、submitボタンが複数個あっても、押されたボタンのみが送られてきます。
(*)仕様的にそうするしかなったのでしょうが、画面情報を取得するという面では、Submitコントロールは別扱いなんでしょうね。
押されたsubmitキーの判別は、Page.Request[]を順次スキャンして、コントロール.Nameを調べるのが正攻法でしょう。
画面仕様によっては、データの量に応じてn個のsubmitキーを配置することもあります。
その際は、レコードIDをコントロール名に含めるなど、小技をつかって小細工することになります。
うーん。エレガントでないですね。なんかスマートな方法がないものでしょうか。
2009/12/03
トイレットペーパー持ち出し禁止?
最近、雑居ビルのトイレで、このような張り紙を見かけます。こないだは、
「 トイレットペーパーは持ち出さないでください。あなたの行為は誰かが見ています。後々後悔しないためにも。」
のような、訓示めいた張り紙もありました。
見かける頻度が高くなっているのは、持ち帰る人が増えたわけか。節約の為だとしたら、セコすぎますね。
以前は(電車の)駅トイレは紙は有料でしたが、最近は標準で設置しています。結構な費用が必要だと聞きます。
こちらのほうが、持ち帰る被害が、多そうですが、どうなんでしょうね。
持ち出す人は、ほかに使用目的があるのでしょうか。
トイレにゴミ袋を放置して、ゴミ処理する人もいるとか。
気が滅入る時代なんだなぁ。
「 トイレットペーパーは持ち出さないでください。あなたの行為は誰かが見ています。後々後悔しないためにも。」
のような、訓示めいた張り紙もありました。
見かける頻度が高くなっているのは、持ち帰る人が増えたわけか。節約の為だとしたら、セコすぎますね。
以前は(電車の)駅トイレは紙は有料でしたが、最近は標準で設置しています。結構な費用が必要だと聞きます。
こちらのほうが、持ち帰る被害が、多そうですが、どうなんでしょうね。
持ち出す人は、ほかに使用目的があるのでしょうか。
トイレにゴミ袋を放置して、ゴミ処理する人もいるとか。
気が滅入る時代なんだなぁ。
2009/12/02
3穴パンチ
(今は改善されているかもしれませんが)
IBM関係の書類は3つの穴が空いている書類が多かったです。
日本以外の会社では、3穴バインダーが多いからだと聞きました。でも、此処は日本です。
(参考) http://www2.ocn.ne.jp/~hasamaya/jimuyouhin/panch/4panch.htm
一般の文具屋さんには、3穴バインダーは置いてません。パイプ式も殆どが二穴です。
西洋で主流とされる3穴式が日本で普及しなかった理由は判りません。日本での主流は二穴です。
その文化背景を考えると、外資系企業でも、配布資料は二穴式にして欲しいです。
3穴パンチも需要が少ないため、結構高価なものになってます。
紙のサイズも、欧米ではA3/A4/A5が主流だそうです。B3/B4/B5は日本ローカル仕様のようです。
明治期は舶来崇拝だと言われますが、日本規格を貫いて独自色を出した部分もあるようですね。
それは、良いことだと思います。文化といえますね。「郷にいれば郷に従う」でしょう。外資系企業が母国文化を持ち込んで、不毛な摩擦が生じると、双方にとってマイナスですね。
文房具一つで、不満を感じるので、感情は難しいものです。
IBM関係の書類は3つの穴が空いている書類が多かったです。
日本以外の会社では、3穴バインダーが多いからだと聞きました。でも、此処は日本です。
(参考) http://www2.ocn.ne.jp/~hasamaya/jimuyouhin/panch/4panch.htm
一般の文具屋さんには、3穴バインダーは置いてません。パイプ式も殆どが二穴です。
西洋で主流とされる3穴式が日本で普及しなかった理由は判りません。日本での主流は二穴です。
その文化背景を考えると、外資系企業でも、配布資料は二穴式にして欲しいです。
3穴パンチも需要が少ないため、結構高価なものになってます。
紙のサイズも、欧米ではA3/A4/A5が主流だそうです。B3/B4/B5は日本ローカル仕様のようです。
明治期は舶来崇拝だと言われますが、日本規格を貫いて独自色を出した部分もあるようですね。
それは、良いことだと思います。文化といえますね。「郷にいれば郷に従う」でしょう。外資系企業が母国文化を持ち込んで、不毛な摩擦が生じると、双方にとってマイナスですね。
文房具一つで、不満を感じるので、感情は難しいものです。
2009/12/01
坂の上の雲
大河ドラマが11月で最終回になったので、変だなぁと思っていたら、足かけ三年に渡るドラマが始まるとか。
1年を通して観続けるのは、辛いです。ビデオにとっておいても、観ないままお蔵入りすることも多々あります。
筋書きの展開が早いときは、間が飛ぶとストーリーがワケワカになったりします。
三ヶ月単位のドラマが主流になっている昨今で、3年スケールのドラマで勝負するとは、さすがNHKだなぁ。と思ったしだい。
司馬遼太郎史観の是非は、ともかく、ドラマとして楽しめそうでした。でも2部、3部が1年後というのは。
そのころは、1部の内容は忘却しているだろうな。スパンが長すぎる希ガス。
1年を通して観続けるのは、辛いです。ビデオにとっておいても、観ないままお蔵入りすることも多々あります。
筋書きの展開が早いときは、間が飛ぶとストーリーがワケワカになったりします。
三ヶ月単位のドラマが主流になっている昨今で、3年スケールのドラマで勝負するとは、さすがNHKだなぁ。と思ったしだい。
司馬遼太郎史観の是非は、ともかく、ドラマとして楽しめそうでした。でも2部、3部が1年後というのは。
そのころは、1部の内容は忘却しているだろうな。スパンが長すぎる希ガス。
登録:
投稿 (Atom)