SQLite - kuotsanhsu/ccc GitHub Wiki
Datatypes In SQLite
SQLite uses a more general dynamic type system. In SQLite, the datatype of a value is associated with the value itself, not with its container.
The Advantages Of Flexible Typing
As of version 3.37.0 (2021-11-27), SQLite provides STRICT tables that do rigid type enforcement, for developers who prefer that kind of thing.
Database encoding (UTF-8, UTF-16BE or UTF-16LE)
StackOverflow, Check the encoding of text in SQlite
You can test the encoding with this pragma:
PRAGMA encoding;
You cannot change the encoding for an existing database. To create a new database with a specific encoding, open a SQLite connection to a blank file, run this pragma:
PRAGMA encoding = "UTF-8";
And then create your database.
Case-sensitivity
SQLite only understands upper/lower case for ASCII characters by default. The LIKE operator is case sensitive by default for unicode characters that are beyond the ASCII range. For example, the expression 'a' LIKE 'A' is TRUE but 'æ' LIKE 'Æ' is FALSE. The ICU extension to SQLite includes an enhanced version of the LIKE operator that does case folding across all unicode characters.
STRICT Tables
Primary key
Primary key as a table constraints can consist of more than 1 columns. The point of a primary key is to give a non-null unique handle to each row in the table.
Datetime
SELECT date(); -- time now
TEXT
as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").REAL
as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.INTEGER
as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can choose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.
Generated column
3.4. The GENERATED ALWAYS AS clause
There is no TIMESTAMP
column type
Constraint enforcement
Single quotes vs double quotes
- Single quotes are for strings.
- Double quotes are for identifiers.
NOT NULL constraints are not verified during queries, so a query of a column might produce a NULL value even though the column is marked as NOT NULL, if the database file is corrupt.
SQLite Foreign Key Support
Example: bibliography
/*
- https://dx.doi.org
https://www.doi.org/doi-handbook/HTML/case-insensitivity.html
> DOI names are case insensitive, using ASCII case folding for comparison of text. (Case insensitivity for DOI names applies only to ASCII characters. DOI names which differ in the case of non-ASCII Unicode characters may be different identifiers.) 10.123/ABC is identical to 10.123/AbC. All DOI names are converted to upper case upon registration, which is a common practice for making any kind of service case insensitive. The same is true with resolution. If a DOI name were registered as 10.123/ABC, then 10.123/abc will resolve it and an attempt to register 10.123/AbC would be rejected with the error message that this DOI name already existed.
*/
CREATE TABLE reference(
doi_prefix TEXT,
doi_suffix TEXT,
time_added INTEGER AS (unixepoch()) STORED
PRIMARY KEY (doi_prefix, doi_suffix)
) STRICT;
INSERT INTO reference values('10.1017', 'CBO9781107590120');
-- Runtime error: non-deterministic use of unixepoch() in a generated column
CREATE TABLE work(
doi_prefix TEXT,
doi_suffix TEXT,
time_added TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (doi_prefix, doi_suffix)
) STRICT;
INSERT INTO reference VALUES('10.1017', 'CBO9781107590120');
-- Parse error: table reference has 3 columns but 2 values were supplied
INSERT INTO reference(doi_prefix, doi_suffix) VALUES('10.1017', 'CBO9781107590120');
-- Good
/*********
* FINAL *
*********/
CREATE TABLE author(
name TEXT PRIMARY KEY,
) STRICT;
CREATE TABLE work(
doi_prefix TEXT,
doi_suffix TEXT,
kind TEXT, -- book, journal, etc.
time_added TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (doi_prefix, doi_suffix)
) STRICT;
CREATE TABLE author_work(
author_name TEXT REFERENCES author,
doi_prefix TEXT,
doi_suffix TEXT,
FOREIGN KEY(doi_prefix, doi_suffix) REFERENCES work
) STRICT;
CREATE TABLE book(
doi_prefix TEXT,
doi_suffix TEXT,
isbn13 TEXT CHECK (length(isbn13) = 13 AND rtrim(isbn,'0123456789') = ''),
title TEXT,
subtitle TEXT,
volume INTEGER CHECK (volumn >= 1), -- NOT NULL ?
edition INTEGER CHECK (edition >= 1), -- NOT NULL ?
year INTEGER CHECK (year <> 0), -- NOT NULL ?
PRIMARY KEY(doi_prefix, doi_suffix),
FOREIGN KEY(doi_prefix, doi_suffix) REFERENCES work
) STRICT;
CREATE TABLE series(
name TEXT PRIMARY KEY,
publisher TEXT,
) STRICT;
CREATE TABLE book_series(
doi_prefix TEXT,
doi_suffix TEXT,
series_name TEXT REFERENCES series,
issue INTEGER CHECK (issue >= 1), -- NOT NULL ?
FOREIGN KEY(doi_prefix, doi_suffix) REFERENCES book
) STRICT;
INSERT INTO author(name) VALUES(
'David Williams',
'Leonard Christopher Gordon Rogers',
);