ชนิดข้อมูล MySQL ที่จะใช้สำหรับการจัดเก็บค่าบูลีน


1207

เนื่องจาก MySQL ดูเหมือนจะไม่มีประเภทข้อมูล 'บูลีน' คุณใช้ 'data' ในการเก็บข้อมูลจริง / เท็จใน MySQL หรือไม่

โดยเฉพาะอย่างยิ่งในบริบทของการเขียนและการอ่านจาก / ถึงสคริปต์ PHP

เมื่อเวลาผ่านไปฉันได้ใช้และเห็นหลายวิธี:

  • tinyint, varchar field ที่มีค่า 0/1,
  • เขตข้อมูล varchar มีสตริง '0' / '1' หรือ 'true' / 'false'
  • และในที่สุด Enum ฟิลด์ที่มีสองตัวเลือก 'จริง' / 'เท็จ'

ไม่มีสิ่งใดที่เหมาะสม ฉันมักจะชอบตัวแปรจิ๋ว 0/1 เนื่องจากการแปลงชนิดอัตโนมัติใน PHP ให้ค่าบูลีนแทน

ดังนั้นคุณใช้ชนิดข้อมูลใด มีประเภทที่ออกแบบมาสำหรับค่าบูลีนที่ฉันมองข้ามไปหรือไม่? คุณเห็นข้อดี / ข้อเสียใด ๆ โดยการใช้งานประเภทใดประเภทหนึ่งหรือไม่?


217
ทุกคนที่กำลังอ่านคำตอบเก่าสำหรับคำถามนี้ต้องเข้าใจว่า MySQL ได้เพิ่มประเภทข้อมูลบิตในเวอร์ชัน 5 ใช้ข้อมูลนั้นเท่าที่คุณจะทำได้ dev.mysql.com/doc/refman/5.0/en/bit-type.html
smp7d

3
คำถามที่เกี่ยวข้องกับAlternative เพื่อ booleans มากมายใน MySQL?
tereško

7
สำหรับรุ่นปัจจุบันของประเภท MYSQL Boolean สามารถใช้ได้ - dev.mysql.com/doc/refman/5.5/th/numeric-type-overview.htmlตรวจสอบสิ่งนี้ ตามค่าที่ถือว่าเป็นศูนย์
DevT

7
bit(1)เป็นบิต ** เพื่อนำเข้าใน Excel สลับไปใช้tinyint(1)งานได้
Cees Timmerman

8
ตอนนี้เรามีบูลีนหลังจาก 5 ปี
V-SHY

คำตอบ:


1232

สำหรับ MySQL 5.0.3 BITและสูงกว่าคุณสามารถใช้ คู่มือบอกว่า:

ในฐานะของ MySQL 5.0.3 ชนิดข้อมูล BIT ถูกใช้เพื่อเก็บค่าบิตฟิลด์ ประเภท BIT (M) ช่วยให้สามารถจัดเก็บค่า M-bit ได้ M สามารถอยู่ในช่วง 1 ถึง 64

มิฉะนั้นตามคู่มือ MySQL คุณสามารถใช้บูลและบูลีนซึ่งเป็นชื่อแทนของจิ๋ว (1):

บูลบูลีน: ประเภทนี้มีความหมายเหมือนกันสำหรับTINYINT (1) ค่าศูนย์ถือเป็นเท็จ ค่าที่ไม่ใช่ศูนย์ถือว่าเป็นจริง

MySQL ระบุด้วยว่า:

เราตั้งใจที่จะใช้การจัดการแบบบูลเต็มรูปแบบตามมาตรฐาน SQL ในรุ่น MySQL ในอนาคต

การอ้างอิง: http://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html


11
ใช่ฉันจะไปเพื่อสิ่งนี้หรือสำหรับชาร์ (1) และเก็บ 'Y' / 'N' หรือ 'T' / 'F' ฯลฯ ขึ้นอยู่กับบริบท ข้อดีของการใช้ประเภทจำนวนเต็มขนาดเล็กก็คือคุณจะได้รับความสะดวกในการพกพาสูงสุดใน RDBMS-es
Roland Bouman

36
อย่างน้อยการใช้ถ่านใน PHP อย่างน้อยก็จะนำไปสู่โค้ดที่มากขึ้นซึ่ง!$booleanจะไม่สามารถประเมินได้อย่างถูกต้องหากไม่มีการประมวลผลเพิ่มเติม
Mild Fuzz

