【问题标题】:How to create ENUM type in SQLite?如何在 SQLite 中创建 ENUM 类型?
【发布时间】:2011-07-15 00:44:30
【问题描述】:

我需要将表从 MySQL 转换为 SQLite,但我不知道如何转换枚举字段,因为我在 SQLite 中找不到ENUM 类型。

上述字段为下表中的pType

CREATE TABLE `prices` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `pName` VARCHAR(100) NOT NULL DEFAULT '',
    `pType` ENUM('M','R','H') NOT NULL DEFAULT 'M',
    `pField` VARCHAR(50) NULL DEFAULT NULL,
    `pFieldExt` VARCHAR(50) NULL DEFAULT NULL,
    `cmp_id` INT(11) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
)
ENGINE=MyISAM
ROW_FORMAT=DEFAULT

我需要一个只有三个值的字段供用户选择,我想在数据库中强制执行该字段,而不仅仅是在我的应用程序中。

【问题讨论】:

    标签: sqlite types enums


    【解决方案1】:

    SQLite 中没有枚举类型,只有以下几种:

    • 整数
    • 真实
    • 文本
    • BLOB

    来源:http://www.sqlite.org/datatype3.html

    恐怕您的情况需要一个小的自定义枚举表。

    【讨论】:

    • 实际上“自定义枚举表”是一种使用真实枚举的更简洁的设计
    • 为什么不使用 CHECK() 约束来只允许三个可能的字符串?
    • @Wideshanks 我不认为CHECK() 在我写这个答案时存在。除非字符串 真的 短,否则我完全反对。最多 1 或 2 个字符。
    • 我可以在我的 SQLite 版本中使用VARCHAR,这是新增的类型吗?
    • @HammanSamuel 这不是新的,它被解析为含义TEXT。在我给出的源页面上,请参阅第 2.1 点关于确定列亲和力。
    【解决方案2】:

    要扩展 MPelletier 的答案,您可以像这样创建表格:

    CREATE TABLE Price (
      PriceId INTEGER       PRIMARY KEY AUTOINCREMENT NOT NULL,
      Name    VARCHAR(100)  NOT NULL,
      Type    CHAR(1)       NOT NULL DEFAULT ('M') REFERENCES PriceType(Type)
    );
    
    CREATE TABLE PriceType (
      Type    CHAR(1)       PRIMARY KEY NOT NULL,
      Seq     INTEGER
    );
    INSERT INTO PriceType(Type, Seq) VALUES ('M',1);
    INSERT INTO PriceType(Type, Seq) VALUES ('R',2);
    INSERT INTO PriceType(Type, Seq) VALUES ('H',3);
    

    现在枚举值可以直接在 Price 表中使用,因为它们将使用 ENUM:您不需要加入 PriceType 表来获取 Type 值,您只需要在要确定时使用它ENUM 的序列。

    在 SQLite 3.6.19 版本中引入了外键约束。

    【讨论】:

    • INSERT INTO PriceType(Type, Seq) VALUES ('M',1), ('R',2), ('H',3); 应该会给你一个语法错误。 “第一种形式(使用“VALUES”关键字)在现有表中创建一个新行。”sqlite.org/lang_insert.html。分手避免:INSERT INTO PriceType(Type, Seq) VALUES ('M',1); INSERT INTO PriceType(Type, Seq) VALUES ('R',2); INSERT INTO PriceType(Type, Seq) VALUES ('H',3);
    • 不要忘记在每个会话中PRAGMA foreign_keys = ON; - 因为在 sqlite3 中默认禁用 fkeys
    • 如果您想避免忘记PRAGMA foreign_keys = ON;,那么您可以在主目录的 .sqliterc 文件中进行设置。
    • 另外,您可能希望在 Seq 上使用 UNIQUE 约束。像这样CREATE TABLE PriceType( Type Char(1) PRIMARY KEY NOT NULL, Seq INTEGER UNIQUE);
    • 为什么要创建一个单独的“Seq”列而不是只使用默认的rowid column
    【解决方案3】:

    SQLite 方式是使用CHECK constraint

    一些例子:

    CREATE TABLE prices (
     id         INTEGER                                PRIMARY KEY,
     pName      TEXT CHECK( LENGTH(pName) <= 100 )     NOT NULL DEFAULT '',
     pType      TEXT CHECK( pType IN ('M','R','H') )   NOT NULL DEFAULT 'M',
     pField     TEXT CHECK( LENGTH(pField) <= 50 )     NULL DEFAULT NULL,
     pFieldExt  TEXT CHECK( LENGTH(pFieldExt) <= 50 )  NULL DEFAULT NULL,
     cmp_id     INTEGER                                NOT NULL DEFAULT '0'
    )
    

    这会将pType 列限制为值MRH,仅 就像 enum("M", "R", "H") 在其他一些 SQL 引擎中一样。

    【讨论】:

    • Welp,实际上这个实现并没有完全模拟enum,因为它不可能按值的整数索引进行排序(这可以通过实际的enum 字段来实现)。只是,每个人,请记住这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多