0

When someone asked the difference between integer types in SQLITE:

What is the difference between SQLite integer data types like int, integer, bigint, etc.?

The answer declared it unimportant for SQLITE because:

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.

A SqlLite "integer" can hold whatever you put into it: from a 1-byte char to an 8-byte long long.

When I think of storing integers into a container, the signature of the container can vary with the same value.

0000 0000 0000 0001 = 1
          0000 0001 = 1

Conversely an unsigned integer and an integer can have the same signature but different values:

1111 1111 1111 1111 1111 1111 1111 1111 = -1
1111 1111 1111 1111 1111 1111 1111 1111 = 4294967295

And so I am a bit confused whether it matters for primary keys if I specify the type, because the manual states:

A primary key is a field in a table which uniquely identifies the each rows/records in a database table. Primary keys must contain unique values. A primary key column cannot have NULL values.

From this, I have to assume that declaring the specific integer type for a column, being one of:

INT
INTEGER
TINYINT
SMALLINT
MEDIUMINT
BIGINT
UNSIGNED BIG INT
INT2
INT8

is important because I assume that datatypes can have exact same signatures with different values and vice versa, thus violating the must contain unique values specification somehow.

So ultimately my question is, will declaring the datatype of a primary key to be specifically be one of TINYINT SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8 make any difference whatsoever?

I need to know this because I am making a key value store with SQLITE, and want to have the ability to set keys for all the possible datatypes. If there is no difference between TINYINT and INTEGER, then I won't bother having TINYINT as a possible key datatype.

Anon
  • 2,267
  • 3
  • 34
  • 51
  • Ask 1 specific researched non-duplicate question. It's not cledar what you are tying to say or what you what to do that you can't do or how the language is that you don't want or why how the langauge could be but isn't matters. What does "specifying the integer type for the primary key is not important" mean? As opposed to what? What do you mean "signature" and what is it relevant? Or "deviating from the set type"? Why do you think your "same value" is relevant rather than the definition of the language? A column has to have a SQL type & that is the value in the column. – philipxy Jul 29 '21 at 18:45
  • Put what is needed to ask your question in your post, not just at a link. Paraphrase or quote from other text. Give just what you need & relate it to your problem. – philipxy Jul 29 '21 at 18:48
  • There are multiple types allowed for PKs--see the manual. There are reasons why certain types are preferred--asked many time already. Please before considering posting read the manual & google any error message & many clear, concise & precise phrasings of your question/problem/goal, with & without your particular names/strings/numbers, 'site:stackoverflow.com' & tags; read many answers. Reflect your research. See [ask], [Help] & the voting arrow mouseover texts. If you post a question, use one phrasing as title. – philipxy Jul 29 '21 at 18:54
  • My long comment sentence has typos, it should be "It's not clear what you are tying to say, or what you want to do that you can't do, or how the language is that you don't want, or how the language could be but isn't matters." – philipxy Jul 29 '21 at 19:15
  • All my comments still apply. You are using notions not part of the language semantics & unexplained & not relevant. ("signatures" & "signatures with different values".) Are you trying to talk of data type representations? Why would they matter? The language defines what types have what values written by what literals & with what operators & coersions & conversions & how they work. Please simplify this. Use appropriate terms & meanings. Give a concrete example. [mre] Please act on the rest of my comments. (Quote not link, etc.) PS UNIQUE just means a value appears at most 1 time in a column. – philipxy Jul 29 '21 at 19:49
  • https://www.sqlite.org/datatype3.html – philipxy Jul 29 '21 at 20:44

1 Answers1

2

The column type INT, INTEGER, WHATEVER (you can specify virtually any column type) has little bearing, it's an indication of what is to be stored in the column. However, it does not set the type as with one exception (to be discussed) of data that can be stored. In short any type (bar the exception) of data can be stored in any column (irrespective of the defined column type).

  • see 3.1 Determination of Column Affinity in the link below