10
@Pererier ไม่มีอะไรที่คุณไม่สามารถ google ด้วยตัวคุณเอง แต่ตกลงฉันจะกัด ก่อนอื่นโปรดดูที่ data0type.h โปรดทราบว่า innodb ไม่ได้กำหนดประเภท BIT ไว้ที่นั่น ถ้ามันจะจัดการกับเขตข้อมูล BIT ในแบบที่คุณอธิบายแน่นอนเราจะพบคำใบ้ของการมีอยู่ของมัน ประการที่สองการอ่านmysqlperformanceblog.com/2008/04/23/... และอย่าลังเลที่จะสอนเราว่าลูกค้า MySQL ที่น่าทึ่งใน "marktetplace" เล่นได้ดีกับ BIT field พวกเขาจะเข้ามาหาคนที่พลาดบทความนั้นอย่างไม่ต้องสงสัย
Roland Bouman

9
เมื่อฉันเลือกจากมาตรฐาน bit ลูกค้าบรรทัดคำสั่ง mysql ฟิลด์แสดงว่างเปล่าอย่างสมบูรณ์ ด้วยเหตุนี้ฉันชอบ TINYINT (1)
ผู้ใช้

8
@ MikePurcell ฉันเกลียดที่จะถาม แต่ทำไมคุณถึงต้องการauto_incrementคอลัมน์ที่แสดงถึงค่าบูลีน
Chris Hayes

248

BOOLและเป็นคำพ้องความหมายของBOOLEAN TINYINT(1)เป็นศูนย์false, trueสิ่งอื่นใดคือ ข้อมูลเพิ่มเติมที่นี่


7
(1)ไม่อะไรมากไปกว่าการตรวจสอบว่าค่าจะปรากฏถ้าคุณใส่ใจเกี่ยวกับขนาดการจัดเก็บแล้วคุณต้องการที่จะใช้BITแทน
JamesHalsall

35
@JamesHalsall: ที่จริงBIT(1)และTINYINT(1)ทั้งสองจะใช้หนึ่งไบต์ในการจัดเก็บ จนกระทั่ง MySQL 5.0.3, เป็นจริงไวพจน์สำหรับBIT TINYINTMySQL รุ่นที่ใหม่กว่าเปลี่ยนการใช้งาน BIT แต่ถึงแม้จะมีการเปลี่ยนแปลงการใช้งานก็ยังไม่มี "ขนาดการจัดเก็บ" ที่เป็นประโยชน์ต่อBITประเภทข้อมูล (อย่างน้อยกับ InnoDB และ MyISAM เครื่องมือจัดเก็บอื่น ๆ เช่น NDB อาจมีการเพิ่มประสิทธิภาพการจัดเก็บบางส่วนสำหรับการประกาศคอลัมน์ BIT หลายรายการ) ไลบรารีไม่รู้จักหรือจัดการBITคอลัมน์ประเภทข้อมูลที่ส่งคืนอย่างเหมาะสม TINYINTทำงานได้ดีขึ้น
spencer7593

5
คู่มือ MySQL 5.0 อย่างชัดเจนบอกว่าค่าบูลีนเป็น 1 หรือ 0 วลี "สิ่งอื่นคือtrue" ไม่เป็นความจริง
วอลเตอร์

7
@ วอลเตอร์: จริง ๆ แล้วมันเป็นเรื่องจริงคำอธิบายค่อนข้างขาด ในบริบทบูลีนสั้น ๆ นิพจน์สามารถประเมินค่าเป็น NULL, FALSE หรือ TRUE ในคำสั่ง MySQL นิพจน์ที่ประเมินในบริบทบูลีนจะถูกประเมินเป็นจำนวนเต็มก่อน (ค่าทศนิยมและค่าทศนิยมจะถูกปัดเศษสตริงจะถูกแปลงในลักษณะปกติที่ MySQL แปลงสตริงเป็นจำนวนเต็ม) NULL เห็นได้ชัดว่าเป็น NULL (ไม่ใช่ทั้ง TRUE และ FALSE) ค่าจำนวนเต็มของ 0 จะจัดการเป็นเท็จและใด ๆค่าจำนวนเต็มอื่น ๆ (1, 2, -7 ฯลฯ ) ตรวจสอบการจริง สำหรับความเข้ากันได้เราเลียนแบบตรรกะ / การจัดการบูลีน TINYINT
spencer7593

