在 SQLITE 中,考虑到主键必须具有唯一值,为主键指定整数类型是否重要?
In SQLITE, does specifying the integer type for Primary Keys matter considering that primary keys must have unique values?
当有人问SQLITE中整数类型的区别时:
What is the difference between SQLite integer data types like int, integer, bigint, etc.?
答案宣称它对 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.
A SqlLite "integer" can hold whatever you put into it: from a 1-byte char to an 8-byte long long.
当我想到将整数存储到容器中时,容器的签名可以随同一个值而变化。
0000 0000 0000 0001 = 1
0000 0001 = 1
相反,无符号整数和整数可以具有相同的签名但不同的值:
1111 1111 1111 1111 1111 1111 1111 1111 = -1
1111 1111 1111 1111 1111 1111 1111 1111 = 4294967295
所以我有点困惑,如果我指定类型,它对主键是否重要,因为手册指出:
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.
据此,我必须假设声明列的特定整数类型是以下之一:
INT
INTEGER
TINYINT
SMALLINT
MEDIUMINT
BIGINT
UNSIGNED BIG INT
INT2
INT8
很重要,因为我假设数据类型可以具有完全相同的签名和不同的值,反之亦然,因此以某种方式违反了 must contain unique values
规范。
所以最终我的问题是,将主键的数据类型声明为特定的 TINYINT SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8
有什么不同吗?
我需要知道这一点,因为我正在使用 SQLITE 创建键值存储,并且希望能够为所有可能的数据类型设置键。如果 TINYINT
和 INTEGER
之间没有区别,那么我就不会费心将 TINYINT
作为可能的键数据类型。
列类型 INT、INTEGER、WHATEVER(您几乎可以指定任何列类型)几乎没有影响,它指示要存储在列中的内容。但是,它没有设置可以存储的数据的类型(有待讨论)。简而言之,任何类型(例外除外)的数据都可以存储在任何列中(与定义的列类型无关)。
- 参见下文link中的3.1 柱亲和力的测定
SQL 不区分存储 class 以外的存储值(null、integer、real、text、blob),如果存储为 INTEGER 那么它是一个整数,仅由它最多存储 8 个字节(64 位有符号)的限制。
- 参见 2。存储 类 和数据类型 在 link 下面
异常是在table级别使用INTEGER PRIMARY KEY或INTEGER作为主键的列。存储的值 必须 是一个整数,否则将发生数据类型不匹配。
- 根据SQLite 版本 3 数据库中的任何列,INTEGER PRIMARY KEY 列除外,可用于存储任何存储 class 的值。 (也在2.存储类和数据类型中)
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?
不适用于列出的类型 (TINYINT ....),因为这些类型都包含 INT,它们将具有 INTEGER 的类型关联,并且该列将 NOT 是以下的别名rowid 列。
如果您在列表中包含 INTEGER 那么 YES 它会有所不同,因为该列将成为 rowid 的别名列(即它是 INTEGER PRIMARY KEY)。该列也将被限制为整数值(使用其他列出的类型的列将不会被限制为整数值)。
您不妨参考Datatypes in SQLite
下面的 SQL 演示了上面的一些内容:-
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;
第一个SELECT的结果将是:-
- 请注意,根据工具(SQLite 的 Navicat)处理 blob 显示的方式,blob handled/displayed。
最后一个 INSERT 失败,因为插入到 rowid 别名中的值不是整数值,例如:-
/* WILL FAIL as rowid alias is not an integer */
INSERT INTO example VALUES('a','a','a','a','a','a')
> datatype mismatch
> Time: 0s
- 注意答案没有处理列亲和力如何影响数据提取的复杂性。
当有人问SQLITE中整数类型的区别时:
What is the difference between SQLite integer data types like int, integer, bigint, etc.?
答案宣称它对 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.
A SqlLite "integer" can hold whatever you put into it: from a 1-byte char to an 8-byte long long.
当我想到将整数存储到容器中时,容器的签名可以随同一个值而变化。
0000 0000 0000 0001 = 1
0000 0001 = 1
相反,无符号整数和整数可以具有相同的签名但不同的值:
1111 1111 1111 1111 1111 1111 1111 1111 = -1
1111 1111 1111 1111 1111 1111 1111 1111 = 4294967295
所以我有点困惑,如果我指定类型,它对主键是否重要,因为手册指出:
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.
据此,我必须假设声明列的特定整数类型是以下之一:
INT
INTEGER
TINYINT
SMALLINT
MEDIUMINT
BIGINT
UNSIGNED BIG INT
INT2
INT8
很重要,因为我假设数据类型可以具有完全相同的签名和不同的值,反之亦然,因此以某种方式违反了 must contain unique values
规范。
所以最终我的问题是,将主键的数据类型声明为特定的 TINYINT SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8
有什么不同吗?
我需要知道这一点,因为我正在使用 SQLITE 创建键值存储,并且希望能够为所有可能的数据类型设置键。如果 TINYINT
和 INTEGER
之间没有区别,那么我就不会费心将 TINYINT
作为可能的键数据类型。
列类型 INT、INTEGER、WHATEVER(您几乎可以指定任何列类型)几乎没有影响,它指示要存储在列中的内容。但是,它没有设置可以存储的数据的类型(有待讨论)。简而言之,任何类型(例外除外)的数据都可以存储在任何列中(与定义的列类型无关)。
- 参见下文link中的3.1 柱亲和力的测定
SQL 不区分存储 class 以外的存储值(null、integer、real、text、blob),如果存储为 INTEGER 那么它是一个整数,仅由它最多存储 8 个字节(64 位有符号)的限制。
- 参见 2。存储 类 和数据类型 在 link 下面
异常是在table级别使用INTEGER PRIMARY KEY或INTEGER作为主键的列。存储的值 必须 是一个整数,否则将发生数据类型不匹配。
- 根据SQLite 版本 3 数据库中的任何列,INTEGER PRIMARY KEY 列除外,可用于存储任何存储 class 的值。 (也在2.存储类和数据类型中)
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?
不适用于列出的类型 (TINYINT ....),因为这些类型都包含 INT,它们将具有 INTEGER 的类型关联,并且该列将 NOT 是以下的别名rowid 列。
如果您在列表中包含 INTEGER 那么 YES 它会有所不同,因为该列将成为 rowid 的别名列(即它是 INTEGER PRIMARY KEY)。该列也将被限制为整数值(使用其他列出的类型的列将不会被限制为整数值)。
您不妨参考Datatypes in SQLite
下面的 SQL 演示了上面的一些内容:-
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;
第一个SELECT的结果将是:-
- 请注意,根据工具(SQLite 的 Navicat)处理 blob 显示的方式,blob handled/displayed。
最后一个 INSERT 失败,因为插入到 rowid 别名中的值不是整数值,例如:-
/* WILL FAIL as rowid alias is not an integer */
INSERT INTO example VALUES('a','a','a','a','a','a')
> datatype mismatch
> Time: 0s
- 注意答案没有处理列亲和力如何影响数据提取的复杂性。