Ưu điểm và nhược điểm của việc sử dụng mặt nạ bit trong cơ sở dữ liệu


22

Cách đây không lâu, tôi đã nói chuyện với đồng nghiệp của mình và anh ấy chắc chắn chống lại việc sử dụng mặt nạ bit vì khó hiểu tất cả các giá trị được lưu trữ trong cơ sở dữ liệu. Theo tôi, không phải lúc nào cũng nên sử dụng chúng, ví dụ để xác định vai trò của người dùng hiện tại. Nếu không, bạn cần lưu trữ nó trong một bảng riêng biệt, điều này sẽ gây ra thêm một THAM GIA. Bạn có thể vui lòng cho tôi biết nếu tôi sai? Bất kỳ tác dụng phụ, ưu điểm / nhược điểm khác của việc sử dụng mặt nạ bit?


2
Có thể có ý nghĩa hơn khi cơ sở dữ liệu tạo mặt nạ bit bên trong và trình bày các bit dưới dạng các cột riêng biệt cho bạn. Yêu cầu của bạn có thể thay đổi.
Simon Richter

1
Nếu bạn không sử dụng thì bạn không sử dụng cơ sở dữ liệu quan hệ của mình theo cách nó dự định.
Pieter B

Câu trả lời:


38

Tôi làm việc với một ứng dụng sử dụng bitmasks để lưu trữ phân công vai trò của người dùng. Đó là một cơn đau ở mông. Nếu điều này làm cho tôi thiên vị, có tội như bị buộc tội.

Nếu bạn đã sử dụng cơ sở dữ liệu quan hệ, thì đó là một mô hình chống vi phạm hầu hết lý thuyết quan hệ và tất cả các quy tắc chuẩn hóa. Khi bạn xây dựng lưu trữ dữ liệu của riêng bạn, nó có thể không phải là một ý tưởng tồi.

Có một điều như có quá nhiều bảng được tham gia, nhưng cơ sở dữ liệu quan hệ được xây dựng để xử lý việc này. Nhiều tính năng bổ sung nếu hiệu suất trở thành một vấn đề: chỉ mục, chế độ xem được lập chỉ mục, v.v. Ngay cả khi các giá trị bạn đang tìm kiếm không thay đổi thường xuyên, đó là một lợi thế cho Bitmask, việc vượt qua việc phải quản lý lập chỉ mục là khá dễ dàng trên cơ sở dữ liệu.

Mặc dù cơ sở dữ liệu thực hiện tốt công việc tổng hợp dữ liệu, chúng có thể trở nên chậm chạp khi bạn bắt đầu đưa những thứ như công thức phức tạp hoặc Hàm vô hướng vào bộ dữ liệu. Bạn có thể thực hiện bitwise trong ứng dụng của mình, nhưng nếu tất cả những gì bạn đang làm là nhận dữ liệu liên quan (tìm kiếm vai trò của người dùng), bạn sẽ không tận dụng những gì lưu trữ dữ liệu của bạn tốt nhất.

Lập luận cuối cùng của tôi chống lại nó sẽ là sự đơn giản cho các nhà phát triển khác. Bạn có người dùng, vai trò và bài tập. Đó là một tập hợp quan hệ nhiều-nhiều (vì có nhiều hơn một mối quan hệ) rất phổ biến, nên dễ quản lý. Nó chỉ là thứ CRUD.


8
Một cơ sở dữ liệu quan hệ là về nơi tồi tệ nhất cho bitmask. Chi phí lưu trữ không còn quá tệ nữa mà một vài lần tham gia và một bảng phụ sẽ phá vỡ bạn. Nó chắc chắn làm cho mọi thứ khó khăn hơn để lý do về. Lưu trữ các quyền dưới dạng bit (1/0) trong cơ sở dữ liệu trong bảng riêng của chúng và biểu thị chúng theo mã có nhưng cờ. Có vẻ khá thích hợp và khả thi. Các nhà phát triển nhận các cờ đơn giản và dbas có các bảng được chuẩn hóa. Mọi người đều vui vẻ.
Mike McMahon

