システムで「性別」の情報を扱う前に知っておくべきこと

# 序文

読んで時間を無駄にしたとか言われないために先に断るべきことを書きます

■ どんなことを書いてるか
人間の性別に関する国際規格 ISO 5218 のことと、それをそのままフロントエンド側に使ってはいけない理由、でもデータベース側ではきっちり使うべき理由、実際にどう実装するのがよさそうか、などを書きます。最後に予備知識程度に性別についての明日使えない知識を吹き込みたいと思います。

■ 誰に向けた記事か
システムで性別を扱ったことがある、これから扱うかもしれない、でも性別のデータ化について深く考えたことはない、そんな日本の技術者。

■ 筆者は何者か
Webサービス開発村のデータベース屋さん。レベルはロマリア周辺で全滅しかけるくらい。性別不詳。


# そもそもコンピュータシステムが人間の性別を扱う必要はあるのか

コンピュータシステムに関わっていると、たびたび「性別」と言う単語とエンカウントする事があるかと思います。

使いもしないのに性別を入力させるサービスと言うのは本当にうんざりするほど多いです。個人情報を入力させる際に「名前」「生年月日」「性別」あたりを何も考えずにとりあえず入力させようとするサービスは腐るほどあります。
生年月日はまだカスタマーサポートで個人識別のために使ったりする場合がなくもないですが、性別は使われていません。設計にあたる技術屋さんは是非「使わないんだったら性別欄は削除しましょう」と提案してください。

近年は不要な性別欄の削除を求める団体が活躍しており、行政の方でも不要な性別欄は廃止する方向がトレンドになってきています。(「性別欄 廃止」とかでぐぐると関連記事がわらわらと出てきます)

さてさてしかしながら、性別情報を活用したサービスもたくさんあります。必要な性別欄であれば技術屋としても実装するのはやぶさかではありません。具体的にざっと性別情報の用途を挙げるとこんな感じです。

- 身分証明のための一項目として(行政などで)
- プロフィールの一項目として(SNSなどで)
- マーケティング目的(広告とかリコメンドとかの参考情報として)
- 利用可能な商品を分ける(保険とかは男女で商品が異なる場合があります)
- 異性間または同性間のマッチングサービス(出会い系)
- 侵入可能エリアの区分け
- etc.

これらを扱うようなシステムに関わる場合は、性別に関するプログラミング知識が必要になります。何も知らずに独自の実装をして失敗したくなければ。

# 性別情報をどのようにデータ化するのか

さて入力項目として持つからには当然データベースに値を登録するわけですが、何て登録すれば良いんでしょうか。何も知らない人たちで議論をすれば、いろんなアイデアが出ると思います。

- 直球勝負こそ正義。「男」「女」の文字列で持つ。
- 1バイトの数値で持ちたい。男は「1」で女は「2」って事にしよう。
- なんで女が2で男が1なんだ！女が1ではダメなのか！
- じゃあ同じ1バイトだし男は「M」で女は「F」にしよう
- たぶんこのMとかFとかの値は「Mother」と「Father」の頭文字だな(名推理)
- うちでは「男」「女」「子供」で分けてるからChildの「C」も欲しい

いろんな意見があるかもしれません。このままではシステムごとにバラバラの実装をされてしまって、新しい職場に慣れないプログラマが勘違いして不具合を出してしまうかもしれません。会社が合併して2社で持ってるお客様情報を統合するよとか言われたらコード体系の違いを吸収するためにSEさんが徹夜してしまうかもしれません。「まさかnullがあるなんて...」とか「0って何！？」みたいな悲鳴がオフィスにこだまするかもしれません。そんなことにならないために規格があります。


## 性別の表記に関する国際規格

データベースアプリケーションなどの情報システムで使用するためのヒトの性別の表記について、国際規格「ISO 5218」が定められています。特別な主義主張があって国際規格に反旗を翻したいのでなければ、あなたのシステムでもこの規格で定められたコード体系を採用しましょう。

ISO 5218 では性別とコードは以下のように定められています。簡単のために右に多言語対応についても併記しちゃいますが、原文を確認したい方は原文を読んでください。

> Human sex is represented by a one-character numeric code. 
> (人間の性別は、1文字の数字コードで表される)
> The following data elements and codes are used:
> (以下のデータ要素とコードを用いる)

| Data elements | Code   |   | 英語(米) | 日本語 |
|:--------------|:-------|---|:--|:--|
|Not known      |0 (zero)|   |not known|不明|
|Male           |1 (one) |   |male|男|
|Female         |2 (two) |   |female|女|
|Not applicable |9 (nine)|   |not applicable|適用不能|


