読者です 読者をやめる 読者になる 読者になる

すがブロ

sugamasaoのhatenablogだよ

SQLite3の実際の型

ruby rails sqlite3 sql

SQLiteの型のなぞ

SQLite3の型はスゲーざっくりしていると聞いていたのだけど、RailsでデータベースをSQLiteにして、適当なテーブルを作成したら、なんか varchar とか出てくる。どういうことなんだってばよ? というのを調査してみた。

まずはRailsでテーブルを作るところまで

結論から言うと、別にRailsを使う必要は無いんだけども、まぁせっかくなんでね。

ちなみに、-T は unit/test のテンプレートを作らないというオプションで、単なる手クセなので気にしないで(普段はrspecを使うので)。

% rails new sample -d sqlite3 -T 
(snip)
cd sample
% rails g scaffold blog title:string body:text like:integer
% bundle  exec rake db:migrate

ちなみに、ここの例ではテキトーなブログシステムを作る、みたいのを想定してもらいたい。likeはそのブログに対するいいね数みたいなものだと思って。

データの確認

まず、念のためRails側のmigrateでどんな型が指定されているかを確認する。

% cat db/migrate/20111113064850_create_blogs.rb
class CreateBlogs < ActiveRecord::Migration
  def change
    create_table :blogs do |t|
      t.string :title
      t.text :body
      t.integer :like

      t.timestamps
    end
  end
end

あたりまえだけど、指定した通りである。
さて、SQLiteでDBを開いてみよう(rails db とかでも大丈夫だと思うけど)。

% sqlite3  db/development.sqlite3 

では、さっきのテーブルの中身を見てみよう。

sqlite> .dump blogs
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE "blogs" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "body" text, "like" integer, "created_at" datetime, "updated_at" datetime);
COMMIT;

整形してなくてアレだけど、varchar や datetime とかが指定されてる。無いんじゃないの。

ここからが本題

こういう時は公式のドキュメントにあたるのが一番ですね。

で、ここをきちんと読んでみると、1.0 Storage Classes and Datatypes に、データ型として5つあるよと書いてある(このデータ型はカラムの型ではなく、実データを扱う際の型らしい?)。

  • NULL
  • INTEGER
  • REAL
  • TEXT
  • BLOB

さらに、1.2 では Date型を保持する型としては TEXT の場合と REAL の場合と INTEGER の場合があるとか書いてある。

カラムの型は

2.0 Type Affinity に書いてある。SQLite3ではこの5つが定義されているようだ。

  • TEXT
  • NUMERIC
  • INTEGER
  • REAL
  • NONE

つまり、SQLiteの実際のカラムの型っていうのは、ここの事らしい。で、更にその下 2.2 Affinity Name Examples に他のSQLとの互換のためにどのような型指定の場合はどの型に変換されるかのテーブルがある。

というわけで

今回の場合だと以下のような型に変換されているような気がする。

  • title => TEXT
  • body => TEXT
  • like => INTEGER
  • created_at => NUMERIC
  • updated_at => NUMERIC

なんとなくわかったのだけど、その変換された型を実際に確認する場合ってどうすれば良いんですかね。。。