INT、INTEGER、SMALLINT、TINYINTなどの関連するSQLiteデータ型の違いは何ですか?


101

SQLite3でテーブルを作成するとき、同様の内容を意味する可能性のあるすべてのデータ型に直面すると混乱するので、次のデータ型の違いを誰かに教えてもらえますか?

INT, INTEGER, SMALLINT, TINYINT

DEC, DECIMAL

LONGCHAR, LONGVARCHAR

DATETIME, SMALLDATETIME

最小値/最大値を記載したドキュメントがどこかにありますか?さまざまなデータ型の容量?たとえば、私smallintはより大きい最大値を保持していると思いますtinyintが、整数よりは小さい値ですが、これらの容量が何であるかはわかりません。

回答:


95

SQLite、技術的には、データ型がなく、マニフェスト型システムにストレージクラスがあります。そうです、従来のRDBMSesに慣れていると混乱します。内部的には、すべてがテキストとして保存されます。データ型は、アフィニティ(列に割り当てられたデータ型)に基づいて、さまざまな格納場所に強制/変換されます。

私があなたに勧める最高のことは、

  1. スタンドアロンデータベースのデータ型について知っていたすべてを一時的に忘れる

  2. SQLiteサイトから上記のリンクを読んでください。

  3. 古いスキーマに基づいて型を取り、それらが何にマッピングされるかを確認します SQLite

  4. すべてのデータをSQLiteデータベースに移行します。

注:データ型の制限は、特に期間、日付、またはそのようなものをで追加する場合、扱いにくい場合がありますSQLSQLiteそのようなことのための組み込み関数はほとんどありません。ただし、SQLiteでは、sqlite3_create_functionライブラリー関数を使用して、期間やその性質を追加するための独自の組み込み関数を簡単に作成できます。従来のストアドプロシージャの代わりにその機能を使用します。


1
返信とリンクをありがとう。これは、テキスト、数値、整数、実数、なしの基本的なタイプに固執する必要があるという意味ですか 特にMSSQL、Foxpro、Oracleの経歴を持っているため、私には非常に限られているようです。よろしく。
Alan Harris-Reid、

6
私はあなたに同意します、それは最初は制限されているようです。ただし、SQLiteは、アフィニティシステムを介してデータベースにデータを挿入する方法に非常に寛容であることがわかるでしょう。SQLiteはスタンドアロンではありません-小さなアプリケーションに配置する小さなデータベースバックエンドとして設計されており、コードでデータベースアクセスAPIを介してのみアクセスできます。SQLiteでの問題の解決は、通常、彼らがどのようにそれを実行したいかを理解することです。
J. Polfer

ベーシックタイプにこだわります。
J. Polfer

4
@Alan:数値アフィニティ列をDATEまたはとして宣言すると便利な場合がありますBOOLEANが、整数の異なるサイズを区別する必要はありません。これはINTEGER PRIMARY KEY、正確な型名が重要であるの場合に特に当てはまります。
dan04

「すべてがテキストとして保存されている」によると間違っているように思わsqlite.org/fileformat.html番号はコンパクトvarints /のfloat64として保存されている、とだけブロブとテキストは文字列として保存されていると言いれ、
phiresky

47

違いは構文糖です。型の類似性に関しては、型名の一部のサブストリングのみが重要です。

  • INT、INTEGER、SMALLINT、TINYINT→INTEGERアフィニティ。これらにはすべて「INT」が含まれているためです。
  • LONGCHAR、LONGVARCHAR→TEXTアフィニティ。 "CHAR"が含まれているためです。
  • DEC、DECIMAL、DATETIME、SMALLDATETIME→NUMERIC。重要な部分文字列が含まれていないためです。

アフィニティを決定するためのルールは、SQLiteサイトにリストされています

厳密な型付けを主張する場合は、CHECK制約付きで実装できます。

CREATE TABLE T (
   N   INTEGER CHECK(TYPEOF(N) = 'integer'),
   Str TEXT CHECK(TYPEOF(Str) = 'text'),
   Dt  DATETIME CHECK(JULIANDAY(Dt) IS NOT NULL)
);

しかし、私はそれを気にすることはありません。

各タイプの容量について:

  • INTEGER常に64ビット署名されています。SQLiteは舞台裏で小さな整数の格納を最適化するので、TINYINTはいずれにしても役に立たないことに注意してください。
  • REALは常に64ビット(double)です。
  • TEXTまた、プリプロセッサマクロによって決定される最大サイズBLOBがあり、デフォルトは1,000,000,000バイトです。

1
素敵なトリック。この方法で、と同じストレージクラスを使用するために、挿入/更新される値が必要であることに注意してくださいTYPEOF。したがって、そうでなければSQliteによってNUMERIC / INTEGERストレージクラスに変換されるTEXTを挿入しようとすると(つまり、そのような変換はsqlite.org/datatype3.html#affinityのように無損失で)失敗します。言い換えれば、このアプローチは、値を挿入し、SQLiteによってその値を格納するために使用されるストレージクラスを何らかの方法で魔法のように検証するアドホックなアプローチより厳密です。より寛容なアプローチについては、以下の私の答えを参照してください。
2015

10

それらのほとんどは互換性のためにあります。あなたは本当に整数、浮動小数点数、テキスト、ブロブしか持っていません。日付は数値(Unix時間は整数、Microsoft時間は浮動小数点数)またはテキストとして保存できます。


私はそれを最終的にすべてがとにかくhtmlページにテキストを挿入することになったWebベースのプロジェクトに使用しました。多くのデータ変換を省き、ほとんどの列にテキストを使用しました。それはうまくいきました。
ジェイ

3

NULL。値はNULL値です。

INTEGER。値は符号付き整数で、値の大きさに応じて1、2、3、4、6、または8バイトに格納されます。

REAL。値は浮動小数点値で、8バイトのIEEE浮動小数点数として格納されます。

TEXT。値はテキスト文字列で、データベースエンコーディング(UTF-8、UTF-16BE、またはUTF-16LE)を使用して保存されます。

BLOB。値はデータのblobであり、入力されたとおりに格納されます。


1

dan04からの回答への追加として、aでNUMERIC表されるゼロ以外を盲目的に挿入したいTEXTが、テキスト数値に変換可能であることを確認する場合:

your_numeric_col NUMERIC CHECK(abs(your_numeric_col) <> 0)

典型的な使用例は、すべてのデータをテキストとして扱うプログラムからのクエリです(SQLiteは既にそうしているので、統一性と単純さのために)。これの良い点は、次のような構成が可能であることです。

INSERT INTO table (..., your_numeric_column, ...) VALUES (..., some_string, ...)

このようなゼロ以外の数値フィールドを特別に処理する必要がないため、プレースホルダーを使用している場合に便利です。Pythonのsqlite3モジュールを使用した例は、

conn_or_cursor.execute(
    "INSERT INTO table VALUES (" + ",".join("?" * num_values) + ")",   
    str_value_tuple)  # no need to convert some from str to int/float

上記の例では、str_value_tupleSQliteに渡されるときに、すべての値がエスケープされ、文字列として引用されます。ただし、型を明示的にチェックするのではなく、型への変換性TYPEOFのみをチェックするため、それは引き続き期待どおりに機能します(つまり、SQLiteは数値として格納するか、それ以外の場合は失敗します)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.