Tôi có nên sử dụng chuỗi bit PostgreSQL không?


18

bit stringGần đây tôi đã tìm hiểu về kiểu dữ liệu và tôi khá tò mò về:

  1. Ở dưới cùng của trang tài liệu này có câu:

    ... cộng thêm 5 hoặc 8 byte phí tùy thuộc vào độ dài của chuỗi

  2. Các chuỗi bit được xử lý như thế nào trong các ngôn ngữ khác như PHP, Java, C #, C ++, v.v., thông qua các trình điều khiển như Npgsql, ODBC, v.v.

Đối với câu hỏi số 1, sử dụng smallint hoặc bigint sẽ hiệu quả hơn về lưu trữ và có lẽ sẽ mang lại hiệu suất tăng do các số nguyên được hỗ trợ ở mọi nơi. Hầu hết các ngôn ngữ lập trình xử lý các hoạt động bit trên số nguyên một cách dễ dàng. Nếu đó là trường hợp, điểm giới thiệu kiểu dữ liệu chuỗi bit là gì? Có phải chỉ dành cho những trường hợp cần một lượng lớn mặt nạ bit? Có thể lập chỉ mục trường bit? Tôi tò mò hơn về cách lập chỉ mục trường bit được thực hiện trong PostgreSQL.

Đối với # 2, tôi bối rối, nhiều hơn là tò mò. Ví dụ: điều gì sẽ xảy ra nếu tôi lưu trữ mặt nạ bit ngày trong tuần trong trường bit (7), một bit cho một ngày, với bit thấp nhất đại diện cho thứ Hai. Sau đó, tôi truy vấn giá trị trong PHP và C ++. Tôi sẽ nhận được gì? Tài liệu nói rằng tôi sẽ có một chuỗi bit, tuy nhiên chuỗi bit không phải là thứ tôi có thể sử dụng trực tiếp - như với số nguyên. Vậy thì trong trường hợp này, tôi có nên từ bỏ trường bit không?

Bất cứ ai có thể giải thích tại sao và khi tôi nên sử dụng bit hoặc bit khác nhau?



2
Câu trả lời của Erwin về SO rất hay (và nếu bạn không sao chép nó qua @Erwin, sẽ rất hữu ích khi có ở đây), nhưng tôi muốn thêm sự thận trọng của mình: trong hầu hết các trường hợp, bạn sẽ không dự tính việc lưu trữ thông tin trong chuỗi bit trên RDBMS - sử dụng các cột boolean riêng biệt trong giải pháp bình thường bất kể lưu trữ 'hiệu quả'.
Jack Douglas

@JackDoumund: Tôi sẽ không sao chép câu trả lời của mình. Tuy nhiên, tôi tự hỏi: sao chép một câu trả lời trên các trang web SE là một ý tưởng tốt?
Erwin Brandstetter

@Erwin Tôi không hiểu tại sao không - có một số trùng lặp giữa các trang web và cả hai đều phải đứng một mình (vì vậy, ví dụ chúng tôi sẽ không - và dù sao cũng không thể - đóng một câu hỏi ở đây như một bản sao nếu có một câu hỏi giống hệt nhau trên SO). Trọng tâm của chúng tôi tập trung nhiều hơn vào các vấn đề của 'chuyên gia', nhưng IMO câu trả lời của bạn phù hợp với thể loại đó như hiện tại :)
Jack Douglas

@JackDoumund: Vâng, có ý nghĩa. Và làm thế nào tôi có thể không đồng ý sau khi những lời khen ngợi bạn trượt vào, dù sao? ;)
Erwin Brandstetter

Câu trả lời:


18