4
@Walter: SELECT 'foo' AS bar FROM dual WHERE -7นี้เป็นเรื่องง่ายในการทดสอบเช่น นิพจน์ -7 ถูกประเมินค่าในบริบทบูลีนและเคียวรีส่งคืนแถว เราสามารถทดสอบด้วย 0 หรือนิพจน์ใด ๆ ที่ประเมินค่าเป็นจำนวนเต็ม 0 และไม่มีการส่งคืนแถว หากนิพจน์ในส่วนคำสั่ง WHERE จะประเมินค่าเป็นจำนวนเต็มที่ไม่ใช่ค่า null ใด ๆ นอกเหนือจากศูนย์นิพจน์จะเป็น TRUE (ฉันเชื่อว่าค่าทศนิยมและทศนิยมจะได้รับ "ปัดเศษ" เป็นจำนวนเต็มเช่นWHERE 1/3ประเมินผลWHERE 0เราได้ผลลัพธ์เดียวกันกับWHERE 'foo'เพราะสตริง'foo'ยังประเมินค่าเป็นจำนวนเต็ม 0
spencer7593

71

นี่เป็นทางออกที่สง่างามที่ฉันค่อนข้างชื่นชมเพราะใช้ศูนย์ข้อมูลไบต์:

some_flag CHAR(0) DEFAULT NULL

การตั้งค่าให้เป็นจริงชุดและจะตั้งเป็นเท็จชุดsome_flag = ''some_flag = NULL

จากนั้นก็ให้ทดสอบจริงตรวจสอบว่า some_flag IS NOT NULLและเพื่อทดสอบเท็จตรวจสอบถ้า IS NULLsome_flag

(วิธีนี้อธิบายไว้ใน "MySQL ประสิทธิภาพสูง: การเพิ่มประสิทธิภาพการสำรองข้อมูลการจำลองแบบและอื่น ๆ " โดย Jon Warren Lentz, Baron Schwartz และ Arjen Lentz)


3
เคล็ดลับแฟนซี! สิ่งนี้มีประโยชน์หากทำงานกับ MySQL <5 และอาจเป็นรอยเท้าที่เบากว่า BIT แต่ในความพยายามที่จะปฏิบัติตามอนุสัญญาและค่าใช้จ่ายในการคำนวณน้อยกว่าเล็กน้อย (ตรรกะเทียบกับค่าที่แน่นอน) ฉันจะบอกว่า BIT เป็นวิธีที่ดีกว่า
zamnuts

59
อาจเป็น 'เร็ว' แต่มันทำให้ข้อมูลสับสนจนนักพัฒนารายใหม่ ๆ ไม่ทราบว่าคอลัมน์นั้นหมายถึงอะไร
Richthofen

5
นี่ใช้จำนวนไบต์เท่ากับ BIT (1)
ITS Alaska

25
โชคดีที่ได้รับออมเพื่อทำแผนที่อย่างนี้
Craig Labenz

4
ฉันเห็นด้วยกับ @Richthofen และพบว่ามันยากที่จะจินตนาการถึงสถานการณ์ที่ฉันเคยสนับสนุนด้วยการใช้โซลูชันนี้ อย่างไรก็ตามหากต้องใช้งานให้ระบุเป็น a COMMENTในคำจำกัดความของคอลัมน์ที่NULLระบุว่าเป็นเท็จและ''บ่งชี้ว่าอาจเป็นวิธีที่เล็กมากในการช่วยเหลือความเข้าใจในอนาคต
eggyal

34

หากคุณใช้ประเภทบูลีนจะใช้นามแฝงเป็น TINYINT (1) สิ่งนี้ดีที่สุดถ้าคุณต้องการใช้ SQL ที่ได้มาตรฐานและไม่ต้องสนใจว่าเขตข้อมูลนั้นอาจมีค่านอกช่วง (โดยพื้นฐานแล้วสิ่งใดก็ตามที่ไม่ใช่ 0 จะเป็น 'จริง')

ENUM ('False', 'True') จะช่วยให้คุณใช้สตริงใน SQL ของคุณและ MySQL จะเก็บฟิลด์ภายในเป็นจำนวนเต็มโดยที่ 'False' = 0 และ 'True' = 1 ตามลำดับที่ระบุ Enum .

ใน MySQL 5+ คุณสามารถใช้ฟิลด์ BIT (1) เพื่อระบุประเภทตัวเลข 1 บิต ฉันไม่เชื่อว่าสิ่งนี้จะใช้พื้นที่ในการจัดเก็บน้อยลง แต่ให้คุณ จำกัด ค่าที่เป็นไปได้คือ 1 หรือ 0

ข้อมูลทั้งหมดที่กล่าวมาจะใช้พื้นที่เก็บข้อมูลประมาณเท่ากันดังนั้นจึงเป็นการดีที่สุดที่จะเลือกที่เก็บข้อมูลที่คุณใช้งานได้ง่ายที่สุด


8
หมายเหตุของคุณเกี่ยวกับ ENUM ไม่เป็นความจริง: ลอง CAST (yourenumcol ตามที่ไม่ได้ลงชื่อ) และคุณจะสังเกตเห็นว่า False จะเป็น 1 และ True จะเป็น 2 ปัญหาอีกประการของ ENUM คือการแทรก "" (สตริงว่างเปล่าง่ายเกินไป) ). ฉันจะไม่แนะนำให้ใช้สิ่งนี้
Roland Bouman