0は性別に関する情報が得られない場合に使います。性別に関する情報はあるのだけど1とも2とも言えない場合は9を使います。要は「0でもなくて1でも2でもなければ9」です。
これを知っていればMだとかFだとかを議論をせずに済みますね。


## 国際規格に従うべき理由

国際規格に従うことは色々と利点があります。まず、どうしてそういうコード体系にしたのかを説明しやすいです。また多言語対応する際も規格通りに書けば伝わるはずなので迷わずに済みます。別システムへのデータの移行や、異なるシステム間でのデータの統合もコード体系が同じならラクラクです。もしかしたら別のプロジェクトで書いたコードをそのまま使いまわせるかもしれません。技術者に対するトレーニングも不要です。
対して、わざわざ国際規格に反する実装をする場合は上記のメリットがそのままひっくり返ってデメリットになりはしますが、もちろん、それなりの理由があれば規格とは別の実装をするのも全然有りです。どちらが良いとか悪いとかではなく、要求仕様次第です。


## では、データ型はどうなる？

ISO 5218 に従うならば、*one-character numeric code* と言うことなので、*char(1)*と言うことになります。もちろん、*one-character numeric code* なら数値として扱いたいと言う気持ちはわかります。しかしながら多くの言語で `1 == "1"` は成り立たないので、プログラムの再利用性のことを考えたら文字とするのが良いと思います。

また、 ISO 5218 ではnullを扱っていません。そのためもしデータにnullがあったら規格に沿わないデータが存在する状態になってしまうので、`not null`とするのが良いでしょう。値が分からないときは0なので、`default 0` として下さい。値の取りうる範囲を0,1,2,9に限定する制約をかけても良いですけど、さすがにやりすぎだと思います。環境によってはパフォーマンスに影響するので無駄に制約を増やすのはやめましょう。

列名は **sex** です。規格通りなので大きな声で設定しましょう。何に配慮したのか gender とかの列名を使う例もありますが、 ISO 5218 は Human sex の表記についての規格なので **sex** と書くのが正しいです。

まとめるとこうなります。

```sql
SEX CHAR(1) DEFAULT '0' NOT NULL
```

# 選択肢として表示するべきものは何か

さて、データベース上の定義が決まったら今度はフロントエンド側、ユーザーの画面に表示する話になります。

## ISO 5218 通りの選択肢を用意してみたらヒドかった

さっそく規格通りの選択肢を用意してみましょう。

