ข้อดีและข้อเสียของการใช้บิตมาสก์ในฐานข้อมูล


22

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


2
มันอาจเหมาะสมกว่าที่จะให้ฐานข้อมูลสร้างมาสก์บิตภายในและนำเสนอบิตเป็นคอลัมน์แยกให้คุณ ความต้องการของคุณอาจมีการเปลี่ยนแปลง
Simon Richter

1
หากคุณไม่ได้ใช้การเชื่อมคุณไม่ได้ใช้ฐานข้อมูลเชิงสัมพันธ์ตามที่ตั้งใจไว้
Pieter B

คำตอบ:


38

ฉันทำงานกับแอปพลิเคชันที่ใช้ bitmasks เพื่อเก็บการกำหนดบทบาทผู้ใช้ มันเจ็บที่ก้น หากสิ่งนี้ทำให้ฉันลำเอียงมีความผิดในข้อหา

หากคุณใช้ฐานข้อมูลเชิงสัมพันธ์อยู่แล้วมันเป็นรูปแบบการต่อต้านที่ละเมิดทฤษฎีเชิงสัมพันธ์ส่วนใหญ่และกฎการทำให้เป็นมาตรฐานทั้งหมด เมื่อคุณสร้างที่เก็บข้อมูลของคุณเองมันอาจไม่ใช่ความคิดที่เลวร้ายนัก

มีหลายอย่างที่ตารางเข้าร่วมมากเกินไป แต่ฐานข้อมูลเชิงสัมพันธ์ถูกสร้างขึ้นเพื่อจัดการกับสิ่งนี้ หลายคนมีคุณสมบัติเพิ่มเติมหากประสิทธิภาพกลายเป็นปัญหา: ดัชนีมุมมองที่จัดทำดัชนี ฯลฯ แม้ว่าค่าที่คุณค้นหาไม่เปลี่ยนแปลงบ่อยนักซึ่งเป็นข้อได้เปรียบสำหรับ Bitmask ผู้ที่ต้องจัดการกับดัชนีมากเกินไปคือ ค่อนข้างง่ายในฐานข้อมูล

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

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


8
ฐานข้อมูลเชิงสัมพันธ์เกี่ยวกับสถานที่ที่เลวร้ายที่สุดสำหรับ bitmask ค่าใช้จ่ายในการจัดเก็บนั้นไม่เลวอีกต่อไปที่มีผู้เข้าร่วมเพียงไม่กี่คนและโต๊ะพิเศษควรทำลายคุณ มันทำให้ทุกอย่างยากขึ้นที่จะให้เหตุผล จัดเก็บสิทธิ์เป็นบิต (1/0) ในฐานข้อมูลในตารางของตนเองและแสดงเป็นรหัสในยกเว้นแฟล็ก ดูเหมือนว่าเหมาะสมและเป็นไปได้ นักพัฒนาได้รับการตั้งค่าสถานะที่ง่ายและ dbas มีตารางมาตรฐาน ทุกคนมีความสุข
Mike McMahon

3
ตกลงฉันใช้เพื่อสนับสนุนแอปพลิเคชันที่ใช้บิตมาสก์สำหรับบทบาทผู้ใช้และสิทธิ์ในฐานข้อมูล มันเป็นฝันร้าย ด้วยการใช้ 32 บิตเราจึงหมดบิตดังนั้นบางคนมีความคิดที่ดีที่จะเพิ่มมาส์กบิตเพิ่มเติมแล้วจึงมีการทับซ้อนดังนั้นบิตที่ 4 ในหนึ่งคอลัมน์จึงหมายถึงบิตที่ 8 ในคอลัมน์อื่นนี้และพวกเขาก็ไม่ซิงค์กัน Aye aye aye เป็นการยากที่จะทำดัชนีเนื่องจากดัชนีจัดเก็บค่าคอลัมน์แบบแยกกันไม่ใช่บิตแต่ละรายการดังนั้นคุณจึงไม่สามารถค้นหาแถวwhere some_bit_mask & 12 > 0โดยไม่ต้องสแกนทีละแถว
Brandon

