ฟิลด์บูลีนใน Oracle


145

เมื่อวานนี้ฉันต้องการเพิ่มฟิลด์บูลีนลงในตาราง Oracle อย่างไรก็ตามไม่มีประเภทข้อมูลบูลีนจริงใน Oracle ไม่มีใครที่นี่รู้วิธีที่ดีที่สุดในการจำลองบูลีนหรือไม่? Googling ผู้ค้นพบวิธีการหลายวิธี

  1. ใช้จำนวนเต็มและอย่ายุ่งกับการกำหนดสิ่งอื่นใดนอกเหนือจาก 0 หรือ 1

  2. ใช้เขตข้อมูลถ่านที่มี 'Y' หรือ 'N' เป็นสองค่าเท่านั้น

  3. ใช้ enum กับข้อ จำกัด การตรวจสอบ

นักพัฒนา Oracle ที่มีประสบการณ์รู้หรือไม่ว่าแนวทางใดเป็นที่ต้องการ / มาตรฐาน


195
ฉันหวังว่าออราเคิลจะมีwallประเภทข้อมูลดังนั้นฉันสามารถทุบหัวของฉันกับมันเมื่อใช้บูลีน
Greg

คำตอบ:


82

ฉันพบลิงค์นี้มีประโยชน์

นี่คือย่อหน้าที่เน้นถึงข้อดี / ข้อเสียของแต่ละวิธี

การออกแบบที่พบเห็นบ่อยที่สุดคือการเลียนแบบแฟล็กเหมือนบูลีนจำนวนมากที่มุมมองพจนานุกรมข้อมูลของ Oracle ใช้โดยเลือก 'Y' สำหรับจริงและ 'N' สำหรับเท็จ อย่างไรก็ตามการโต้ตอบอย่างถูกต้องกับสภาพแวดล้อมโฮสต์เช่น JDBC, OCCI และสภาพแวดล้อมการเขียนโปรแกรมอื่น ๆ จะดีกว่าที่จะเลือก 0 สำหรับเท็จและ 1 สำหรับจริงเพื่อให้สามารถทำงานได้อย่างถูกต้องกับฟังก์ชั่น getBoolean และ setBoolean

โดยพื้นฐานแล้วพวกเขาสนับสนุนวิธีที่ 2 เพื่อประโยชน์ในการใช้งาน

  • ค่า 0/1 (เนื่องจากความสามารถในการทำงานร่วมกับ JDBC getBoolean()เป็นต้น) ด้วยข้อ จำกัด การตรวจสอบ
  • ประเภทของ CHAR (เพราะใช้พื้นที่น้อยกว่าจำนวน)

ตัวอย่างของพวกเขา:

