Kiểu dữ liệu để lưu trữ một mảng cờ (mảng bitmap / bit)


15

Tôi cần lưu trữ một mảng bit cho mỗi bản ghi của bảng, hỗ trợ các hoạt động sau:

  • Kiểm tra nếu một bit được đặt và thiết lập một bit (sử dụng SQL)

  • Truy vấn và thiết lập giá trị bằng ADO 2.8 (không phải ADO.NET)

  • Lập chỉ mục (để hưởng lợi từ tính năng "bao gồm chỉ mục")

Số lượng bit tối đa được lưu trữ trong mảng này là cố định, nhưng có thể vượt quá 32 . Đó là, một cột int đơn giản không phải lúc nào cũng hoạt động.

Từ những gì tôi đã thấy cho đến nay, các lựa chọn của tôi là:

  1. Sử dụng một số cột int
  2. Sử dụng bigint (hoạt động miễn là số bit là <= 64)
  3. Sử dụng nhị phân
  4. ?

Tùy chọn đầu tiên sẽ hoạt động, nhưng đòi hỏi khá nhiều cấu trúc lại trong mã truy cập dữ liệu. Tùy chọn thứ hai chỉ là một cứu trợ tạm thời và từ các tìm kiếm của tôi cho đến nay tôi không chắc chắn liệu ADO có hoạt động tốt với bigint hay không . Tôi không có kinh nghiệm về nhị phân và tôi không biết về bất kỳ lựa chọn nào khác.

Loại dữ liệu nào bạn sẽ chọn, đưa ra các yêu cầu?

Câu trả lời:


12

Tôi không thể ủng hộ đủ mạnh để không sử dụng một lĩnh vực duy nhất cho việc này.

Tôi hiện đang xử lý việc duy trì một bộ dữ liệu rất lớn với biginttrường bitmask và đó là một cơn ác mộng về hiệu suất.

Nếu bạn kiểm tra một chút thì không sao. Nếu bạn kiểm tra hiệu suất nhiều hơn một bit sẽ giảm rất nhanh.

Do tính chất của số nguyên bitmask, phân phối dữ liệu sẽ rất mất cân bằng và bạn sẽ nhận được các gói dưới mức tối ưu.

Kiểm tra nhiều bit dẫn đến quét phạm vi hoặc chỉ mục với một chức năng chạy trên mỗi hàng. Đó là một mớ hỗn độn.

Cách giải quyết của tôi rất đơn giản - Tôi đã tạo một bảng để lưu trữ PK cho từng điều kiện cần kiểm tra. Đây là phản trực quan ban đầu nhưng không gian cần thiết thấp (bạn chỉ lưu trữ PK) và tra cứu nhanh như chớp, đặc biệt nếu bạn sử dụng a UNIQUE CLUSTERED INDEX.

Bạn có thể thêm bao nhiêu điều kiện tùy thích mà không ảnh hưởng đến bảng chính của bạn và các cập nhật cũng không ảnh hưởng đến bảng chính của bạn.

Lập chỉ mục rất đơn giản vì bạn chỉ lập chỉ mục tất cả các bảng tra cứu riêng lẻ và vì khóa cụm của bạn giống nhau trên bảng chính của bạn và việc tra cứu tất cả các đánh giá của bạn merge joinđều rất hiệu quả.


1
Bạn có thể xây dựng thêm một chút về cách giải quyết của bạn? Tôi thấy điều này bởi vì tôi đang cố gắng giải quyết vấn đề cơ bản tương tự, nhưng không chắc cách tốt nhất để làm điều đó.
Joshua Frank

4

Nếu tất cả những gì bạn cần lưu trữ là một số lượng vừa phải các giá trị đúng / sai, bạn có thể sử dụng bitkiểu dữ liệu.

Trong nội bộ, SQL Server lưu trữ bitcác cột được đóng gói thành "khối" byte. Vì vậy, đối với tối đa 8 bitcột trong bảng của bạn, SQL lưu trữ dưới dạng 1 byte; 9-16 bitcột trong 2 byte, v.v.

Có vẻ như bạn sẽ không đạt đến giới hạn cột, vì vậy điều này có vẻ khá đơn giản. Và tất nhiên, việc giữ chúng tách biệt tốt như thế cho phép bạn đặt tên cho các cột để dễ đọc và có được tất cả các khả năng lập chỉ mục mà bạn thường làm (nếu các cờ được chọn lọc cao, các chỉ mục được lọc có thể hữu ích nếu bạn có thể nhắm mục tiêu 2008+).

Tự mình đóng gói bit sẽ khiến việc lập chỉ mục trở nên phức tạp hơn nhiều (có thể là bitcác cột được tính toán và lập chỉ mục để thể hiện từng vị trí của mặt nạ ... nhưng sau đó bạn lại tệ hơn so với sử dụng bittrực tiếp).

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.