จะสร้างประเภท ENUM ใน SQLite ได้อย่างไร?


105

ฉันต้องการแปลงตารางจาก MySQL เป็น SQLite แต่ฉันไม่สามารถหาวิธีแปลงฟิลด์ enum ได้เนื่องจากฉันไม่พบ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

ไม่มีประเภท enum ใน SQLite เฉพาะดังต่อไปนี้:

  • NULL
  • จำนวนเต็ม
  • จริง
  • TEXT
  • หยด

ที่มา: http://www.sqlite.org/datatype3.html

ฉันเกรงว่าจะต้องใช้ตาราง enum ขนาดเล็กที่กำหนดเองในกรณีของคุณ


26
จริงๆแล้ว "ตาราง enum ที่กำหนดเอง" เป็นการออกแบบที่สะอาดกว่าโดยใช้ enums จริง
a_horse_with_no_name

19
ทำไมไม่ใช้ข้อ จำกัด CHECK () เพื่ออนุญาตให้มีเพียงสามสตริงที่เป็นไปได้
mateusza

1
@Wideshanks ฉันไม่คิดว่าCHECK()มีอยู่ในเวลาที่ฉันเขียนคำตอบนั้น เว้นแต่สตริงจะสั้นจริงๆฉันต่อต้านมันโดยสิ้นเชิง สูงสุด 1 หรือ 2 อักขระ
MPelletier

ฉันสามารถใช้VARCHARในเวอร์ชัน SQLite ของฉันได้เป็นการเพิ่มประเภทใหม่หรือไม่
Hamman Samuel

3
@HammanSamuel TEXTมันไม่ได้ใหม่ก็มีมติเป็นความหมาย ในหน้าแหล่งที่มาที่ฉันให้ดูจุดที่ 2.1 เรื่องการกำหนดความสัมพันธ์ของคอลัมน์
MPelletier

106

วิธี SQLite คือการใช้ข้อ จำกัด การตรวจสอบ

ตัวอย่างบางส่วน:

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ฟิลด์จริง) เพียงแค่ทุกคนจำไว้ว่า
Boris D.Teoharov

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 เพื่อรับค่า Type คุณจะต้องใช้หากคุณต้องการกำหนดลำดับของ ENUMs

ข้อ จำกัด ของ Foreign Key ถูกนำมาใช้ใน SQLite เวอร์ชัน 3.6.19


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;ทุกเซสชั่น - เนื่องจาก fkeys ถูกปิดใช้งานโดยค่าเริ่มต้นใน sqlite3
smathy

3
หากคุณต้องการหลีกเลี่ยงการลืมPRAGMA foreign_keys = ON;คุณสามารถตั้งค่าในไฟล์. sqliterc ในโฮมไดเร็กทอรีของคุณ
Eradicatore

1
นอกจากนี้คุณอาจต้องการใช้UNIQUEข้อ จำกัด ใน Seq อะไรทำนองนี้CREATE TABLE PriceType( Type Char(1) PRIMARY KEY NOT NULL, Seq INTEGER UNIQUE);
Eradicatore

1
ทำไมคุณจะสร้างแยกลำดับคอลัมน์ 'แทนการใช้เพียงเริ่มต้นคอลัมน์ ROWID ?
Parthian Shot
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.