1

I understand that SQLite does not have data type. But I'm not quite sure if it matters when creating table?

I was trying to generate the CREATE TABLE statement automatically. At the very beginning, I thought I should map the C# data types to SQLite data types until I read the description of storage class. This document confused me a bit, thus I think it's better to ask and correct my understanding.

  1. It says there are 5 storage classes, which are NULL, INTEGER, REAL, TEXT and BLOB. However, it also stated 5 affinities, TEXT, NUMERIC, INTEGER, REAL and BLOB, which doesn't map to the storage classes exactly. i.e., it doesn't have NULL affinity and what will NUMERIC map to in the storage class?

  2. Decimal in C# is a floating point, why it is mapped to NUMERIC affinity? Was that because REAL has 8 bytes max and Decimal has 16? Can SQLite store Decimal precisely as in C#?

  3. Why both Boolean and Decimal are mapped to NUMERIC? Boolean seems take the smallest storage (1 byte or even 1 bit), but Decimal takes much more. If NUMERIC is a single-byte type, it won't be able to store Decimal, or if it is multi-bytes, why don't Boolean mapped to INTEGER? It should be more efficient, shouldn't it? Or, should I completely forget the bytes of data type in SQLite?

Albeit these questions in my head, I tried to map a struct into table. Some sample code can be seen as follows (class/function structure excluded):

public sealed class ScreenInfo { public int ScreenId; public string Name; public int BoundX; public int BoundY; public int BoundW; public int BoundH; public int WorkingAreaX; public int WorkingAreaY; public int WorkingAreaW; public int WorkingAreaH; public int BitsPerPixel; public bool IsPrimary; public Rectangle Bounds { get { return new Rectangle(BoundX, BoundY, BoundW, BoundH); } set { BoundX = value.X; BoundY = value.Y; BoundW = value.Width; BoundH = value.Height; } } public Rectangle WorkingArea { get { return new Rectangle(WorkingAreaX, WorkingAreaY, WorkingAreaW, WorkingAreaH); } set { WorkingAreaX = value.X; WorkingAreaY = value.Y; WorkingAreaW = value.Width; WorkingAreaH = value.Height; } } } StringBuilder sb = new StringBuilder(); sb.Append("CREATE TABLE `Screens` (`id` INTEGER PRIMARY KEY AUTOINCREMENT"); var fields = typeof(ScreenInfo).GetFields(); foreach (var f in fields) { sb.Append($", `{f.Name}` {Type.GetTypeCode(f.FieldType).ToString()}"); } sb.Append(");"); 

The code above generates the following SQL statement. Although String and Int32 are not typical SQL data types, it seems to be working fine.

"CREATE TABLE `Screens` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `ScreenId` Int32, `Name` String, `BoundX` Int32, `BoundY` Int32, `BoundW` Int32, `BoundH` Int32, `WorkingAreaX` Int32, `WorkingAreaY` Int32, `WorkingAreaW` Int32, `WorkingAreaH` Int32, `BitsPerPixel` Int32, `IsPrimary` Boolean);" 

If the struct does not contain a field named id (otherwise it will conflict with the primary key), will it cause any other potential problems in the SQLite database?

Thanks in advance!

1 Answer 1

3

SQLite does have data types, it just uses dynamic typing, i.e., it does not restrict the types that can be inserted into a column.

Affinities are not storage classes; they describe the type that a column 'wants' to be. Therefore, there is no NULL afinity.

The NUMERIC affinity maps to either INTEGER or REAL, whatever is more efficient.

SQLite has no decimal type.

SQLite's storage classes are types, but the actual way how values are stored in the database is different. Integers can be smaller than 8 bytes, and booleans take 0 bytes.

Writing a column type as Int32 does not make it any different from any other type that maps to the INTEGER affinity; it would be useful only for documentation.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. Can I safely say I can use any column type in CREATE TABLE, and the only use for "correct" type is to let developer read the database easier?
Affinities can change the behaviour slightly.
Thanks. Just found a new article about affinities. It says if storing "0" to INTEGER affinity, it will convert to numeric 0, but in TEXT affinity it will retain "0". Is there any benefits (precision / performance) from using either of them? How about declaring none affinities at insert? e.g.: CREATE TABLE Screens (id INTEGER PRIMARY KEY AUTOINCREMENT, ScreenId, Name, BoundX, ...
The documentation you linked to explains how columns with and without affinities behave. You use whatever results in the behaviour you want.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.