ในตอนท้ายของวันหลายต่อหลายคนuser_role_mapหรือuser_priv_mapตารางจะพอเพียง
Brandon

@MikeMcMahon คุณช่วยกรุณาดำน้ำลึกลงไปในการออกแบบตารางและฉันควรแมปในรหัสเพื่อให้บรรลุผลที่คุณพูดถึง?
Alex Ovechkin

2
@usr - อย่าพูดว่าไม่เคย แน่นอนคุณสามารถใช้ bitmasks ได้ แต่ฉันจะไม่ใช้มันในแอปพลิเคชันที่ใช้ฐานข้อมูลเชิงสัมพันธ์ อาจมีบางกรณีขอบเมื่อจัดการกับข้อมูลดั้งเดิมหรือต้องการความเร็ว
JeffO

24

คุณได้ตั้งชื่อข้อดีและข้อเสียที่เกี่ยวข้องแล้ว:

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

การตัดสินใจว่าจะทำอย่างไรต้องการข้อมูลเพิ่มเติม:

  • พื้นที่ดิสก์เหลือน้อยเพียงใดสำหรับกรณีการใช้งานของคุณ?
  • คุณอ่านบทบาทของผู้ใช้บ่อยครั้งหรือไม่ที่เวลาที่จะเข้าร่วมเป็นคอขวด?
  • จะให้คุณไปอ่าน SQL ส่งออกและการตัดสินใจบนพื้นฐานที่ - หรืออ่านไม่ได้เป็นฐานข้อมูลที่บันทึกสาระสำคัญเช่นเดียวกับความจริงที่ว่าที่รหัสเครื่องของระบบของคุณไม่สามารถอ่านได้?

ดังนั้นสิ่งที่คุณต้องทำคือรวบรวมปัจจัยเสี่ยงจากนั้นชั่งน้ำหนักพวกเขาเพื่อดูว่าข้อดีมีมากกว่าข้อเสียหรือไม่


ขอบคุณสำหรับคำตอบของคุณเห็นด้วยกับความคิดของคุณทั้งหมด แต่โดยทั่วไปแล้วนี่เป็นรูปแบบการต่อต้านหรือไม่? และคุณใช้มาสก์ในโครงการของคุณหรือไม่?
Alex Ovechkin

12
@Alex ไม่มีสิ่งใดเป็น "แนวปฏิบัติที่ดีที่สุด" ที่สามารถตัดสินใจได้ว่าจะทำอย่างไรในกรณีของคุณ หากคุณมีพื้นที่เหลือน้อยมากการใช้ฟิลด์บิตเป็นแนวปฏิบัติที่เหมาะสมที่สุด หากคุณต้องการใช้เอาต์พุต SQL ในรายงานต่อ CEO การใช้ชื่อพูดเป็นแนวปฏิบัติที่ดีที่สุด แต่คุณเป็นคนเดียวที่รู้สถานการณ์เหล่านี้ดังนั้นชุมชนไม่สามารถให้ใบสั่งยาที่ถูกต้องได้เสมอ
Kilian Foth

รับอาร์กิวเมนต์ช่องว่างเป็น "gimme" คำถามที่ว่าจะใช้บิตมาส์กหรือไม่ก็ขึ้นอยู่กับว่ามันจะส่งผลประโยชน์ใด ๆ
Robbie Dee

นอกจากนี้คุณยังจำเป็นต้องประมวลผลข้อมูลในฐานข้อมูลทุกครั้งหรือไม่หรือต้องอ่านลงในแอปพลิเคชันทุกครั้งก่อนใช้งาน
เอียน