create table tbool (bool char check (bool in (0,1));
insert into tbool values(0);
insert into tbool values(1);`

31
ฉันแนะนำไม่ให้ใช้ 'N' และ 'Y' เนื่องจากมันขึ้นอยู่กับภาษา บางครั้งแองโกลโฟนลืมว่าส่วนใหญ่ของโลกไม่ได้เป็นตัวแทนของแนวคิดของความจริงด้วยตัวอักษร Y. ในทางตรงกันข้ามความหมายของ 0 และ 1 นั้นคงที่ตลอดช่วงเวลาที่มีอุปสรรคทางภาษา
Andrew Spencer

7
0 และ 1 เนื่องจากค่าบูลีนไม่สอดคล้องกันในวิทยาการคอมพิวเตอร์ - ภาษาของชนิดสคริปต์เชลล์มีแนวโน้มที่จะเป็น 0 และไม่เป็นศูนย์ว่าล้มเหลวในขณะที่ภาษาประเภท C มีแนวโน้มที่จะเป็น 0 เป็นความล้มเหลวและไม่ใช่ศูนย์เป็นความสำเร็จ
Phil

41
ในฐานะที่เป็นค่าบูลีนพวกเขาจะไม่น่าสงสัย รหัสส่งคืนกระบวนการไม่ใช่ค่าบูลีน
Andrew Spencer

13
เหตุใดย่อหน้าทั้งหมดนี้จากลิงก์ที่ให้ไว้จึงถูกละเว้นในคำตอบนี้ "การออกแบบที่พบเห็นได้บ่อยที่สุดคือการเลียนแบบแฟล็กเหมือนบูลีนจำนวนมากที่มุมมองพจนานุกรมข้อมูลของ Oracle ใช้เลือก 'Y' สำหรับจริงและ 'N' สำหรับเท็จอย่างไรก็ตามเพื่อโต้ตอบกับสภาพแวดล้อมโฮสต์เช่น JDBC, OCCI และสภาพแวดล้อมการเขียนโปรแกรมอื่น ๆ ควรเลือก 0 สำหรับ false และ 1 สำหรับ true เพื่อให้สามารถทำงานได้อย่างถูกต้องกับฟังก์ชัน getBoolean และ setBoolean " พวกเขาระบุว่าในขณะที่ 'Y / N' เป็นเรื่องธรรมดาแนะนำให้ใช้ '0/1' เพื่อเพิ่มความเข้ากันได้กับสภาพแวดล้อมโฮสต์
justin.hughey

28

Oracle เองใช้ Y / N สำหรับค่าบูลีน เพื่อความสมบูรณ์ควรสังเกตว่า pl / sql มีประเภทบูลีนมันเป็นเพียงตารางที่ไม่มี

ถ้าคุณกำลังใช้ฟิลด์เพื่อระบุว่าเร็กคอร์ดจำเป็นต้องถูกประมวลผลหรือไม่คุณอาจพิจารณาใช้ Y และ NULL เป็นค่า สิ่งนี้ทำให้ดัชนีมีขนาดเล็กมาก (อ่านเร็ว) ที่ใช้พื้นที่น้อยมาก


7
+1 ข้อดีของมุมมองและตารางภายในของ Oracle โดยใช้ Y / N ถ้าออราเคิลทำอย่างนั้นจะต้องถูกต้อง! :)
เจฟฟรีย์เคมพ์

คุณช่วยอธิบายว่า Y และ NULL สร้างดัชนีขนาดเล็กได้อย่างไรเมื่อเทียบกับ Y และ N
styfle

6
NULL ไม่ได้รับการจัดทำดัชนีใน Oracle ดังนั้นหากดัชนีของคุณมีอักขระ Y สองสามตัว แต่ส่วนใหญ่เป็น NULL คุณจะมีดัชนีที่เล็กมาก
Leigh Riffel

25

ในการใช้พื้นที่น้อยที่สุดคุณควรใช้ช่อง CHAR ที่ จำกัด ไว้ที่ 'Y' หรือ 'N' Oracle ไม่รองรับประเภทข้อมูลบูลีน, BIT หรือ TINYINT ดังนั้นหนึ่งไบต์ของ CHAR มีขนาดเล็กเท่าที่คุณจะได้รับ


19

ตัวเลือกที่ดีที่สุดคือ 0 และ 1 (เป็นตัวเลข - อีกคำตอบคือ 0 และ 1 เป็นCHARสำหรับประสิทธิภาพของพื้นที่ แต่มันก็บิดเกินไปสำหรับฉัน) โดยใช้ NOT NULL และข้อ จำกัด ในการตรวจสอบเพื่อ จำกัด เนื้อหาให้เป็นค่าเหล่านั้น (หากคุณต้องการให้คอลัมน์เป็นโมฆะไม่ใช่บูลีนที่คุณจัดการ แต่เป็นการระบุด้วยค่าสามค่า ... )

ข้อดีของ 0/1:

  • ภาษาอิสระ 'Y' และ 'N' จะใช้ได้ถ้าทุกคนใช้มัน แต่พวกเขาทำไม่ได้ ในฝรั่งเศสพวกเขาใช้ 'O' และ 'N' (ฉันได้เห็นสิ่งนี้ด้วยตาของตัวเอง) ฉันไม่ได้ตั้งโปรแกรมในฟินแลนด์เพื่อดูว่าพวกเขาใช้ 'E' และ 'K' ที่นั่น - ไม่ต้องสงสัยเลยว่าพวกเขาฉลาดกว่านั้น แต่คุณไม่แน่ใจ
  • สอดคล้องกับการปฏิบัติในภาษาการเขียนโปรแกรมที่ใช้กันอย่างแพร่หลาย (C, C ++, Perl, Javascript)
  • เล่นได้ดีขึ้นด้วยเลเยอร์แอปพลิเคชันเช่น Hibernate
  • ยกตัวอย่างเช่นนำไปสู่ ​​SQL ที่กระชับมากขึ้นเพื่อค้นหาว่ากล้วยมีความพร้อมที่จะกินselect sum(is_ripe) from bananasแทนselect count(*) from bananas where is_ripe = 'Y'หรือแม้กระทั่ง (yuk)select sum(case is_ripe when 'Y' then 1 else 0) from bananas

ข้อดีของ 'Y' / 'N':

  • ใช้พื้นที่น้อยกว่า 0/1
  • นี่คือสิ่งที่ Oracle แนะนำดังนั้นอาจเป็นสิ่งที่บางคนคุ้นเคยมากกว่า

โปสเตอร์อื่นแนะนำ 'Y' / null เพื่อเพิ่มประสิทธิภาพ หากคุณพิสูจน์แล้วว่าคุณต้องการประสิทธิภาพจงยุติธรรม แต่หลีกเลี่ยงเพราะมันทำให้การสืบค้นน้อยลง ( some_column is nullแทนที่จะเป็นsome_column = 0) และการเข้าร่วมด้านซ้ายคุณจะทำให้ความผิดพลาดกับระเบียนที่ไม่มีอยู่


3
คุณพบว่าทุกวันนี้ที่บูลีนมากมายเป็น TriState นั่นคือจริงเท็จและไม่รู้จัก ซึ่งลงตัวกับความคิดฐานข้อมูลว่าง เพียงเพราะหลายครั้งที่รู้ว่าไม่มีคำตอบใดที่มีความสำคัญอย่างยิ่ง
MikeT

1
ใช่จำเป็นต้องใช้จริงเท็จไม่ทราบแม้ว่าฉันจะจู้จี้จุกจิก (ซึ่งฉัน) ฉันก็บอกว่ามันไม่ควรถูกอธิบายว่าเป็นบูลีนเพราะมันไม่ใช่
Andrew Spencer

2
หากคุณกำลังจะจู้จี้จุกจิกนั้นคุณสามารถสร้างอาร์กิวเมนต์เดียวกันสำหรับทุกประเภทข้อมูล ภายใต้ข้อกำหนดที่เข้มงวดจำนวนเต็มสองครั้ง (ผมคิดว่าผมควรจะพูดว่าคู่เจ้าตัวยาวเสริมจุดลอย) Binary, เชือก ฯลฯ ทั้งหมดถือว่าเป็นค่าที่มีให้ แต่การใช้งานฐานข้อมูลมักจะเพิ่มตัวเลือกที่คุ้มค่า null บูลีนไม่แตกต่างใด ๆ
MikeT

1
จริงบนบันทึกบวกสำหรับวิธีการของคุณถ้าคุณกำหนดค่าหมายเลขของคุณอย่างถูกต้องมันยังสามารถเก็บไว้ในไบต์เดียวกับเขตข้อมูลถ่านซึ่งเป็นโมฆะอาร์กิวเมนต์ขนาดกับการใช้ 0/1 ฉันไม่สามารถหาลิงค์ในขณะนี้ ที่เก็บข้อมูลสำหรับช่วงตัวเลขตั้งแต่ 1 - 22 ไบต์ขึ้นอยู่กับการกำหนดค่า
MikeT

4
ฉันสงสัยว่า downvotes เกิดจากมุมมองดั้งเดิมในการเลือกใช้งานหน่วยความจำที่มีประสิทธิภาพมากที่สุด ประสิทธิภาพของหน่วยความจำวันนี้และอายุน้อยกว่าความสำคัญและควรนำมาพิจารณาหลังจากการใช้งานและเข้ากันได้ สำหรับทุกคนที่อาจตอบสนองต่อความคิดเห็นนี้ฉันขอแนะนำให้อ่านข้อมูลเกี่ยวกับการปรับให้เหมาะสมก่อนเวลาอันควร นั่นคือสิ่งที่เกิดขึ้นโดยการเลือก 'Y / N' ขึ้นอยู่กับประสิทธิภาพของหน่วยความจำ คุณกำลังสูญเสียความสามารถในการทำงานร่วมกับชุดกรอบงานที่ใช้กันทั่วไปเนื่องจากการตัดสินใจดังกล่าว
justin.hughey

5

อาจเป็น 1/0 หรือ Y / N ที่มีข้อ จำกัด ในการตรวจสอบ อีเธอร์เป็นวิธีที่ดี โดยส่วนตัวแล้วผมชอบ 1/0 มากเพราะผมทำงานมากในภาษา Perl และมันทำให้การดำเนินการแบบบูลแบบ Perl ในฟิลด์ฐานข้อมูลเป็นเรื่องง่าย

หากคุณต้องการสนทนาอย่างลึกซึ้งในคำถามนี้กับหนึ่งในหัวหน้าของ honcos ของ Oracles ให้ตรวจสอบสิ่งที่ Tom Kyte พูดเกี่ยวกับสิ่งนี้ที่นี่


1/0 ถูกกล่าวว่าเป็น "หน่วยความจำที่มีประสิทธิภาพน้อยลง" แต่ ... ฉันก็ชอบมากกว่านี้ด้วย (และจำศีลต้องใช้บูลีน 1/0 ในการอ่าน)
rogerdpack

1/0 เป็นค่าเริ่มต้นของ Hibernate สำหรับบูลีน แต่คุณสามารถกำหนดการแมปที่กำหนดเองที่คุณต้องการ
Andrew Spencer

@rogerdpack นั่นเป็นเพราะเขตข้อมูลถ่านคือ 1 ไบต์หรือ 2 ไบต์สำหรับ nchar โดยขึ้นอยู่กับว่ามันถูกกำหนดจำนวนอย่างไร 1 ถึง 22 ไบต์
MikeT

4

ฐานข้อมูลที่ฉันทำงานส่วนใหญ่ใช้ 'Y' / 'N' เป็นบูลีน ด้วยการใช้งานนั้นคุณสามารถดึงเทคนิคบางอย่างเช่น:

  1. นับจำนวนแถวที่เป็นจริง:
    SELECT SUM (ในกรณีที่ BOOLEAN_FLAG = 'Y' แล้ว 1 ELSE 0) จาก X

  2. เมื่อจัดกลุ่มแถวให้บังคับใช้ "ถ้าหนึ่งแถวเป็นจริงแล้วทั้งหมดเป็นตรรกะ" ตรรกะ:
    SELECT MAX (BOOLEAN_FLAG) จาก Y
    ตรงกันข้ามให้ใช้ MIN เพื่อบังคับให้จัดกลุ่มเป็นเท็จถ้าแถวหนึ่งเป็นเท็จ


4
ในความเป็นจริงตัวอย่างที่แสดงมีประโยชน์สำหรับวิธีการ 0/1 ด้วยเช่นกันและ IMHO ก็เร็วขึ้น
igorsantos07

2

ตัวอย่างการใช้งานเพื่อนำคำตอบที่ได้รับการยอมรับมาใช้โดยเพิ่มคอลัมน์ "บูลีน" ลงในตารางที่มีอยู่ในฐานข้อมูล oracle (โดยใช้numberประเภท):

ALTER TABLE my_table_name ADD (
my_new_boolean_column number(1) DEFAULT 0 NOT NULL
CONSTRAINT my_new_boolean_column CHECK (my_new_boolean_column in (1,0))
);

นี้จะสร้างคอลัมน์ใหม่ในmy_table_nameที่เรียกว่าmy_new_boolean_columnมีค่าเริ่มต้นของ 0. คอลัมน์จะไม่ยอมรับNULLค่านิยมและ จำกัด ค่าได้รับการยอมรับอย่างใดอย่างหนึ่งหรือ01


1

ในฐานข้อมูลของเราเราใช้ enum เพื่อให้แน่ใจว่าเราผ่านเป็นจริงหรือเท็จ ถ้าคุณทำอย่างใดอย่างหนึ่งในสองวิธีแรกมันง่ายเกินไปที่จะเริ่มเพิ่มความหมายใหม่ให้กับจำนวนเต็มโดยไม่ต้องผ่านการออกแบบที่เหมาะสมหรือจบลงด้วยเขตข้อมูลถ่านที่มี Y, y, N, n, T, t F, ค่า f และต้องจำส่วนของรหัสที่ใช้ในตารางและรุ่นของจริงที่ใช้

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