![1523428324.png](https://qiita-image-store.s3.amazonaws.com/0/176146/ece5e71b-df91-b8c0-8074-dff03c85ad76.png)

待って。
**こんな選択肢、見たことない...**

こんな画面を用意したらみんなから「不明はいらない」とか「適用不能って何」とか「男性女性って書きなさい」とかふるぼっこにされてしまいます。なんでも規格通りに用意すれば良いってものじゃないのです。それもそのはず、 ISO 5218 は性別をコードで表すならこう、っていう規格であって、**「性別と言う項目の選択肢はこう出すべき」と言う規格ではない**のです。つまり、性別欄の選択肢をどうするべきかと言う話については規格がありません。JISにもありません。

## じゃあ、どうすればいい？

では選択肢はどうすれば良いのでしょうか。選択肢として用意した項目を**データ化する際にどのコードを割り当てるかは規格に沿えば良い**けれど、実は**選択肢として何を用意するかはこれから考えること**なのです。その情報を何に使うのか、誰に向けたサービスなのかによって異なります。

選択肢の仕様を決定するにあたって、考慮しなければならないのは以下の点です。

- 未入力を許容するか(回答必須とするか)
- 「適用不能(9)」にあたる選択肢(その他)を必要とするか
- 初期値は何か(たいていは選択無しを初期値とします)
- もっと複雑な選択を可能とするかどうか
- 文言をどうするか

### 未入力を許容するか(回答必須とするか)
これはサービスの性質によります。マーケティング情報として参考までに答えてくれるなら情報を収集したいと言うような場合は選択不要とするべきでしょうし、サービス提供の前提として性別情報が必要となるような場合は必須です。
「別に、性別くらい答えれば良いのでは？必須で良いじゃん？」と思う方がいらっしゃるかもしれません。しかし、性別を答えたくない人と言うのはそれなりの割合で存在していますので、不快感を与えないために必要な措置です。
具体的には女性をターゲットにした勧誘を受けたくないので性別を記入することに抵抗がある人だとか、自分の性別に違和感があってそれを明言したくない人だとか、それはプライベートな質問なので答える理由がないと考えている人も居ます。

### 「適用不能(9)」にあたる選択肢(その他)を必要とするか
これは男性女性以外のユーザーを想定しているかどうかによります。実際に存在しているので通常は想定するべきです。しかしながら男女どちらかの性別に対してのみ提供するサービスである場合や、本当に戸籍性のみを取り扱いたい場合、男女以外の存在からは目を背けたい特別の理由がある場合は不要かもしれません。
ちょっと変わったところで前述した「子供」だとか「ペット」のような性別以外の選択肢について議論が発生する場合、それは総じて性別とは別の項目で扱うべき項目です。お客様種別とかそう言う項目を作成し、性別と言う項目は削除すれば良いでしょう。

### 初期値は何か
初期値はたいていは空欄(▼選択してください)とかですが、女性をターゲットにしたサービスでは初期値が女性になっているものも多いです。シンプルに「男性」「女性」としたために初期値が男性になっているケースも見かけます。
また、初期値空欄で送信可能とすると回答してくれないユーザーが多くなってしまうため、任意回答でよいがなるべく多くの情報が欲しいという場合は初期値を空欄としつつ「回答しない」は明示的に選択させると言う方法もあります。実際この選択方法はよく見かけます。

### もっと複雑な選択を可能とするかどうか
SNSのように自分を表現するべきサービスでは、多種多様な性別についての考え方を表現するために「性別」のほかに「恋愛対象」を用意したり性別を自由記述できるようにするなどの対応が必要になる場合もあります。Google+では自由記述できるようになっていますし、Facebookでは自由記述に加えて数十種類の選択肢が用意されていたりします。(最初は英語だけでしたが割と最近になって日本語版でも利用できるようになったようです)

### 文言をどうするか
男女については一般的には日本語では「男性」「女性」が敵を作らなくて良いです。「男」「女」にすると直接的すぎるとか子供には適さない表現だとか色々と物言いが付きます。適用不能についてはだいたいは「その他」「それ以外」「不明」などです。ジェンダーを強く意識し、さらに細かい情報を必要とするなら自由記述欄を用意するのが良いでしょう。その場合はFacebookやGoogle+の前例にならって「カスタム」としたら誤解がないと思います。

# 結論

と言うわけでまとめると、これからの性別欄はこうするのがスタンダードになるかと思います。(コードは空欄が0でその他が9)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/176146/a36d9fc1-0fc7-1acc-1fc5-d63ee372db85.png)