1
"คุณกำลังจะอ่านเอาต์พุต SQL และทำการตัดสินใจตามนั้น - หรือเป็นฐานข้อมูลที่อ่านไม่ได้สาระสำคัญเหมือนกับข้อเท็จจริงที่ว่ารหัสเครื่องของระบบของคุณอ่านไม่ได้" ฉันเดาว่าฉันไม่สามารถพูดกับนักพัฒนาทุกคน แต่เมื่อฉันพัฒนามันเป็นเรื่องธรรมดามากที่ฉันจะเริ่มเลือกข้อมูลจากฐานข้อมูลเพื่อทำความเข้าใจหรือตรวจสอบบางอย่าง ดังนั้นฉันจะโต้แย้งว่าโดยปกติคำตอบสำหรับเรื่องนี้คือ "ใช่แล้วจะมีใครซักคน"
jpmc26

18

หากคุณจริงๆจริงๆ , จริงๆ strapped สำหรับพื้นที่ดิสก์แล้วคุณอาจพิจารณาบิตแมปสำหรับสิทธิ์ของผู้ใช้ หากการแสดงเป็นเรื่องที่คุณกังวลให้ลืมเรื่องทั้งหมดไปเลยเพราะการแยกมันออกจากกันจะช้าลง คุณไม่สามารถสร้างดัชนีฟิลด์บิตแมปที่มีความหมายส่งผลให้การสแกนตารางฐานข้อมูลซึ่ง [เกือบ] เป็นตัวฆ่าประสิทธิภาพเสมอ

เว้นแต่ว่าคุณเป็น Amazon หรือ Netflix จำนวนข้อมูลที่เกี่ยวข้องกับการอนุญาตของผู้ใช้จะน้อยมากเมื่อเทียบกับทุกอย่างที่คุณมี

DBMS ที่ร้ายแรงใด ๆ สามารถจัดการ "เข้าร่วมพิเศษ" โดยไม่กระพริบ


7
+1: ฐานข้อมูลเชิงสัมพันธ์ที่ดีนั้นได้รับการพัฒนาโดยคนที่เก่งจริง ๆ และเก่งในสิ่งที่พวกเขาทำ ทุกคนในระดับที่ต้องการบีบบิตสุดท้ายของประสิทธิภาพที่คุณอาจได้รับจากการใช้ฟิลด์บิตไม่จำเป็นต้องถามคำถาม ทำโมเดลข้อมูลจากนั้นค้นหาชิ้นส่วนที่ไม่ทำงาน
Blrfl

การมีการเข้าร่วมจะทำให้รหัสแอปพลิเคชันมีความซับซ้อนมากขึ้นดังนั้นจำนวนมากจึงลงมาที่บทบาทจะถูกประมวลผล
เอียน

4
@ ฉันมีการเข้าร่วมดูเหมือนจะไม่ซับซ้อนเกินกว่าที่จำเป็นต้องรู้วิธีการถอดรหัสสิทธิ์ bitmasked
แบรด

@Brad คิดว่า enum ที่เป็นชุดของธงใน C # ด้วยค่าที่เก็บไว้“ ตามสภาพ” ในฐานข้อมูล C # cold ไม่สามารถทำให้เรียบง่ายขึ้นได้ หากมีการใช้การเข้าร่วมรหัส C # จะต้องรับมือกับความสัมพันธ์แบบ“ 1 ต่อหลายคน”
เอียน

ฉันควรจะเพิ่มว่าถ้าคุณมีคอลัมน์บูลีนหลายตัวในตารางฐานข้อมูลส่วนใหญ่จะหาวิธีที่จะบีบให้มีพื้นที่น้อยที่สุดเท่าที่จะเป็นไปได้และจะดูแล bit-twiddling ให้คุณ
Blrfl

8

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

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

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


2

ข้อดีเพียงอย่างเดียวของการใช้ bitmasks คือถ้าความหมายของบิตฟิลด์ไม่คงที่ ตารางเชิงสัมพันธ์จะทำงานได้ดีถ้าคุณรู้ล่วงหน้าว่าแต่ละเขตข้อมูลอยู่ในระเบียนใด: คุณต้องระบุเขตข้อมูลในCREATE TABLEคำสั่ง DDL หลังจากทั้งหมด

