今回のポイント
・主キーの考え方を学ぶ
・数値フラグと文字格納のメリット/デメリット
・数値フラグとリレーションシップは違う

 データベースは,カラムとその集合体のテーブルから出来上がっているということは理解していただけたと思います。今回はもう少しつっこんで,テーブルの中の主キーと数値フラグというものについて学習していきます。開発前のデータベース設計にかかわる部分なので,しっかりと読んで学習してください。序盤の交渉を有利に進めるための大切なポイントです。

ユニークな値と主キー

 今回は簡単な社員名簿でお話を進めます。図1を見てください。10人の社員がいます。

図1●簡単な社員名簿の例1
図1●簡単な社員名簿の例1

 「社員番号」は重複することのないユニークな番号です。データベースではユニークという単語が頻繁に出てきます。日本では“ユニークな人”のような用法が広まっているので,ユニークというと“ちょっと変わっている”とか“面白い(ユーモアがある)”のような印象を受けますが,本来の意味は「一意である」「固有,単独である」です。プログラムの世界でユニークといえば,重複することがなく,それ単体でデータを確定できるといった意味合いになります。

 データベースの案件では,ユニークな値というのは非常に重要です。それぞれのテーブルの中で,ある1行(カラム)を特定するために,ユニークな番号を割り当てることは必須となります。データベース上でデータを特定するために割り当てるユニークなキー番号を「主キー」と言います。「プライマリー・キー」という呼び方もあります。

 前回,「テーブル1の都道府県欄に1と書かれていたユーザーは,テーブル2の都道府県IDが1の都道府県(東京都)の人らしい」というお話をしました。これは都道府県テーブルの都道府県IDが主キーになっていて,「1」といえば東京都である,と確定できるからです。もし都道府県テーブルに「1」というIDが複数存在してしまうと,特定はできないということになります。

 もう一度,社員名簿を見てください。「ユニークであればいいのなら氏名でもいいんじゃないか」ということに気がつきます。たとえば田中さんは一人しかいませんから,これはユニークではないかという話です。この時点ではたしかにユニークです。ところが田中さん,営業の山田さんと結婚することになりました。これで田中→山田に改姓してしまうと山田は二人になってしまうのでユニーク(あくまでも一意で重複があってはならない)ではなくなります。苗字だけだから問題なのかというと,来春入社予定の新卒社員が山田さんと同姓同名だったという事態には対応できなくなります。名前というのはたとえフルネームであっても,ユニークとなりえるとは限らないというわけです。

 では社内で使っている社内コードというのがあるので,それを使えばどうだろうと考えてみました。

図2●簡単な社員名簿の例2。社内コードを追加
図2●簡単な社員名簿の例2。社内コードを追加

 「社内コード」というカラムが追加されました。この社内コードは,どうやら最初のアルファベットが所属部署のようです。K001は「経理の001番」,S003なら「総務の003番」だと思われます。さてこれが主キーで大丈夫でしょうか?

 お気づきのとおり,これは昇進や配置転換が行われると変わっていってしまう番号です。

 「営業を拡充するぞ」と社長の一声で総務から加藤さん(S001)が営業に回って(E005),代わりに宮本さん(S002)が総務部長(S001)に昇進…のように社内コードがコロコロと変わってしまうと,例えば顧客名簿の担当者欄に担当者コードとしてリレーションシップが張ってあった場合に接続先が変わってしまいます。

 その問題を解消するために別のテーブルも修正が必要となり,やっと修正が終わったころにまた配置転換が発生してみたりと,データベースに振り回されることになります。仕事を効率化するためのシステム導入で,仕事を増やしては意味がありません。

 主キーというのは一意であれば,必ずしも変化してはいけないという質のものではありませんが,できることならば一度割り当てたら,ほぼ恒久的に変化しないものが望ましいです。

 実はこの「ほぼ恒久的に変化しない」というのがポイントです。例えば社内コード7の宮本さんが結婚退社した場合,7がいなくなったから,8以下を繰り上げて…という操作をすると,主キーは恒久的ではなくなります。途中に欠番が出ても,主キーの振り直しは行うべきではありません。7の人がいなくなっても,8以降の人は8以降のままです。また空いた7に来春の新卒を割り当てるということもすべきではありません。一度割り当てたら,たとえ無駄に見えても,そこを空欄としておくことがデータベースの基本です。

 プロ野球の背番号はシーズン中には一意(主キー)です。しかしシーズンオフには引退やトレードで空番ができ,その番号を受け継ぐ選手が出てくることがあります。したがって数シーズンというスパンで見ていくと,背番号は主キーたりえません。背番号を主キーにするには,その背番号を付けていた人が引退やトレードでいなくなったら永久欠番として二度と誰もが使わなくするという扱いにしなくてはならないわけです。

 主キーの値そのものは,どうやって決めたらいいでしょうか。実はそれほど難しいことはありません。極論すると,連番で数値を割り当てます。主キーそのものはシステムのどこかで表示されるという質のものではなくて,あくまでもデータベース内での利便性のために付与するものであって,ここで「1からじゃ会員数が少なく見えてかっこ悪いから10000からにして」(実話)とか,文句や注文を言う性質のものでもありません。1万からの表示は別のフィールドで「会員ID」として設けることで解決できます。

