Ognacの雑感

木漏れ日々

目次

Blog 利用状況

書庫

ギャラリ

文字項目をすべて VARCHAR2(n)で定義するのは?  ~~ 別件'2'ってなんだ。

ここ数年携わったプロジェクトの幾つかのRDBのテーブル定義は、文字列属性がすべてvarchar2(n)でした。長さ1byteの項目でも、キー項目でも、複数項目からなる項目でも一律にvarchar2(n)です。
可変長の扱いはOverHeadが高い、Update処理の時、有効な項目データ長が確保されている行領域を超えるときは、行が取り直されるので置換コストが高くつく。というコスト意識がまず浮かんでスナオに賛成できません。
別の面では、項目長の意味合いが崩れる。とも思うのです。8byteの顧客コードのシステムの場合、「8桁の顧客コード」という桁数に意味があるケースもあります。"1234    "が "1234" になるのでは
意味が変わってくることもあります。
また、顧客コードを varchar2(8) にしているシステムと、char(8)としていいるシステムと連動したとき, '1234' = '1234    ' が成立しないので、要らぬ手間が生じたり、不毛なバグ騒ぎになったりします。
桁が固定している項目は固定長にしましょうと主張すると返ってくる反論は 「RDBもCPUも進歩して早くなっているのだから、varchar2()によるコストアップは知れている。それよりも、varchar2()で統一するメリットのほうが大である。他のシステムもvarchar2()に置換すべきだ。」
うーん。いいのかなぁ。引っかかるなぁ。古い感覚から脱皮できないのかなぁ。
varchar2() と char() の 動作振る舞いの差を認識したうえで、varchar2()に統一しているのなら一理あるようにも思います。しかし、それがインフラになっていると、初心者にとってはそれが当たり前になってしまい、違いを知ろうとしない開発者になったりします。
 安易に作れるようになると、浅い開発者が増えるのは痛し痒しですね。

それとはまったく別次元の話ですが ,  Varchar2()の'2'に違和感を感じてます。 マジックナンバー感がするのです。
以前のORACLEはvarchar()があり拡張型として varchar2()が登場した背景があります。しかし、"2"にするのは軽いと思うのです。拡張やexpansionにナンバーを付けるセンスが如何とも。
PowerShellの拡張子が、PS1 というのもあり、末尾に数字を付ける文化って不滅なのかなぁ。
名は体を表わすべきだし、マジックナンバーは止めましょうと推進しているインフラ的な製品に"2" が付くのは落ち着かないです。

投稿日時 : 2008年5月13日 0:40

Feedback

# re: 文字項目をすべて VARCHAR2(n)で定義するのは?  ~~ 別件'2'ってなんだ。 2008/05/13 1:17 通りすがり

命名:ゆとり設計
ゆとり教育の成否が分かるのは、いわゆるゆとり世代が成人し社会に出た後という長い目で見ないといけませんが、ゆとり設計の成否はもう出てませんかね?ぜひ伺いたいものです。
私もOgnac様と同じ感覚を持ちますが、うまくいく場面もあるのでしょうか。

# re: 文字項目をすべて VARCHAR2(n)で定義するのは?  ~~ 別件'2'ってなんだ。 2008/05/13 2:29 Pasie.

とりあえずnvarchar2派になりました。異端児です(汗
私は基本は可変長にして、状況により固定長にします。
同様に数値も基本はnumberで、integerとかfloatとかは使いません。
インピーダンスミスマッチ?が気にもなりますが、私の中ではそれが自然な感じです。

速度についてもトラフィックとのさじ加減で最適化はしますが、基本はコストがかかっても可変長です。語弊はありますが、コストがかるからクラスは使わないとか言わないのと一緒だと思っています。

ところで例の8桁の顧客コードは、8桁固定にもかかわらず4桁が入力されている時点で意味不明と思います。cobolのように原則固定長しか使えない処理系ならともかく(或いは速度面で固定長にせざるを得ないならともかく)、指定桁埋まらないなら可変長にすべきだと思います。指定桁が埋まらないのになぜか固定長を使用しているシステムとの連携については、当初より連携する際に他システムの型に合わせるか、或いは末尾スペースの扱いをどうするかはインターフェイス仕様などで取り決めるべき問題(=処理共通化)である気がします。'1234'と'1234 'の意味づけや比較の基準はスペック策定時に解決されるべきものであり、データベースの型に依存する問題ではないと考えます。

# re: 文字項目をすべて VARCHAR2(n)で定義するのは?  ~~ 別件'2'ってなんだ。 2008/05/13 9:38 シャノン

NVARCHAR2でw

# re: 文字項目をすべて VARCHAR2(n)で定義するのは?  ~~ 別件'2'ってなんだ。 2008/05/13 10:47 はつね

取り扱うデータが固定長であればCHAR、可変長であればVARCHAR2を使っています。
例に挙げている顧客コードは8桁固定なのであれば、CHAR(8)として定義し8桁固定という意味をテーブル自体に持たせます。場合によっては(Oracleでの)Before TriggerでTrimかけてLengthチェックして8桁じゃなかったらエラーにする必要もあるでしょう。
え?諸々のオーバーヘッドや「開発者の」使いやすさですか?そんなものはRDBもCPUも進歩して早くなっているのだから微々たるものでしょうし、開発者が使いやすくても間違えたデータが混入するよりもトータルコストは下がるはずです。

# しまいには数値も日付も全部VARCHAR2と言い出されそう(笑

# re: 文字項目をすべて VARCHAR2(n)で定義するのは?  ~~ 別件'2'ってなんだ。 2008/05/13 12:19 Ognac

>うまくいく場面もあるのでしょうか。
varchar2()使用の是非でなく、疑問をもたない開発者への疑問符はのこりますね。古い人になったのだなぁと思う。

>インピーダンスミスマッチ?が気にもなりますが、私の中ではそれが自然な感じです。
理解した上での採用は問題ないかと思います。

しかし、1byteの文字項目でかつ, NOT NULL の項目までも、 varchar(1) にするのは違和感があります。

>例に挙げている顧客コードは8桁固定なのであれば、CHAR(8)として定義し8桁固定という意味をテーブル自体に持たせます。場合によっては(Oracleでの)Before TriggerでTrimかけてLengthチェックして8桁じゃなかったらエラーにする必要もあるでしょう。

例に挙げた8桁の顧客コードは桁に意味を含んだ場合で、上4桁は顧客の請求先コード(取りまとめ部署) で下4桁が部署コードを想定しました。
部署コードが 空白の時は請求先を意味するというルール。
Fieldを別けるべきだとの案もありますが、過去のながれから、項目内の桁位置に意味を持たせているシステムも現存します。
右側が空欄になるのはおかしい......のかもしれませんが...ジレンマ。

>諸々のオーバーヘッドや「開発者の」使いやすさですか?
オーバーヘッドが気になるのは古い世代なんですねぇ。

>しまいには数値も日付も全部VARCHAR2と言い出されそう(笑
スクリプト言語や動的言語が普及すると、そうなる可能性が高まる予感。

# re: 文字項目をすべて VARCHAR2(n)で定義するのは?  ~~ 別件'2'ってなんだ。 2008/05/18 1:37 はつね

>スクリプト言語や動的言語が普及すると、

言語の表現方法と、RDBMSのテーブル定義とは無縁だという事に気がついて欲しいですよね。

タイトル
名前
Url
コメント