SQL does not differentiate between stored values other than the storage class (null,integer,real,text,blob), if stored as an INTEGER then it is an integer bound only by the limitations of it being stored in at most 8 bytes (64 bit signed).

  • see 2. Storage Classes and Datatypes in the link below

The exception is the use specifically of INTEGER PRIMARY KEY or INTEGER with the column set as the primary key at the table level. The value stored MUST be an integer otherwise a DATATYPE MISMATCH will occur.

  • as per Any column in an SQLite version 3 database, except an INTEGER PRIMARY KEY column, may be used to store a value of any storage class. ( also in 2. Storage Classes and Datatypes)

So ultimately my question is, will declaring the datatype of a primary key to be specifically be one of TINYINT SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8 make any difference whatsoever?

Not with the listed types (TINYINT ....) as the types all contain INT they will have a type affinity of INTEGER and the column will NOT be an alias of the rowid column.

If you included INTEGER in the list then YES it will make a difference as the column will then be an alias of the rowid column (i.e. it is INTEGER PRIMARY KEY). The column will also be restricted to being an integer value (the columns using the other listed types will not be restricted to integer values).

You may wish to refer to Datatypes in SQLite

The following SQL demonstrates some of the above:-

DROP TABLE IF EXISTS example;
CREATE TABLE IF NOT EXISTS example (
    rowid_alias_must_be_unique_integer INTEGER PRIMARY KEY, -- INTEGER PRIMARY KEY makes the column an alias of the rowid
    col_text TEXT,
    col_integer INTEGER,
    col_real REAL,
    col_BLOB BLOB,
    col_anyother this_is_a_stupid_column_type  -- will have a type affinitiy of NUMERIC
);

/* INSERTS first row with a negative rowid */
INSERT INTO example VALUES (-100,'MY TEXT', 340000,34.5678,x'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff',100);
/* All subsequent inserts use the generated rowid */
/* the same value is inserted into all the other columns */
INSERT INTO example (col_text,col_integer,col_real,col_blob,col_anyother) VALUES
    ('MY TEXT','MY TEXT','MY TEXT','MY TEXT','MY TEXT'),
    (100,100,100,100,100),
    (34.5678,34.5678,34.5678,34.5678,34.5678),
    (x'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff',x'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff',x'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff',x'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff',x'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff')
;

SELECT 
    *,
    rowid, 
    typeof(rowid_alias_must_be_unique_integer),
    typeof(col_text), 
    typeof(col_integer),
    typeof(col_real),
    typeof(col_blob),
    typeof(col_anyother)
FROM example
;
/* WILL FAIL as rowid alias is not an integer */
INSERT INTO example VALUES('a','a','a','a','a','a');
DROP TABLE IF EXISTS example;

The result of the first SELECT will be :-

enter image description here

  • Note that blobs are handled/displayed according to how the tool (Navicat for SQLite) handles the display of blobs.

The last INSERT fails because the value being inserted into the rowid alias is not an integer value e.g. :-

/* WILL FAIL as rowid alias is not an integer */
INSERT INTO example VALUES('a','a','a','a','a','a')
> datatype mismatch
> Time: 0s
  • Note that the answer has not dealt with the intricacies of how the column affinity may effect the extraction of data.
MikeT
  • 51,415
  • 16
  • 49
  • 68
  • Out of all the questions I have ever asked on Stack Overflow, this is probably the best quality answer I've ever received. Thanks. – Anon Jul 30 '21 at 12:44
  • I want to create an INTEGER UNSIGNED primary key, how can I make an alias for rowid? I read https://sqlite.org/lang_createtable.html#rowids_and_the_integer_primary_key but couldn't figure out whether my use case is supported. – pylipp Nov 30 '21 at 10:47
  • 1
    @pylipp you cannot you should read https://www.sqlite.org/datatype3.html. In short the primary purpose of the rowid column is to uniquely identify a row. To try to use the rowid for other purposes is very likely going to result in wants not being fullfilled. – MikeT Nov 30 '21 at 18:28