Nếu bạn chỉ có một vài biến tôi sẽ xem xét giữ booleancác cột riêng biệt .

  • Lập chỉ mục là dễ dàng. Đặc biệt, các chỉ mục về biểu thức rất dễ dàng.
  • Điều kiện cho các truy vấn và lập chỉ mục một phần rất dễ viết và đọc và có ý nghĩa.
  • Một cột boolean chiếm 1 byte. Đối với chỉ một vài biến số này chiếm ít không gian nhất.
  • Không giống như các cột boolean tùy chọn khác cho phép NULLcác giá trị cho các bit riêng lẻ nếu bạn cần điều đó. Bạn luôn có thể xác định các cột NOT NULLnếu bạn không.

Tối ưu hóa lưu trữ

Nếu bạn có nhiều hơn một biến số đầy đủ nhưng ít hơn 33, một integercột có thể phục vụ bạn tốt nhất. (Hoặc một bigintcho tối đa 64 biến.)

  • Chiếm 4 byte trên đĩa.
  • Lập chỉ mục rất nhanh cho các kết hợp chính xác ( =toán tử).
  • Xử lý các giá trị riêng lẻ có thể chậm hơn / kém thuận tiện hơn so với bit stringhoặc boolean.

Với nhiều biến số hơn hoặc nếu bạn muốn thao tác nhiều giá trị hoặc nếu bạn không có bảng lớn và dung lượng đĩa / RAM thì không có vấn đề gì, hoặc nếu bạn không chắc chắn nên chọn gì, tôi sẽ xem xét bit(n)hoặcbit varying(n) .

  • Chiếm ít nhất 5 byte (hoặc 8 cho chuỗi rất dài) cộng với 1 byte cho mỗi nhóm 8 bit (làm tròn lên).
  • Bạn có thể sử dụng các hàm chuỗi bit và toán tử trực tiếp.

Ví dụ

Đối với chỉ 3 bit thông tin, các booleancột riêng lẻ có được 3 byte, integercần 4 byte và bit string6 byte (5 + 1).

Đối với 32 bit thông tin, một integervẫn cần 4 byte, bit stringchiếm 9 byte cho cùng (5 + 4) và booleancác cột chiếm 32 byte.

đọc thêm


Vâng tôi đồng ý với bạn. Hiện tại, tôi đang sử dụng samllint để lưu trữ mặt nạ bit của các ngày trong tuần. Nó phù hợp với trường hợp, hiệu quả lưu trữ / hiệu suất rộng. Tuy nhiên, nếu tôi có thêm một số chỉ mục / lọc trên mặt nạ bit, nó sẽ thất bại, do hiệu suất thấp.
Jackey Cheung

3

Tất cả các loại PostgreSQL đều hữu ích cho một số thứ và ít hữu ích hơn cho những thứ khác. Nói chung, bạn sẽ nhận được nhiều hơn từ việc lo lắng về chức năng trước và hiệu suất sau. PostgreSQL có một số lượng lớn các hàm để thao tác các loại dữ liệu khác nhau và chúng cũng không ngoại lệ.

Tôi mong đợi ở lớp ứng dụng, trừ khi trình điều khiển db của bạn xử lý nó thông qua một số loại chuyển đổi, bạn sẽ nhận được một chuỗi đại diện và phải xử lý việc này. Vì vậy, nó có thể hoặc không hữu ích trong khả năng đó.

Trường hợp có thể hữu ích là khi bạn muốn chọn các bản ghi dựa trên các hoạt động theo bit, chẳng hạn như bitwise hoặc bitwise, hoặc nói cách khác là thao tác dữ liệu trong các truy vấn SQL. Trừ khi bạn đang làm điều này, nhiều tính năng bí truyền hơn của PostgreQuery sẽ ít hữu ích hơn.

Cũng lưu ý đối với các chuỗi thông tin nhị phân dài hơn có giao diện đối tượng lớn cho phép bạn truyền phát, v.v. và giao diện bytea cho phép biểu diễn chuỗi nhỏ gọn hơn.

tl; dr: Nếu bạn cần nó bạn sẽ biết nó. Nếu không hãy gửi nó đi trong phần "dành riêng cho sử dụng trong tương lai" trong tâm trí của bạn.

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.