Reputation: 835
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.
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?
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#?
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!
Upvotes: 1
Views: 1151
Reputation: 180070
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.
Upvotes: 3