4
จากประสบการณ์ของฉันการใช้ฟิลด์ BIT (1) จากโค้ด PHP นั้นค่อนข้างลำบาก TINYINT (1) ง่ายขึ้นมากและสร้างโค้ดที่อ่านได้มากขึ้น
M-Peror

1
@ M-Peror - "การใช้เขตข้อมูล BIT (1) จากรหัส PHP เป็นบิตลำบาก" ... ไม่เล่นสำนวนตั้งใจ :) แต่ใช่ฉันเห็นด้วย ฉันจำ TINYINT (1) ได้ง่ายขึ้นเช่นกัน ... แค่จำไม่ได้ว่าทำไม ใครมีความคิดเกี่ยวกับเรื่องนี้? BIT (1) ดูเหมือนดีกว่าบนพื้นผิวเพราะคุณสามารถ จำกัด ได้ 0 หรือ 1 ฉันคิดว่าบางครั้ง BIT ถูกตีความว่าเป็นข้อมูลไบนารี (ขึ้นอยู่กับภาษาการเขียนโปรแกรมและไดรเวอร์ / ไลบรารี); ในขณะที่ TINYINT ได้รับการปฏิบัติเหมือนเป็นจำนวนมากขึ้น
BMiner

2
@Biner - ฮ่าฮ่ามันไม่ได้ตั้งใจจริงๆไม่ได้สังเกตว่า :) แต่แน่นอนถ้าฉันจำได้อย่างถูกต้องเขตบิตถูกตีความว่าเป็นสิ่งที่เป็นเลขฐานสองในขณะที่ smallint ง่ายต่อการรักษาเป็นจำนวนและเพราะง่ายกว่า ใช้ในการแสดงออก (บูลีน)
M-Peror

34

คำถามนี้ได้รับคำตอบแล้ว แต่ฉันคิดว่าฉันจะขว้างด้วยเงิน $ 0.02 ผมมักจะใช้ที่CHAR(0)'' == true and NULL == false

จากmysql docs :

CHAR(0)ยังค่อนข้างดีเมื่อคุณต้องการคอลัมน์ที่สามารถรับค่าได้สองค่าเท่านั้น: คอลัมน์ที่กำหนดให้CHAR(0) NULLใช้เพียงหนึ่งบิตเท่านั้นและสามารถรับเฉพาะค่าNULLและ''(สตริงว่าง)


16
มมดูเหมือนว่าจะถามถึงปัญหาถ้าคุณเป็นฉัน ฉันหมายถึงขึ้นอยู่กับภาษามันอาจง่ายเกินไปที่จะไม่เห็นความแตกต่างระหว่าง NULL และ '' (เช่น PHP)
Roland Bouman

3
ในแง่ของการประหยัดพื้นที่ (จำนวนไบต์ที่ใช้แสดงบูลีน) วิธีการนี้เป็นผู้ชนะที่ชัดเจน สิ่งนี้จะช่วยประหยัดไบต์มากกว่า TINYINT ข้อเสีย (เป็นความเห็นชี้ให้เห็น) คือลูกค้าบางคนอาจมีปัญหาในการแยกความแตกต่างระหว่าง NULL และสตริงที่ว่างเปล่า แม้แต่บางฐานข้อมูลเชิงสัมพันธ์ (เช่น Oracle) ก็ไม่แยกความแตกต่างระหว่างสตริงที่มีความยาวเป็นศูนย์และ NULL
spencer7593

3
มันฉลาดมาก! ฉันเคยเขียนรหัสที่ฉลาดตอนนี้ฉันหลีกเลี่ยงมันเหมือนโรคระบาด ตอนนี้ฉันต้องการให้รหัสของฉันมีเจตนาชัดเจนไม่ใช่แค่พฤติกรรมที่ถูกต้อง คำแนะนำของฉัน? ทำสิ่งนี้หากคุณต้องการสร้างความสับสนให้กับทุกคนที่ต้องสนับสนุนรหัส / ฐานข้อมูล ตัวอย่างเช่นใน PHP ทั้งสอง''และnullเป็นค่าเท็จ
CJ Dennis

1
@CJDennis ถ้าคุณแยกชั้นฐานข้อมูลของคุณไว้เบื้องหลังรูปแบบที่เก็บคุณไม่ต้องกังวลเกี่ยวกับความสับสนของโซลูชันนี้
prograhammer

