DB(データベース)のデータ型 について
自分の理解 や 解釈している内容を書き出してみる、メモです
---
■各データ型 をどのように使い分けたらいいのか? について。
CHAR型 きゃら、ちゃー、とも
→ charは商品コードのような長さが固定、または後方に空白があっても問題がない場合に使用します。
仮に、フィールドに格納されるデータとして「長い文字数のデータ」を格納する事が想定される場合でも、
フィールドに値として格納されるデータの末尾に、自動的に「列サイズ定義の長さ分の 空白文字(␣スペース) 」が付け加えられても支障がない場合には、charを使用できます。
char とは...文字を指す英語 character(文字、キャラクター)の略
VARCHAR型 ばーきゃら、ばーちゃー、とも
→ varcharは、charのように長さが固定でなかったり、最長でも長さが想定できる値を格納する場合に使います。
例えば、人名や商品名などであれば、30 文字とか100文字とかを上限に設定できると思います。
無制限に長さが必要になることはない場合に使います。
varcharはデータサイズが 可変長 のデータ形式なので、
charと違って、データの末尾に、無駄な「空白(スペース)で埋められる領域」を持つ必要がありません。
そのため、格納するデータの末尾に無駄な空白を持たせたくない場合にも、 varchar を使用できます。
これは、PGなどでデータ加工する際に文字連結するなどの操作が容易になる、というメリットもあります。
text型 てきすと
→ textは、事前に最大長を設定や想定できない場合に使うデータ型です。
例えば、「記事データ」のテーブルを作ったとして、タイトルなどはvarcharで管理可能ですが、
記事の本文は最大長を決められなかったりします。そういった場合には、text を使います。
---
■各データ型の パフォーマンスとかコスト の話
charは固定長なので、その列に格納されるデータ(文字列)についてもサイズが固定されます
char型のフィールドに格納したい 値 として入力された文字列は、文字列が "列長サイズ分" のデータになるように、
(= サイズが「固定長」のデータ となるように)
文字列の末尾に、列長サイズに対して余っている文字数分「' '半角スペース」が追加されて、埋められる。
→ 例:列長「5文字」のchar型 の場合char(5)
char(5) に対して値を格納する場合は、
abc を格納した場合→ 格納されるデータはabc␣␣のようになる
a␣bcを格納した場合→ 格納されるデータはa␣bc␣のようになる
※␣はスペース
charのコスト面:
固定長で格納するために、データとしては無駄なスペースができることはあるが、
RDBMS的には固定長である方が処理は簡単になるためオーバーヘッドは小さい。
--
varcharのコスト面:
固定長のcharと比べると、データ領域上に無駄なスペースを持つ必要はなくなりますが、
フィールド上に格納されているデータについて、それぞれの「データの長さ」を考慮する必要がある分、
RDBMSの作業的には、固定長よりはオーバーヘッドが生じます。
また、フィールドの「最大長」を定義する際に、
データの最大長として適切なサイズを設定しないと、後々、問題が生じてしまう場合があります。
最大長が30文字や100文字といったものなら殆ど無視できますが、
varchar(max)のような最大長が30000万文字といったデータが多量に存在するならオーバーヘッドは無視できなくなる場合があります。
---
列長が無制限のため「最大長がどうなるのか分からないデータ型」とも言えます。
textのコスト面:
→ text は色々なオーバーヘッド要因や機能の制約があったりします。
「最大長が 無制限」なデータなので、RDBMS的には扱いづらいです。
例えば、、textで定義された列値は、
仮に1文字しか格納してなくても「最大長がどのくらいになるか分からない」ので、オーバーヘッドが生じます。
(↓) また、次のような操作も、最大長が 無制限 では、RDBMSとしては処理できません。
上記のような操作は、varcharの最大長に制限を設けていたり、textは最初から動作の対象外にされていたりします。
---
■「text型のオーバーヘッド」についての補足 的な話。
(RDBMSにより違いはあると思いますが 、、)
例えば、text型の 1件 のデータをテーブル上のフィールドに「格納」するとき、
DBMS上では、内部的には次のような事が行われたりします。
1件分のデータが、複数に分割されて、
物理的に、別々の場所にある複数の行(レコード)に分けられて格納されたりする。
なので、他のデータ型と比較すると、
データを読み書きする際に余計にオーバーヘッドが生じたり、ストレージのデータ量が膨大になったりする。
また、DBMSによっては、DBが持つ機能として、
text型を扱う際のオーバーヘッドを減らすための特別な実装があったりします。
例えば、PostgreSQLは、元々、各列の値を物理的には別レコードで格納している。(らしい)
SQLiteはいくつかのデータ型があるが、内部的にはすべてtext型で管理している.. (らしい)
..
上記のようなアーキテクチャを持つDBMSを使用する場合には、
textのオーバーヘッドが改善されているため、
あまり深く考えずtext型を使っても構わない。という事が言われる場合もあります。
..
→ しかし、この深く考えずtext型を使っても構わない というのは、
あくまで「オーバーヘッドが軽減されている」というだけであって、
次のような場合には、text型は使うべきではない。です
インデックスを定義したり、ソートしたりしたい列には、使用できません。
また、text型の列の場合、検索条件に制限が生じる場合もあります。
(インデックスが使えず検索コストがかかってしまうため、)
LIKE条件が使えず、全文検索といった特別な仕組みを組み込んだりする事が必要になる事もあります。
---