Як створити тип ENUM у SQLite?


105

Мені потрібно перетворити таблицю з MySQL в SQLite, але я не можу зрозуміти, як перетворити поле перерахунку, оскільки я не можу знайти ENUMтип у SQLite.

Вищезазначене поле знаходиться 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

Мені потрібно поле з лише трьома значеннями, які користувач обрав, і я хотів би застосувати це в БД, а не лише в моїй програмі.

Відповіді:


81

У SQLite немає enum типу, лише наступне:

  • НУЛЬ
  • ІНТЕГЕР
  • РЕАЛЬНА
  • ТЕКСТ
  • БЛОБ

Джерело: http://www.sqlite.org/datatype3.html

Боюся, у вашому випадку буде потрібна невелика спеціальна таблиця перерахунків.


26
Насправді "спеціальна таблиця перерахувань" - це набагато чистіший дизайн, який використовує справжні перерахунки
— a_horse_with_no_name

19
Чому б не використовувати обмеження CHECK (), щоб дозволити лише три можливі рядки?
— mateusza

1
@Wideshanks Я не думаю, що CHECK()існував під час написання цієї відповіді. Якщо струна не є дійсно короткою, я абсолютно проти. Максимум 1 або 2 символи.
— MPelletier

Я можу використовувати VARCHARу своїй версії SQLite, це нове доповнення типу?
— Хамман Самуель

3
@HammanSamuel Це не ново, це вирішено як значення TEXT. На сторінці джерела, яку я дав, див. Пункт 2.1 щодо Визначення придатності стовпця.
— MPelletier

106

Шляхом SQLite є використання обмеження CHECK .

Деякі приклади:

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стовпець лише значеннями M, Rі H, як enum("M", "R", "H")і в інших SQL-движках.


2
Welp, насправді ця реалізація не повністю імітується, enumоскільки унеможливлює сортування за цілим індексом значень (що можливо за допомогою фактичного enumполя). Просто всі, майте це на увазі.
— Борис Д.

53

Щоб розширити відповідь 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);

Тепер значення перерахування доступні безпосередньо в таблиці цін, оскільки вони використовували б ENUM: вам не потрібно приєднуватися до таблиці PriceType, щоб отримати значення типу, використовувати його потрібно лише у тому випадку, якщо ви хочете визначити послідовність ENUMs.

Зовнішні ключові обмеження були введені у версії 3.6.19 SQLite.


3
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);
— ahcox

9
Не забувайте PRAGMA foreign_keys = ON;про кожен сеанс - адже файли за замовчуванням відключені в sqlite3
— smathy

3
Якщо ви хочете уникнути забуття, PRAGMA foreign_keys = ON;ви можете встановити це у вашому .sqliterc-файлі у вашому домашньому каталозі.
— Ерадикатор

1
Крім того, ви можете використовувати UNIQUEобмеження на Seq. Щось подібнеCREATE TABLE PriceType( Type Char(1) PRIMARY KEY NOT NULL, Seq INTEGER UNIQUE);
— Eradicatore

1
Чому б ви створили окремий стовпчик "Послідовність" замість того, щоб просто використовувати стовпець із замовчуванням в рядку ?
— Парфянський розстріл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.