92583


MySQL5.7において、CHARとVARCHARをどのように使い分ければよいのでしょうか？  
下記のような理解をしていたのですが、固定長の文字列もVARCHARに入れてすべてVARCHARでもよいのでしょうか？

  * CHARは固定長のため、固定長の文字列を格納する
  * VARCHARは可変長のため、固定長ではない文字列を格納する


CC BY-SA 4.0
2022-12-05T00:52:56.100
92580
2022-12-07T12:53:29.780
19297
question
mysql database
MySQLにおけるCHARとVARCHARの使い分け


mysql5.7におけるvarcharとcharの違いは以下のとおりです。  
<https://dev.mysql.com/doc/refman/5.7/en/char.html>

> trailing spaces are removed from CHAR columns upon retrieval.

とあるとおり、以下のような違いがあります。

[code]

    create table example(a varchar(10), b char(10));
    insert into example values('A', 'B');
    insert into example values('         A', '         B');
    insert into example values('A         ', 'B         ');
    select a, length(a), b, length(b) from example;
    
[/code]

[code]

    +------------+-----------+------------+-----------+
    | a          | length(a) | b          | length(b) |
    +------------+-----------+------------+-----------+
    | A          |         1 | B          |         1 |
    |          A |        10 |          B |        10 |
    | A          |        10 | B          |         1 |
    +------------+-----------+------------+-----------+
    
[/code]

末尾空白でない固定長データを扱う場合はcharでいいと思いますが、varcharでも長さ情報を含められる容量的な余裕があれば(ほぼ)同じです。

#### 余談

個人的な感覚で言えば、(汎用機など)外から来る固定長のデータ以外は慣習的にvarchar(oracleならvarchar2)にしてる気がします。


CC BY-SA 4.0
2022-12-05T02:42:02.680
92583
2022-12-05T02:42:02.680
54957
92580
answer


固定長文字列だからといってchar(100)だったら必ず100文字の文字列しか保存できない、というわけではありません。

固定長文字列と可変長文字列の「固定」と「可変」は文字列そのものではなくデータ量だと思ってください。

char(100)とvarchar(100)はいずれも100文字までの文字列を保存できますが、前者は格納しているのが0文字だろうと100文字だろうと100文字分の記憶領域を消費します。一方後者は実際に保存している文字数に応じて消費が増減します。

固定長文字列の場合、指定した文字数より実際に格納した文字列が短い場合は慣例的に後ろがスペースで埋められます。挿入した文字列末尾にスペースが含まれていた場合それがデータなのかパディングなのか区別がつかなくなります。固定長文字列で「後続スペースが無視される」のはいわば副作用です。

なおRDBMSによっては(MYSQLの場合 PAD_CHAR_TO_FULL_LENGTH
SQLモードを設定した場合)、データを取り出すときにパディングを含めて取り出すことができます。昔のキャラクタベースの画面などデータが一定長であることが都合のいいアプリケーションには便利だったと思います。

あとMYSQL特有の問題としてutf8/utf8mb4(のような可変長エンコーディングの文字コード)を使うと無駄が大きくなります。MYSQLのutf8は1文字を1～3バイト、utf8mb4は1～4バイトで表現しますが、文字列が確定しないとデータ長が確定しません。でも固定長文字列はあらかじめ記憶領域が確定する必要があるので、1文字3バイトまたは4バイトで決め打ちする仕様です。そこで実際に投入されるデータがASCII文字だけだとスペース効率が1/3とか1/4になってしまいます。

固定長文字列は

  * データ量が確定するので記憶領域の見積もりがしやすくなる
  * 更新時確実にその場でデータが上書きできる(可変長の場合、元より長いデータに更新しようとすると余計な処理が必要)

という利点があります。が、大昔のシステムならともかく今時の環境ではメリットとは言いがたくなっています。よっぽどのことがない限り可変長文字列を使った方がいいでしょう。


CC BY-SA 4.0
2022-12-07T12:53:29.780
92625
2022-12-07T12:53:29.780
5793
92580
answer