18

ฉันใช้ TINYINT (1) เพื่อเก็บค่าบูลีนใน Mysql

ฉันไม่ทราบว่ามีข้อได้เปรียบในการใช้สิ่งนี้หรือไม่ ... แต่ถ้าฉันไม่ผิด mysql สามารถเก็บบูลีน (BOOL) และเก็บไว้เป็นจิ๋ว (1)

http://dev.mysql.com/doc/refman/5.0/en/other-vendor-data-types.html


17

บิตเป็นข้อได้เปรียบเหนือตัวเลือกไบต์ต่าง ๆ (tinyint, enum, char (1)) ถ้าคุณมีฟิลด์บูลีนจำนวนมาก เขตข้อมูลหนึ่งบิตยังคงใช้ไบต์เต็ม ฟิลด์สองบิตพอดีกับไบต์เดียวกัน สามสี่ห้าห้าหกเจ็ดแปด หลังจากนั้นพวกเขาก็เริ่มเติมไบต์ต่อไป ในที่สุดการออมมีขนาดเล็กมากมีการปรับปรุงอื่น ๆ หลายพันรายการที่คุณควรมุ่ง เว้นแต่ว่าคุณกำลังจัดการกับข้อมูลจำนวนมหาศาลไบต์จำนวนน้อยเหล่านั้นจะไม่เพิ่มขึ้นมากนัก หากคุณใช้บิตกับ PHP คุณจะต้องพิมพ์ค่าที่เข้าและออก


1
+1 สำหรับความคิดเห็นที่พิมพ์ออกมา เพื่อเพิ่มไปนี้เมื่อทำงานกับภาษาการเขียนโปรแกรมหลีกเลี่ยงการใช้เทคนิคการเขียนโปรแกรมสันหลังยาวเพื่อความสอดคล้อง ใช้ตัวดำเนินการเหมือนกันแทนที่จะเท่ากับ ในกรณีของ PHP ถ้า ($ var == "") จะเป็นจริงสำหรับ 0, false, null, undefined และ "" เพื่อทดสอบค่าทั้งหมดมักจะใช้ถ้า (จริง === ว่างเปล่า ($ var)) เนื่องจากจะหลีกเลี่ยงข้อผิดพลาดที่ไม่ได้กำหนดเช่นกัน คุณควรตรวจสอบประเภทข้อมูลที่คุณกำลังทำงานด้วยหาก (is_int ($ var) && $ $ === 0) หรือพิมพ์ข้อมูลเพื่อบังคับให้เป็นประเภทข้อมูลเฉพาะ (int) $ var สำหรับงาน
fyrye

@ สิ่งนี้เป็นจริงสำหรับ MySQL ในระดับเดียวกับ MSSQL หรือไม่ ฉันกำลังโยกย้ายแอปพลิเคชันใหม่ที่ยังไม่ได้ทำการผลิตเลยจาก MSSQL ไปยัง MySQL ฉันไม่ได้ใช้ PHP แต่แทนที่จะแปลง C # เป็น Java 8 เนื่องจาก Java เป็นภาษาที่พิมพ์ได้ดีฉันไม่กังวลเกี่ยวกับการจัดการประเภท ... เพียงแค่ค่าสถานะบิตทั้งหมดที่จะย้ายจากหนึ่งไบต์ถึง 8 ธงเพื่อ 1 ไบต์แต่ละแฟล็กที่ได้รับ TINYINT (1) คุณรู้เกี่ยวกับเอกสารใด ๆ ในหัวข้อนี้สำหรับ MySQL หรือไม่?
Zack Jannsen

1
@Thor การทำวิจัยบางอย่างที่ลึกลงไปก็เป็นที่ชัดเจนว่าคำตอบที่ควร การเปลี่ยนแปลงเกิดขึ้นและเราได้เห็นการปรับปรุงในการจัดการนี้ รู้ภาษาของคุณที่จะอยู่ใน Application Layer / Data Access Layer และรู้ว่าไลบรารีของคุณรองรับ ฉันใช้ Java ในปัจจุบันและ BIT (1) เป็นตัวเลือกที่แนะนำในขณะนี้สำหรับไลบรารี่อย่าง Hybernate และการใช้ JDBC นี่คือ URL [ดูตารางที่ 5.2]: dev.mysql.com/doc/connector-j/en/…
Zack Jannsen

12

จนกว่า MySQL จะใช้ประเภทข้อมูลบิตหากการประมวลผลของคุณถูกกดสำหรับพื้นที่และ / หรือเวลาเช่นการทำธุรกรรมในปริมาณมากให้สร้างฟิลด์ TINYINT ที่เรียกว่า bit_flagsตัวแปรบูลีนทั้งหมดและมาส์กและเลื่อนบิตบูลีนที่คุณต้องการใน SQL สอบถาม

