在 SQLITE 中,考虑到主键必须具有唯一值,为主键指定整数类型是否重要?

当有人问到 SQLITE 中整数类型的区别时:

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

答案声明它对 SQLITE 不重要,因为:

SQLite 使用更通用的动态类型系统。在 SQLite 中,值的数据类型与值本身相关联,而不是与其容器相关联。

SqlLite“整数”可以保存你放入其中的任何内容:从 1 字节字符到 8 字节长。

当我想到将整数存储到容器中时,容器的签名可以随同一个值而变化。

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

所以我有点困惑如果我指定类型是否对主键重要,因为手册指出:

主键是表中的一个字段,它唯一标识数据库表中的每一行/记录。 主键必须包含唯一值。主键列不能有 NULL 值。

由此,我必须假设为列声明特定的整数类型,是其中之一:

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 创建一个键值存储,并且希望能够为所有可能的数据类型设置键。如果 TINYINTINTEGER 之间没有区别,那么我不会费心将 TINYINT 作为可能的键数据类型。

tongfang001 回答:在 SQLITE 中,考虑到主键必须具有唯一值,为主键指定整数类型是否重要?

列类型 INT、INTEGER、WHATEVER(您几乎可以指定任何列类型)几乎没有影响,它表示要存储在列中的内容。但是,它没有设置可以存储的数据的一种例外(将要讨论)的类型。简而言之,任何类型(除外)的数据都可以存储在任何列中(与定义的列类型无关)。

  • 请参阅以下链接中的3.1 列亲和性的确定

SQL 不区分存储类(null、integer、real、text、blob)以外的存储值,如果存储为 INTEGER,则它是一个整数,仅受其存储限制为最多 8字节(64 位有符号)。

  • 2。存储类和数据类型在下面的链接中

例外是专门使用 INTEGER PRIMARY KEY 或 INTEGER 并将列设置为表级别的主键。存储的值必须是一个整数,否则会发生 DATATYPE MISMATCH。

  • 根据 SQLite 版本 3 数据库中的任何列(INTEGER PRIMARY KEY 列除外)都可用于存储任何存储类的值。 (也在2.存储类和数据类型

所以最终我的问题是,将主键的数据类型声明为 TINYINT SMALLINT、MEDIUMINT、BIGINT、UNSIGNED BIG INT、INT2、INT8 之一会有什么不同吗?

不适用于列出的类型 (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'),(100,100,100),(34.5678,34.5678),(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');
DROP TABLE IF EXISTS example;

第一个 SELECT 的结果将是:-

enter image description here

  • 请注意,blob 是根据工具(Navicat for SQLite)处理 blob 显示的方式来处理/显示的。

最后一个 INSERT 失败,因为插入到 rowid 别名中的值不是整数值,例如:-

/* WILL FAIL as rowid alias is not an integer */
INSERT INTO example VALUES('a','a')
> datatype mismatch
> Time: 0s
  • 请注意,答案并未涉及列亲和性如何影响数据提取的复杂性。
本文链接:https://www.f2er.com/13986.html

大家都在问