3
Đồng ý, tôi đã từng hỗ trợ một ứng dụng sử dụng mặt nạ bit cho vai trò và đặc quyền của người dùng trong cơ sở dữ liệu của nó. Đó là một cơn ác mộng. Sử dụng int 32 bit, chúng tôi đã hết bit, vì vậy ai đó có ý tưởng tuyệt vời để thêm nhiều mặt nạ bit, và sau đó với các phần trùng lặp, vì vậy bit 4 trong một cột có nghĩa là bit 8 trong cột khác này và chúng không đồng bộ. Aye aye aye. Rất khó để lập chỉ mục vì các chỉ mục lưu trữ các giá trị cột rời rạc, không phải các bit riêng lẻ trong chúng, vì vậy bạn không thể tìm kiếm các hàng where some_bit_mask & 12 > 0mà không quét theo từng hàng.
Brandon

Vào cuối ngày, một bảng nhiều user_role_maphoặc nhiều user_priv_mapsẽ có hiệu lực.
Brandon

@MikeMcMahon, bạn có thể vui lòng đi sâu hơn vào thiết kế bảng không và tôi nên ánh xạ nó theo mã như thế nào để đạt được kết quả mà bạn đang nói đến?
Alex Ovechkin

2
@usr - Không bao giờ nói không bao giờ. Chắc chắn bạn có thể sử dụng bitmasks, nhưng tôi sẽ không sử dụng chúng trong một ứng dụng sử dụng cơ sở dữ liệu quan hệ. Có thể có một số trường hợp cạnh khi xử lý dữ liệu cũ hoặc siêu cần tốc độ.
JeffO

24

Bạn đã đặt tên cho những ưu và nhược điểm có liên quan:

  • Các trường bit tiết kiệm không gian.
  • Họ lưu trữ dữ liệu trong bản ghi, vì vậy bạn không cần THAM GIA để tìm thấy chúng. (Nhưng các trường cờ riêng lẻ trong bản ghi sẽ làm tương tự.)
  • Chúng rất dễ đọc nếu bạn muốn làm việc hiệu quả với đầu ra SQL thô.

Quyết định những việc cần làm đòi hỏi thêm thông tin:

  • Làm thế nào khan hiếm không gian đĩa cho trường hợp sử dụng của bạn?
  • Bạn có thực sự đọc vai trò của người dùng thường xuyên đến mức thời gian THAM GIA chúng là một nút cổ chai không?
  • Bạn sẽ đọc đầu ra SQL và đưa ra quyết định dựa trên điều đó - hoặc là một bản ghi cơ sở dữ liệu không thể đọc được, giống như thực tế là mã máy của hệ thống của bạn không thể đọc được?

Vì vậy, những gì bạn phải làm là thu thập các yếu tố rủi ro và sau đó cân nhắc chúng, để xem liệu những ưu điểm có vượt trội hơn các nhược điểm hay không.


Cảm ơn câu trả lời của bạn, hoàn toàn đồng ý với suy nghĩ của bạn, nhưng nói chung là chống mẫu này hay không? Và bạn có sử dụng mặt nạ trong các dự án của bạn?
Alex Ovechkin

12
@Alex Không có thứ gọi là "thực hành tốt nhất" có thể quyết định những việc cần làm trong trường hợp của bạn. Nếu bạn cực kỳ ngắn về không gian, sử dụng các trường bit là cách tốt nhất. Nếu bạn muốn sử dụng đầu ra SQL trong các báo cáo cho CEO, sử dụng tên nói là cách tốt nhất. Nhưng bạn là người duy nhất biết những trường hợp này, do đó cộng đồng không thể cung cấp cho bạn một đơn thuốc luôn có giá trị.
Kilian Foth

Lấy đối số không gian làm "gimme". Câu hỏi về việc nên sử dụng mặt nạ bit hay đứng trên liệu nó có mang lại lợi ích nào hơn và hơn thế này không.
Robbie Dee

Ngoài ra, bạn MỌI cần phải xử lý thông tin trong cơ sở dữ liệu, hoặc nó luôn luôn được đọc vào một ứng dụng trước khi sử dụng nó.
Ian