ตัวอย่างเช่นหากบิตซ้ายสุดของคุณแทนเขตข้อมูลบูลของคุณและบิต 7 ขวาสุดแทนอะไรเลยbit_flagsเขตข้อมูลของคุณจะเท่ากับ 128 (ไบนารี 10,000,000) Mask (ซ่อน) บิตขวาสุดเจ็ดตัว (ใช้ตัวดำเนินการ bitwise &) และเลื่อนบิตที่เจ็ดเจ็ดช่องว่างไปทางขวาลงท้ายด้วย 00000001 ตอนนี้จำนวนทั้งหมด (ซึ่งในกรณีนี้คือ 1) คือค่าของคุณ

SELECT (t.bit_flags & 128) >> 7 AS myBool FROM myTable t;

if bit_flags = 128 ==> 1 (true)
if bit_flags = 0 ==> 0 (false)

คุณสามารถเรียกใช้คำสั่งเช่นนี้ในขณะที่คุณทดสอบ

SELECT (128 & 128) >> 7;

SELECT (0 & 128) >> 7;

เป็นต้น

เนื่องจากคุณมี 8 บิตคุณอาจมีตัวแปรบูลีน 8 ตัวจากหนึ่งไบต์ โปรแกรมเมอร์ในอนาคตบางคนจะใช้บิตต่อไปเจ็ดบิตดังนั้นคุณต้องปิดบัง อย่าเพิ่งเปลี่ยนหรือคุณจะสร้างนรกให้ตัวเองและคนอื่น ๆ ในอนาคต ตรวจสอบให้แน่ใจว่าคุณใช้ MySQL ทำการปิดบังและขยับ - ซึ่งจะเร็วกว่าการใช้ภาษาสคริปต์บนเว็บ (PHP, ASP และอื่น ๆ ) นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณได้แสดงความคิดเห็นในช่องข้อคิดเห็น MySQL สำหรับคุณbit_flagsเขตข้อมูล

คุณจะพบว่าไซต์เหล่านี้มีประโยชน์เมื่อใช้วิธีนี้:


7
นี่ดูเหมือนจะเป็นวิธีที่น่าสะพรึงกลัวที่ทำให้สับสนกับความตั้งใจของโปรแกรมเมอร์ในอนาคต ดูเหมือนว่าปัญหามากในการประหยัด 7 ไบต์ (สมมติว่าคุณกำลังใช้ทั้งหมด 8 bools ในตารางเดียวที่!)
อ๋อ

@ ใช่ไม่มีความงงงวยเลย! เขียนเอกสารและข้อคิดเห็น MySQL อธิบายแต่ละฟิลด์ในตาราง (ตามคำตอบที่กล่าวถึง)! กลยุทธ์การคลาย MySQL ที่แนะนำนั้นดูแข็งแกร่งและเก็บฟิลด์บูลีนต่าง ๆ ได้มากถึง 16 ฟิลด์โดยมีคอลัมน์เพียงไม่กี่คอลัมน์ดีกว่ามี 16 ฟิลด์แทน หากมันสับสนเกินกว่าที่จะใช้การจัดการบิตและคุณต้องการใช้ภาษาสคริปต์บนเว็บเพื่อรับบูลีนแต่ละอันเพียงแค่เก็บเป็นVARCHARและทำตามขั้นตอนการปลดล็อคในโค้ด ...
CPHPython

BITประเภทที่มีอยู่ ดูdev.mysql.com/doc/refman/8.0/en/bit-type.html
dolmen

10

ฉันเบื่อหน่ายกับการพยายามรับค่าศูนย์ NULLS และ '' อย่างแม่นยำวนรอบค่า PHP, MySql และ POST ดังนั้นฉันจึงใช้ 'ใช่' และ 'ไม่'

ใช้งานได้อย่างไม่มีที่ติและไม่ต้องการการดูแลเป็นพิเศษที่ไม่ชัดเจนและใช้งานง่าย


17
หากคุณต้องการที่จะเสียพื้นที่มากและประสิทธิภาพการประนีประนอมอย่างน้อยคุณสามารถทำอย่างน้อย CHAR (1) กับตัวเลือก Y และ N
ILikeTacos