また、なるべく多くの情報が欲しい等の理由で「回答しない」を明示的に選択させたい場合はこうなります。(空欄のまま決定できない仕様とし、回答しないのコードは0とする)
![1524019896.png](https://qiita-image-store.s3.amazonaws.com/0/176146/1634421f-f477-f9ef-3eb4-e8a0201c5544.png)


# 与太話

以下は性別に関する与太話です。

## Facebookでは国際規格が使われていない？

かの有名なSNSでは、性別についてのコードは(少なくとも表向きには) ISO 5218 が使われていません。具体的にはこうなっています。

- 女 (1)
- 男 (2)
- カスタム (6)

~~※ただし2018年4月現在、アカウント登録時には1か2を選択必須となっています。登録後に性別(gender)のプロフィール情報を変更可能です。もしかしたら裏では新規登録時の選択とは別の情報として持っていて何かに使っているのかもしれませんが、新規登録時のみ必須2値となっている合理的な説明がないのでいずれ改善されると思います。いつまでも改善されないとしたら多分裏で何かに使っていて捨てられない情報なんだと思います。~~

※2023年2月現在、上記は改善されていました。具体的には新規登録時にもカスタムを選択可能となり、またカスタムのvalueは-1となっていました。(女1男2はそのまま)フォームの名前はgenderになってるのにinputタグのname属性は相変わらずsexだったり、度重なる仕様変更でわけがわからなくなっています。皆さんはこうならないように最初から体系的なコードを使用すると良いでしょう。

どうして国際規格と異なるコード体系を使っているのか明言はされていないと思いますが、単にsexではなくgenderを扱っているからかもしれませんし、「レディファーストだから女を1にしているんだ」とか「データを抜かれても再利用しにくいように」とかの説もあります。

## (追記) 性別の入力を強制させるとAppleの審査でリジェクトされる？

コメントやらSNSで、「男」「女」と言う選択肢でアプリを作ると審査でリジェクトされると言う噂がありました。調べてみたんですが[App Store審査ガイドライン](https://developer.apple.com/jp/app-store/review/guidelines/)にこんな記述がありました。

>法律で要求される場合を除いて、アプリケーションを動作させるためにユーザーの個人情報の入力を要求することは許可されません。

「未回答」と言う選択肢が必要と言う話もありましたので、おそらく性別に限らず個人情報を回答必須とするのはNGのようです。「不明」や「その他」を用意しても回答を強制している事になってしまうので、対策としては「未回答」を用意するか回答しなくてもよい事にするのが良さそうです。情報をお寄せ頂いた方々に感謝。

## 性別の種類

ここまで「性別」と単に言ってきましたが、実のところ性別にはいろんな意味があります。

- (生物学上の)性別
- (遺伝学上の)性別
- (戸籍上の)(法的な)性別
- (生活上の)(社会的な)性別
- (自分が思う)性別

英語では上の方をsexと言って下の方をgenderとか言って区別していますね。もっと細かい区別を言うフレーズもあります。
ISO 5218 が示しているのは主にヒトの生物学的な性であったり法的な取り扱い上の性別、つまりsexのことであったりします。多くのシステムでは特に意識せず戸籍上の性別と同一だと思って性別を取り扱っていると思いますが、特定の意味での性別を強く意識しているケースもあります。いくつかのSNSでは自分が思う性別や恋愛対象を強く意識しているようです。

恋愛対象の話をするなら異性、同性のほかに両方とかどっちもダメだとか性別と恋愛対象が関係なかったりだとか細かい分類をすればキリがないですね。めんどくさいから恋愛対象が人間かどうかで分ければいいと思います。三次元か二次元かで分けても良いです。二次元ケモミミ限定とか言い出す人が居るのでもう分けるのは諦めたら良いと思います。

## 性別はめんどうくさい

さて性別と言うのは本当にめんどうくさいです。

例えば生物学上の性別と言うのは主に生殖機能を指して言いますので遺伝子上の性別とは違うものですよね。(途中で性別が変わるとか両性具有とか自然界ではザラですしね)

日本の場合は戸籍上の性別は医師の診断に基づく出生届に従いますが、まれに「判別不能」のため空白で出すケースもありますし、「後から違う性だとわかった」で訂正するケースもありますので生物学上の性別と戸籍上の性別も別のものです。日本の場合は婚姻は男性と女性の間でのみ認められていますが(2018年4月現在の話)、性別変更の手続きにより婚姻可能な性別も変わりますので戸籍上は女だけど妻がいたこともありましたとかの事例もよくありますね。

戸籍と異なる性別で普通に生活してるひともいますし、戸籍と自分の思う性別が異なると言うのも多いですね。もっと言うとそれも時系列とともに変化するので一定ではありません。

戸籍の話をするなら男性女性の二種類しかないのが標準ですけども、その決定方法は国によって異なり(たいてい医師の診断は不要)、性別変更もできたりできなかったり、基準もゆるゆるだったりきつきつだったりします。なのに帰化する時は元の国の戸籍性に従います。

性別変更と言えば多くのシステムでは個人情報の「性別」のところは変更不可になっていますけど、変更になるケースもあるのでその都度サポートが個別対応するくらいなら最初から変更可能にしておいた方が良いと思います。対応してくれないところは退会理由に「性別が変更できなかったので」とか書いておけばそのうちしれっと変更可能になるかもしれません。
~~余談ですがPlayStationNetworkさんは電話したら3分とかからずオペレータの方が手作業で変更してくれました。そもそも性別情報使ってない気がするから仕事を増やすくらいなら最初からそんな項目を用意しなければよかったのに。~~
[2019年10月追記]2019年頃(?)からPlayStationNetworkさんでは性別情報をアカウント管理のページからユーザーが任意に変更できるようになっていました。最初からそう設計しておけば余計な仕事は増えなかったのに。
免許証には性別欄はありませんが本籍と同じでデータ上は登録されていて、これも変更には手続きが必要ですね。しかしながらこれは姓名の変更なんかと同じ手続きになっていて、特に仕事が増える感じではないのでこういうのはこれで良いと思います。
クレジットカードにも性別情報が登録されています。性別によって限度額が変わったりするんでしょうか。何に使っているか不透明なのでそんな性別欄は削除してしまえば良いと思います。

パスポートの性別欄も多くの国で発行されるものはMとFですが、最近はXを用意する(またはその検討をしている)国も増えてきてます。日本は遅れているのでまだ当分先になりそうですけど。

要するに性別って**ただでさえめんどくさい**のに、**めんどくさい事を言うひとも多い**んですね。なるべく持ちたくないですね。システム設計の際には「この性別欄、本当に要る？」と一度考え直してみてください。たいてい要らないです。