数値フラグという考え方

 話を少し戻しましょう。退職した宮本さんのデータのお話です。退職者はどう扱えばいいでしょうか。一つの考え方として,退職しても宮本さんのカラムは残しておいて,在職中なのかどうかを示すなんらかの状態ステータス列を設置するという方法があります。

図3●簡単な社員名簿の例3。在職フラグを追加
図3●簡単な社員名簿の例3。在職フラグを追加

 「在職フラグ」というデータを追加しました。フラグというのは元々は“旗”(flag)の意味です。プログラムでフラグという単語を使う場合は,目印とか指標といった意味合いになります。

 この例では「1」は在職中,「0」は退職を意味します。社員番号7の宮本さんは「0」ですから退職状態となります。社員番号3の加藤さんに「2」が付いてます。これはたまたま在職フラグと言うものを使った副産物で,0が退職,1が在職なら,産休,停職,休職,アルバイトといった状態も,他の数値で表してしまえばいいじゃないかということです。

 フラグには欠点もあります。フラグにある数字が実際に何の意味なのか,一覧表などを参照しないとわかりにくいという点です。では,なぜ直接「在職」「退職」という単語で格納しないんでしょう? メリットとデメリットを考えてみます。

在職/退職などの「文字」で格納する場合
メリット
状態を把握しやすい
「在職」と書かれていれば,誰が見ても「在職」であることがわかる
×
デメリット
データの記録容量が増える
数値と比べてデータで10倍以上の容量を消費する場合がある
データ抽出プログラムが複雑になる
x="在職" OR x="休職" OR x="アルバイト在職" OR…のように抽出条件式が複雑化する

在職は1,退職は0のように「数値」で格納する
メリット
複合状態を記録しやすい
値の設定方法を工夫することで,1は一般社員/在職中,11は管理職/在職中,21は派遣社員/在職中,30はアルバイト/退職のように,複合条件をデータで記録できる
データ抽出のプログラム処理が楽
「0<x<10 なら一般社員」のような抽出条件プログラムを作りやすい
データ記憶容量がコンパクトになる
2バイト文字(かな漢字)と比較して記憶容量が小さい。数万データになると記録容量の差は直接パフォーマンスに影響する
×
デメリット
状態を把握しにくい
例えば1や0が何の意味かは見ただけではわからない

 一方のメリットが他方のデメリットです。記憶容量については数十件程度ならばパフォーマンスやリソース消費で極端な差は出ません。しかし大規模な案件で数万,数十万件というデータを扱いだすと,データの大小はパフォーマンスに露骨に出てきます。

 複合条件の記録については,数値フラグだと1なら「一般社員/在職」,11なら「管理職/在職」のように記録することもできますが,「社員レベル」という列を設けて,そこに一般社員か管理職かと分けることもできる(「社員レベル」1で「在職フラグ」1なら一般社員/在職中のようにできます)ので,決定的な差異とは言えません。

 根幹の部分でいうと,わかりやすいか,わかりにくいかが最も大きな相違点です。ただ本当に数値だからわかりにくいんでしょうか。

 経験則からお話をすると,日本語で記録できるようなフィールド(列)を作った場合,あまりにも大らかに運用されるケースが多いようです。

 自由に項目名を追加/編集できるように作っておくと,運用開始直後は問題になりませんが,数カ月後にサポートに行ったときに「暫定休職中(退職前提)」「正社員扱いアルバイト」のような項目がぽろぽろと出てきて,数種類どころか数十種類の状態設定ができてしまったりします。項目追加が多すぎて検索用のリストボックスが画面からはみ出してしまうという極端な例も目にしたことがあります。ここまでくると一人に対して一つの状態が割り当てられている…という状態に近く,勤務状態を示すと言うより,その人に対するメモ書きになってしまいます。

 データベースの本来の目的は,メモ帳代わりになんでも書いて記録することではなく,そこに記録されているものから特定条件で必要なデータを取り出すことです。データベース初心者の方の多く――Excel初心者もそうかもしれません――が,データを取り出すことを主眼としないで,溜め込むことに注力しすぎるように思われます。だからとにかくいろんなことを統一感なく書いてしまい,欲しいデータを絞り込むための工夫や整理にいたりません。

 そこで数値フラグという考え方でデータを検討します。