3
ในสถานการณ์จริงส่วนใหญ่มีความแตกต่างที่แท้จริงระหว่าง 'ไม่' และไม่มีข้อมูล ตัวอย่างเช่นคุณอาจต้องการให้ทำเครื่องหมายในช่องทำเครื่องหมายโดยค่าเริ่มต้นหากผู้ใช้ยังไม่ได้พูดว่า 'ไม่' คุณคิดว่าคุณประหยัดพื้นที่มากแค่ไหนและคุณประมวลผลเท่าไรทุกครั้งที่คุณต้องแยกแยะระหว่าง false และ NULL - ถ้าคุณแยกแยะได้จริง ๆ ? ในโลกของภาพที่จัดเก็บและวิดีโอดิจิตอลบิตหรือสองของการประหยัดพื้นที่ไม่เกี่ยวข้องอย่างเต็มที่ แต่ความคมชัดและการประมวลผลลดลงเป็นจริง
Geoff Kendall

8
คำตอบนี้ไม่ผิดเพราะมันใช้งานได้และมันก็ไม่แย่เท่าที่คนอื่นให้เครดิต สำหรับโครงการส่วนใหญ่ (เช่น: ขนาดตาราง <1mil แถว) ความแตกต่างด้านประสิทธิภาพระหว่างโซลูชันที่ให้มาจะถูกปฏิเสธได้ ฉันจะไม่บ่นถ้าข้อความค้นหาของฉันกลับมาใน 7 vs 5 มิลลิวินาที ... เพื่อความยุติธรรมแม้ว่าตารางของคุณจะเติบโตเป็นแถว 10mil หรือมากกว่านั้นอาจเป็นวิธีที่ไม่เหมาะสม
แบรด

1
+1 จากฉันสำหรับการใช้ประเภทข้อมูล ENUM ฉันชอบสัญกรณ์นี้เป็นการส่วนตัว: ENUM ('y', 'n') มันมีขนาดกะทัดรัด (ยาวเพียงไบต์), ใช้งานง่ายและดูดีเป็นรูปแบบระดับแอปพลิเคชันสำหรับธงบูลีนทั้งหมด คุณสามารถใช้โดยตรงกับเขตข้อมูลฟอร์ม HTML ตัวอย่างเช่นด้วย PHP: <select name = "production"> <option value = "y" <? = $ production === 'y'? 'selected = "selected"': ''? >> ใช่ </option> <ตัวเลือกค่า = "n" <? = $ การผลิต === 'n'? 'selected = "selected"': ''? >> ไม่มี </option> </select>
Vlado

2
ฮ่า ๆ นี่ตาของฉัน แต่ฉันต้องพูด @GeoffKendall ถูกต้อง ในหลายกรณีไม่จำเป็นต้องมีประสิทธิภาพสูงสุดและวิธีการใดที่ทำงานให้คุณเป็นวิธีที่เหมาะสม
Madmenyo

6

อ้างถึงลิงค์นี้ ประเภทข้อมูลบูลีนใน Mysqlตามการใช้งานของแอปพลิเคชันหากต้องการให้จัดเก็บเพียง 0 หรือ 1 บิตบิต (1) เป็นตัวเลือกที่ดีกว่า


6
เป็นความจริงที่BIT(1)จะอนุญาตให้เก็บค่าb'0'หรือb'1'ค่าเท่านั้น ปัญหาที่ใหญ่ที่สุดเกี่ยวกับBITประเภทข้อมูลคือห้องสมุดไคลเอนต์ต่างๆมีการจัดการประเภทข้อมูลที่ไม่แพง ชำระเงินพฤติกรรมในเครื่องมือ SQL ต่าง ๆ (SQLyog, คางคกสำหรับ MySQL, SQL Developer), เครื่องมือที่ "โมเดลวิศวกรย้อนกลับ" ฐานข้อมูลและไคลเอนต์ต่าง ๆ เช่น JDBC, PHP, Perl DBI และสำหรับวัดที่ดีทดสอบกรอบ ORM ไม่กี่ ( Hibernate, Mybatis, JPA) ในแง่ของการใช้งานง่ายความเข้ากันได้ของเครื่องมือ / กรอบ / การสนับสนุนดั้งเดิมTINYINT(1)เป็นผู้ชนะที่ชัดเจน
spencer7593

ใช่. มันเสร็จสมบูรณ์ขึ้นอยู่กับกรอบการพิจารณาสำหรับแอพ ตัวอย่างเช่นกรอบ Phalcon ของ PHP ไม่รองรับประเภทข้อมูลบิต
Vidz

สำหรับบันทึก MyBatis รองรับทั้งBITและTINYINTและโปรดดูระดับ JdbcType MyBatis ของmybatis.org/mybatis-3/apidocs/reference/org/apache/ibatis/type/...
โชคดี