หากความหมายของแต่ละฟิลด์บิตสามารถกำหนดค่าได้ที่รันไทม์หรือไม่ทราบล่วงหน้าก่อนหน้านั้นอาจทำให้รู้สึกถึงการเก็บบูลีนเป็นฟิลด์บิต ถึงอย่างนั้นก็เป็นไปได้ในการกำหนดตารางที่มีสาขาพล: field_1, field_2ฯลฯ ซึ่งจะช่วยให้คุณออกแบบเชิงสัมพันธ์ทำความสะอาด แต่ยังคงไม่เหมาะ ไม่ว่าจะเป็นสิ่งที่พิเศษไปยังเขตข้อมูลบิตเป็นส่วนใหญ่เรื่องของความเห็นเนื่องจากการแก้ปัญหาไม่เหมาะ

ถ้าคุณรู้ว่าบิตแทนในระหว่างการพัฒนาแล้วสร้างฟิลด์สำหรับแต่ละบิตและให้พวกเขามีความหมายชื่อ

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


2

ฉันสับสนเกี่ยวกับ bitmasks ฉันพบว่าผู้ว่าส่วนใหญ่ไม่เข้าใจเลขฐานสองและเลขฐานสิบหก เพื่อความชัดเจนให้ใช้ตัวช่วยจำที่ดี

ข้อได้เปรียบที่ไม่ได้กล่าวถึงข้างต้นคือความสามารถในการเพิ่มความหมายใหม่ให้กับรูปแบบบิตโดยไม่ต้องเพิ่มคอลัมน์ใหม่ นักออกแบบฐานข้อมูลของเรา (ที่นำหน้าฉัน) มีพวกเขาในตารางที่ตอนนี้ได้รับ 5 ล้านบันทึกใหม่ทุกวัน การเพิ่มคอลัมน์ใหม่เพื่อแสดงพฤติกรรมใหม่อาจใช้เวลานานในขณะที่กำหนดบิตใหม่ (เราใช้ไปหมด 33 จาก 64) ไม่จำเป็นต้องสร้างตารางใหม่

ไม่ได้บิตมาสก์ไม่สามารถทำดัชนีได้ แต่การสร้างดัชนี 33 รายการนั้นไร้สาระและจะทำให้การแทรกช้าลงในการรวบรวมข้อมูล การค้นหาตารางใช้ดัชนีวันที่ & บันทึก "เจ้าของ" ดังนั้นดัชนีของรูปแบบบิตนี้ถ้าเป็นไปได้จะไม่ถูกนำมาใช้


เป็นกรณีที่น่าสนใจ ฉันคิดว่าคุณสามารถทำได้เหมือนเดิมในแบบโคเชอร์และแบบชัดแจ้งโดยกำหนดคอลัมน์ "ว่าง" บนโต๊ะแล้วนำสิ่งเหล่านี้มาใช้ตามต้องการ อย่างน้อยคุณก็สามารถจัดทำดัชนีคอลัมน์เหล่านี้ได้หากคุณเลือกที่จะทำเช่นนั้น
Steve

1

หากเป้าหมายเพียงเพื่อประหยัดเนื้อที่ดิสก์ฉันคิดว่าเป็นความคิดที่ไม่ดี:

  • ดูค่าใช้จ่ายของ GB วันนี้
  • เปรียบเทียบกับต้นทุนของเวลาของผู้ที่เขียนรายงานและการสอบถามและต้องคิดว่ามีอะไรในฟิลด์และวิธีการระบุบิตเฉพาะการเปรียบเทียบต้นทุน / ผลประโยชน์อาจสิ้นสุดลงในด้านที่ไม่ถูกต้อง
  • หากคุณกำลังทำงานกับฐานข้อมูล SQL การดำเนินการเข้าถึงบิตเพิ่มเติมที่ต้องการในการค้นหาจำนวนมากอาจใช้เวลาในการคำนวณมากกว่าที่จำเป็น

อย่างไรก็ตามมีบางกรณีที่สามารถใช้ jusitfiy ของเขตข้อมูลบิต:

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