1
"Bạn sẽ đọc đầu ra SQL và đưa ra quyết định dựa trên điều đó - hoặc là một bản ghi cơ sở dữ liệu không thể đọc được, giống như thực tế là mã máy của hệ thống của bạn không thể đọc được?" Tôi đoán tôi không thể nói cho tất cả các nhà phát triển, nhưng khi tôi đang phát triển, việc tôi bắt đầu chọn dữ liệu từ DB để hiểu hoặc kiểm tra một cái gì đó là điều cực kỳ phổ biến. Vì vậy, tôi sẽ tranh luận rằng thông thường , câu trả lời cho điều này là "Có, sẽ có người làm."
jpmc26

18

Nếu bạn thực sự, thực sự , thực sự bị ràng buộc về không gian đĩa, thì bạn có thể xem xét ảnh bitmap cho quyền của người dùng. Nếu hiệu suất là lo lắng của bạn, thì hãy quên chúng hoàn toàn, bởi vì việc tách chúng ra sẽ thực sự chậm hơn. Bạn không thể lập chỉ mục một trường bitmap một cách có ý nghĩa, dẫn đến quét bảng cơ sở dữ liệu, gần như luôn luôn là một kẻ giết người hiệu suất.

Trừ khi bạn là Amazon hoặc Netflix, lượng dữ liệu liên quan đến quyền của người dùng sẽ không đáng kể so với mọi thứ khác mà bạn đang nắm giữ.

Bất kỳ DBMS nghiêm túc nào cũng có thể xử lý "tham gia thêm" mà không chớp mắt.


7
+1: Cơ sở dữ liệu quan hệ tốt được phát triển bởi những người thực sự, thực sự, thực sự giỏi về những gì họ làm. Bất cứ ai ở mức độ cần phải vắt kiệt chút hiệu suất cuối cùng mà bạn có thể nhận được bằng cách sử dụng các trường bit sẽ không cần phải đặt câu hỏi. Mô hình hóa dữ liệu, sau đó tìm các phần không thực hiện.
Blrfl

Việc tham gia sẽ làm cho mã ứng dụng trở nên phức tạp hơn, do đó, rất nhiều vấn đề được giải quyết.
Ian

4
@Ian có sự tham gia dường như không phức tạp hơn việc cần biết cách giải mã các quyền bitmasked.
Brad

@Brad, Hãy nghĩ về một enum là một tập hợp các cờ trong C #, với giá trị được lưu trữ của nó như là một cơ sở dữ liệu, lạnh C # không thể đơn giản hơn. Nếu một phép nối được sử dụng, thì mã C # phải đối phó với mối quan hệ 1 với nhiều mối quan hệ.
Ian

Tôi cũng nên thêm rằng nếu bạn có nhiều cột boolean trong một bảng, hầu hết các cơ sở dữ liệu sẽ tìm ra cách nén chúng vào ít không gian nhất có thể và sẽ chăm sóc cho việc xoay vòng bit cho bạn.
Blrfl

8

Quay lại khi lưu trữ đắt tiền, lợi ích với mặt nạ bit là họ đã tiết kiệm không gian. Trong thời đại dữ liệu lớn, đây không phải là vấn đề đã từng xảy ra.

Lấy ví dụ bạn trích dẫn - có các vai trò được lưu trữ dưới dạng mặt nạ bit sẽ là thứ gì đó có mùi mã từ quan điểm thiết kế cơ sở dữ liệu vì nó sẽ vi phạm hình thức bình thường đầu tiên . Theo nghĩa này, chúng là một mô hình chống.

Tất cả điều này đang được nói, nó không phải là một hoặc khác. Bạn có thể lưu trữ dữ liệu dưới dạng mặt nạ bit và sau đó có chế độ xem có thể kéo vai trò người dùng một cách nhanh chóng. Sau đó, bạn cũng có lợi ích khi kiểm tra nhanh xem người dùng nào có vai trò tương tự.


2

Lợi thế duy nhất để sử dụng bitmasks là nếu ý nghĩa của các trường bit không tĩnh. Các bảng quan hệ chỉ hoạt động tốt nếu bạn biết trước từng trường trong bản ghi: bạn phải xác định các trường trong CREATE TABLEcâu lệnh DDL sau khi tất cả.