1
@Vidz ฉันให้คุณบวกหนึ่งสำหรับการกล่าวถึงของ BIT (1) แต่ยังจะชี้ให้เห็นถึงการพัฒนาที่อ่านนี้ - รู้ภาษาของคุณที่จะอยู่ใน Application Layer / Data Access Layer และรู้ว่าห้องสมุดของคุณสนับสนุน ฉันใช้ Java ในปัจจุบันและ BIT (1) เป็นตัวเลือกที่แนะนำในขณะนี้สำหรับไลบรารี่อย่าง Hybernate และการใช้ JDBC นี่คือ URL [ดูตาราง 5.2]: dev.mysql.com/doc/connector-j/en/…
Zack Jannsen

6

ตั้งแต่ MySQL (8.0.16) และ MariaDB (10.2.1) ทั้งสองใช้ข้อ จำกัด การตรวจสอบตอนนี้ฉันจะใช้

bool_val TINYINT CHECK(bool_val IN(0,1))

คุณจะสามารถไปยังร้านค้า0, 1หรือNULLเช่นเดียวกับค่าที่สามารถแปลงเป็น0หรือ1ไม่มีข้อผิดพลาดเช่น'1', 0x00, b'1'หรือ/TRUEFALSE

หากคุณไม่ต้องการอนุญาต NULL ให้เพิ่มNOT NULLตัวเลือก

bool_val TINYINT NOT NULL CHECK(bool_val IN(0,1))

โปรดทราบว่าแทบไม่มีความแตกTINYINTต่างหากคุณใช้TINYINT(1)หรือTINYINT(123)หรือ

หากคุณต้องการให้สคีมาของคุณเข้ากันได้คุณสามารถใช้BOOLหรือBOOLEAN

bool_val BOOL CHECK(bool_val IN(TRUE,FALSE))

db <> การสาธิตซอ


แล้ว enum (0, 1)
santiago arizti

3
@santiagoarizti ENUM(ต้องเป็นenum('0', '1')- หมายเหตุ: สตริงเหล่านั้น) ไม่ใช่ความคิดที่ดี มีปัญหามากเกินไปเนื่องจากวิธีการจัดเก็บภายในและวิธีปฏิบัติต่อค่าที่ไม่ใช่สตริง เช่น. 0และFALSE ไม่สามารถจัดเก็บได้ 1และกลายเป็นTRUE '0'และจะกลายเป็น2 '1'
Paul Spiegel

คำตอบที่ดีที่สุด ... สำหรับผู้ที่ใช้ MySQL 8+
dolmen

2

หลังจากอ่านคำตอบที่นี่ฉันตัดสินใจที่จะใช้bit(1)และใช่มันจะดีกว่าในพื้นที่ / เวลาแต่หลังจากที่ในขณะที่ฉันเปลี่ยนใจและฉันจะไม่ใช้มันอีกครั้ง มันซับซ้อนการพัฒนาของฉันมากเมื่อใช้คำสั่งที่เตรียมไว้ห้องสมุด ฯลฯ (php)

ตั้งแต่นั้นมาฉันมักจะใช้tinyint(1)ดูเหมือนดีพอ


3
สนใจอธิบายว่าการพัฒนาของคุณซับซ้อนแค่ไหน?
Chazy Chaz

@ChazyChaz คาดว่าจะเป็นจริง / เท็จแทนที่จะเป็น 1/0 ซึ่งแตกต่างจาก dbs อื่น ๆ เช่น SQL Server บางครั้งสิ่งนี้สามารถนำไปสู่สถานการณ์แปลก ๆ ที่คุณคิดว่าคุณกำลังตั้งค่าให้เป็นจริง แต่มันไม่ได้เกิดขึ้นจริง
maembe

0

คุณสามารถใช้ชนิดข้อมูล BOOL, BOOLEAN สำหรับการจัดเก็บค่าบูลีน

ประเภทเหล่านี้มีความหมายเหมือนกันสำหรับ TINYINT (1)

อย่างไรก็ตามประเภทข้อมูล BIT (1) เหมาะสมกว่าในการจัดเก็บค่าบูลีน (จริง [1] หรือเท็จ [0]) แต่ TINYINT (1) จะทำงานได้ง่ายขึ้นเมื่อคุณส่งออกข้อมูลแบบสอบถามและอื่น ๆ บนและเพื่อให้บรรลุการทำงานร่วมกันระหว่าง MySQL และฐานข้อมูลอื่น ๆ นอกจากนี้คุณยังสามารถตรวจสอบคำตอบนี้หรือด้าย

MySQL ยังแปลงประเภทข้อมูล BOOL, BOOLEAN เป็น TINYINT (1)

เพิ่มเติมอ่านเอกสาร

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