数値フラグ化したほうがいいデータとは

 数値フラグというのは,データをまとめるという観点を学ぶのに非常に優れた側面を持っています。数値は論理的形態の究極単純表現(最単純化すると0か1かですけど)ですから,ある事象をカテゴライズするのに,数値化できるかどうかというのは,その人の論理演算資質そのものともいえます。

 論理演算資質がどうして必要なんでしょう?この答えは簡単です。今から作ろうとしているシステムは,プログラムという論理演算で作られるからです。プログラムはあいまいな判断はできません。数値に置き換えられるものであれば,数値として考えていただけると,プログラマとの意思の疎通もスムーズになります。簡単明瞭なデータの集まりであれば,その中から必要なものを取り出す手順も簡単になります。

 また多くのデータベースやプログラム開発言語が海外製であるというのも重要なファクターです。海外製であるがゆえに,できることならば日本語よりも数値やアルファベットで対話したほうが,バグなどの問題に出くわしにくくなります。

 数値フラグの考え方は,社員の在職状態だけでなく,ECサイトで商品の在庫状況,会員制サイトの会員ステータスなどでも利用されます。例えば在庫僅少というのは在庫数の列から目安を付けられますが,在庫が切れてしまっているものについて

 「販売中止」以後入荷なし
 「補充待ち」入荷待ち
 「販売停止」事情により販売一時停止
 「予約受付中」販売開始前入荷待ち

 のようにいくつかの状態がありえます。こうした“状態を示すもの”については数値フラグがよく使用されます。

 ただこうした話をすると曲解されてなんでもかんでも数値フラグにしようとしてしまうケースも見受けられます。数値フラグのデメリットにも書きましたが,なんでも数値にしてしまうと一見して何のデータなのかがわからなくなりすぎて,プログラムも結果的に数値を文字に置き換えて表示するなどの手間がかかってきますので加減と言うものは必要です。わかりにくいデータというのは,ある意味ではセキュリティが高いとも言えますが,何事もほどほどにというわけです。

 数値フラグ化する目安として,おおよそ2値から10値程度になるデータが適しています。具体的には「性別」などです。性別には男と女の2つしかありません。フラグというのはあくまでも目印ですから,1なら男性,2なら女性程度のぱっとみてわかる程度のものまでを対象とするのが望ましいということですね。これが100までの数値データだったりすると,83はいったい何の意味なのかをぱっと思い出すことはできません。思い出せる程度までのデータを対象とするのが数値フラグ化のコツです。

 なお数値フラグと数値記録されているところが他テーブルへのリレーションシップになっていることとは,全く意味が違います。前回出てきた「都道府県IDが1だったら東京都」という例では,1というのはフラグではなくて,都道府県テーブルの主キーへのリレーションシップです。数値で記録する = 数値フラグ ではないというわけです。

 冒頭にお話した「主キー」は,連番数値であることが多いです。連番であれば重複は起こりませんし,数値は大小関係が明確なので並べ替えるとき(ソートといいます)も簡単です。しかし主キーが数値連番であっても,これは数値“フラグ”ではありません。データベース上にはいくつかの数値データがでてきます。それがフラグであるかどうかは,その数値を日本語に置き換えられるかどうかで判断してみてください。

 「数値フラグにするかどうかまで発注者が考えるものなのか」と思われるかもしれません。釈然としませんよね。一つだけ覚えておいてください。どういったデータをデータベースに格納するのかは,数回のミーティングやメール,電話でのやりとりだけでは絶対にプログラマには伝わりません。

 前回も書きましたように,データのひな型とサンプル・データは,発注主であるあなたの手で用意するべきです。用意するにあたってはExcelベースで考えることが一番です。サンプルとして5~10点のデータも入れてみてください。主キーも考えます。こうして作成されたドキュメントをプログラマに送り,あるいはミーティングで配布して,8割程度のデータベース構成は合意確定してしまったほうが,その後の作業がはるかに楽になります。

 そのとき,性別欄に1や2という数値が入っていたら,会員種別欄に0/1/2と書かれていたら「この人はあなどれない」とプログラマ側はかなり緊張します。冗談みたいな話ですが,これは現実です。

 往々にしてプログラマと言う人種は――私も含めて――発注主は何もわかっていない人だと思ってタカをくくってミーティングにやってくることが多いようです。適当に話を聞いて,こちらの都合の言いように設計して進めてしまえと考えているものなのです(もちろん,そうではないプログラマも大勢います)。

 最初に牽制球を投げておくことは,その後の折衝を大きく有利にさせると思ってください。最後に言った言わないでもめるよりは,最初に十分に討議をしてスムーズに開発を開始させるべきです。あなたはプログラマとしてはプロではなく,またプログラマもあなたの業界のプロではありません。この案件の中でお互いが歩み寄る接点は,データベースというシステムの上にあります。双方が先方の業務について勉強しつつ,共通の言葉で会話するために,Excelを開いてサンプルを作ってください。

 あと少しだけデータベースについて語らなくてはなりません。次回は,ここまで随所に出てきたリレーションシップという単語の意味を勉強してみます。