2010-05-03 10 views
95

Quando si crea una tabella in SQLite3, mi confondo quando sono confrontati con tutti i possibili tipi di dati che implicano contenuti simili, quindi qualcuno potrebbe dirmi la differenza tra i seguenti tipi di dati?Qual è la differenza tra i tipi di dati SQLite correlati come INT, INTEGER, SMALLINT e TINYINT?

INT, INTEGER, SMALLINT, TINYINT 

DEC, DECIMAL 

LONGCHAR, LONGVARCHAR 

DATETIME, SMALLDATETIME 

C'è qualche documentazione da qualche parte che elenca il min./max. capacità dei vari tipi di dati? Ad esempio, suppongo che smallint contenga un valore massimo maggiore di tinyint, ma un valore inferiore a numero intero, ma non ho idea di quali siano queste capacità.

risposta

90

SQLite, tecnicamente, non ha tipi di dati, ci sono storage classes in un sistema di digitazione manifest, e sì, è confuso se siete abituati ai tradizionali RDBMS es. Tutto, internamente, è memorizzato come testo. I tipi di dati sono forzati/convertiti in varie posizioni di memoria in base alle affinità (tipi di dati ala assegnati alle colonne).

La cosa migliore che vi consiglio di fare è di:

  1. temporaneamente dimenticare tutto ciò che hai utilizzato per sapere di tipi di dati del database standalone

  2. Leggi il link qui sopra dal sito SQLite.

  3. Prendere le tipologie in base al largo del vostro vecchio schema, e vedere quello che avevano mappano in SQLite

  4. la migrazione di tutti i dati nel database SQLite.

Nota: Le limitazioni tipo di dati può essere ingombrante, soprattutto se si aggiunge durate di tempo o date, o cose del genere in SQL. SQLite ha pochissime funzioni integrate per quel genere di cose. Tuttavia, SQLite fornisce un modo semplice per rendere le proprie funzioni incorporate per l'aggiunta di durate di tempo e cose di quella natura, attraverso la funzione di libreria sqlite3_create_function. Dovresti usare quella funzione al posto delle tradizionali procedure memorizzate.

+1

Grazie per la risposta e il collegamento. Questo significa che dovrei attenermi ai tipi base di testo, numerico, intero, reale, nessuno? Sembra molto limitato a me, soprattutto da un background MSSQL, Foxpro e Oracle. Saluti. –

+5

Sono d'accordo con te, inizialmente sembra limitato.Tuttavia, penso che scoprirai che SQLite ti perdona molto nel modo in cui inserisci i dati nel database tramite il suo sistema di affinità. SQLite non è autonomo: è progettato per essere un piccolo backend di database che si inserisce in applicazioni di piccole dimensioni a cui accedere solo tramite un'API di accesso al database nel codice. Risolvere i problemi in SQLite è solitamente una questione di capire come vogliono che tu lo faccia. –

+0

Mi limiterei ai tipi di base. –

10

Molti di questi sono disponibili per la compatibilità. In realtà hai solo numero intero, float, testo e blob. Le date possono essere memorizzate come numero (unix time è intero, microsoft time è float) o come testo.

+0

Grazie. Devo rieducarmi dalla conoscenza del database precedente. All'inizio sembrava che l'approccio di SQLite ai tipi di dati fosse troppo limitante, ma ora penso che in realtà potrebbe essere più flessibile. Saluti. –

+0

L'ho usato per progetti basati sul web dove alla fine tutto è finito per essere inserito in una pagina HTML comunque. Ho rinunciato a un sacco di conversione dei dati e ho appena usato il testo per la maggior parte delle colonne. Ha funzionato bene. – Jay

+0

Grazie Jay, la maggior parte del mio lavoro SQLite sarà anche basato sul web, ma mi piacciono ancora i tipi di dati "vecchio stile". È bello sapere che una data verrà accettata e visualizzata in un formato specifico, anche se i dati sottostanti sono solo un numero! Cordiali saluti –

44

La differenza è zucchero sintattico. Solo alcune sottostringhe dei nomi dei tipi sono importanti per quanto riguarda l'affinità di tipo.

  • INT, INTEGER, SMALLINT, TINYINT → affinità INTEGER, perché contengono tutti "INT".
  • Affinità LONGCHAR, LONGVARCHAR → TEXT, perché contengono "CHAR".
  • DEC, DECIMAL, DATETIME, SMALLDATETIME → NUMERIC, perché non contengono nessuna delle sottostringhe che contano.

Le regole per la determinazione dell'affinità sono elencate allo SQLite site.

Se insistete sulla tipizzazione forte, è possibile implementare con CHECK vincoli:

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

Ma non ho mai perdere tempo con esso.

Per quanto riguarda la capacità di ogni tipo:

  • INTEGER è sempre segno a 64 bit. Si noti che SQLite ottimizza lo storage di piccoli numeri interi dietro le quinte, quindi TINYINT non sarebbe comunque utile.
  • REAL è sempre a 64 bit (double).
  • TEXT e BLOB hanno un maximum size determinato da una macro del preprocessore, che per impostazione predefinita è 1.000.000.000 di byte.
+0

dan04 - Grazie per queste informazioni e il link alla pagina 'Limiti' sul sito SQLite (non mi meraviglia che non potrei trovarlo - stavo cercando 'capacità' :-(). Cordiali saluti –

+0

Grazie. http://www.sqlite.org/draft/datatype3.html dice: "Questa tabella mostra solo un piccolo sottoinsieme dei nomi dei tipi di dati accettati da SQLite." Dove è possibile trovare l'elenco completo ufficiale, mi chiedo? – mlvljr

+1

Là non è uno. Puoi semplicemente inventare nomi di tipo arbitrari e SQLite non si lamenterà – dan04

3

NULL. Il valore è un valore NULL.

INTEGER. Il valore è un numero intero con segno, memorizzato in 1, 2, 3, 4, 6 o 8 byte a seconda della grandezza del valore.

REAL. Il valore è un valore in virgola mobile, memorizzato come numero in virgola mobile IEEE a 8 byte.

TEXT. Il valore è una stringa di testo, memorizzata utilizzando la codifica del database (UTF-8, UTF-16BE o UTF-16LE).

BLOB. Il valore è un blob di dati, memorizzato esattamente come è stato inserito.

1

In aggiunta alla risposta da dan04, se si desidera inserire ciecamente un NUMERIC diverso da zero rappresentato da un TEXT ma garantire che il testo è convertibile ad un numerica:

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

caso d'uso tipico è in una query da un programma che considera tutti i dati come testo (per uniformità &, poiché SQLite lo fa già). La cosa bella di questo è che permette costrutti come questo:

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

che è conveniente nel caso in cui si sta utilizzando segnaposto perché non c'è bisogno di gestire tali campi numerici diversi da zero appositamente. Un esempio utilizzando il modulo di Python sqlite3 sarebbe,

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

Nell'esempio di cui sopra, tutti i valori nella str_value_tuple sarà sfuggito e citato come stringhe quando passato a SQLite. Tuttavia, dal momento che non stiamo controllando esplicitamente il tipo tramite TYPEOF ma solo con la conversione nel tipo, funzionerà comunque come desiderato (ad esempio, SQLite lo memorizzerà come numerico o non funzionerà diversamente).

Problemi correlati