Nếu ý nghĩa của từng trường bit có thể được cấu hình trong thời gian chạy, hoặc nếu không biết trước về thời gian, thì có thể có ý nghĩa để lưu trữ booleans dưới dạng trường bit. Thậm chí sau đó, nó có thể định nghĩa một bảng với các lĩnh vực tùy ý: field_1, field_2, vv Điều này mang đến cho bạn một thiết kế quan hệ sạch hơn, mặc dù vẫn không lý tưởng. Cho dù điều này là ưu tiên cho một lĩnh vực bit phần lớn là một vấn đề quan điểm, vì không có giải pháp nào là lý tưởng.

Nếu bạn biết những gì bit đại diện trong quá trình phát triển, sau đó tạo các trường cho mỗi bit và đặt cho chúng những tên có ý nghĩa .

Chỉ cần cẩn thận của hiệu ứng nền tảng bên trong . Nếu bạn kết thúc việc xác định các trường tùy ý nhưng được gõ tốt là một điều, nhưng nếu bạn đi quá xa hơn thì bạn sẽ phát minh lại một cơ sở dữ liệu quan hệ ... bên trong cơ sở dữ liệu quan hệ.


2

Tôi mơ hồ về bitmasks. Tôi thấy hầu hết những kẻ gièm pha của họ không hiểu nhị phân và thập lục phân. Để rõ ràng, sử dụng ghi nhớ tốt.

Một lợi thế không được đề cập ở trên là khả năng thêm ý nghĩa mới cho mặt nạ bit mà không cần thêm một cột mới có thể tốn thời gian. Các nhà thiết kế db của chúng tôi (đi trước tôi) có chúng trong một bảng hiện có 5 triệu bản ghi mới mỗi ngày. Việc thêm một cột mới để thể hiện một hành vi mới sẽ mất nhiều thời gian, trong khi việc xác định một bit mới (chúng ta đã tiêu thụ 33 trên 64) không yêu cầu xây dựng lại bảng.

Không, mặt nạ bit không thể được lập chỉ mục nhưng việc xây dựng 33 chỉ mục sẽ là vô lý và sẽ làm chậm quá trình chèn vào một con bò. Các tìm kiếm bảng sử dụng các chỉ mục ngày & ghi "chủ sở hữu", do đó các chỉ mục trên mặt nạ bit này, nếu có thể, sẽ không bao giờ được sử dụng.


Đó là một trường hợp thú vị. Tôi cho rằng bạn có thể đạt được điều tương tự theo cách thức rõ ràng và rõ ràng hơn, bằng cách xác định các cột "dự phòng" trên bàn, sau đó đưa chúng vào sử dụng khi cần thiết. Sau đó, bạn có thể lập chỉ mục các cột này một cách chọn lọc, nếu bạn chọn làm như vậy.
Steve

1

Nếu mục tiêu chỉ là để tiết kiệm dung lượng đĩa, tôi nghĩ đó là một ý tưởng tồi:

  • nhìn vào chi phí của GB ngày hôm nay,
  • so sánh nó với chi phí thời gian của những người viết báo cáo và querry và phải tìm ra những gì trong lĩnh vực này, và làm thế nào để giải quyết một bit cụ thể, so sánh chi phí / lợi ích có thể kết thúc sai.
  • nếu bạn đang làm việc với cơ sở dữ liệu SQL, các hoạt động truy cập bit bổ sung được yêu cầu trong nhiều querry cũng có thể tiêu tốn nhiều thời gian tính toán hơn mức cần thiết

Tuy nhiên, có một số trường hợp, có thể sử dụng các trường bit:

  • nếu các bit của bạn đại diện cho một tập hợp các cờ phức tạp mà bạn luôn xử lý chung
  • thậm chí nhiều hơn nếu bạn cần áp dụng một số thuật toán khớp mẫu trên các bộ này,
  • và đặc biệt nếu dữ liệu này không nằm trong số các tiêu chí lựa chọn được sử dụng thường xuyên nhất.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.