Чи варто використовувати бітовий рядок PostgreSQL?


18

Я дізнався про bit stringтип даних останнім часом, і мені дуже цікаво:

  1. Внизу цієї сторінки документа є речення:

    ... плюс 5 або 8 байт накладних витрат залежно від довжини рядка

  2. Як обробляються бітові рядки іншими мовами, такими як PHP, Java, C #, C ++ тощо, через драйвери, такі як Npgsql, ODBC тощо.

Для питання №1 використання smallint або bigint буде набагато ефективнішим для зберігання даних, і, можливо, запропонує підвищення продуктивності, оскільки цілі числа підтримуються повсюдно. Більшість мов програмування обробляють бітові операції з цілими числами легко. Якщо це так, який сенс вводити тип даних бітових рядків? Це лише для випадків, коли потрібна велика кількість бітових масок? Можливо індексація бітових полів? Мені цікавіше, як проводиться індексація бітових полів у PostgreSQL.

Для №2 я розгублений, більш ніж цікавий. Наприклад, що робити, якщо я зберігаю бітові маски тиждень у полі трохи (7), один біт на день, а найнижчий біт - понеділок. Тоді я запитую значення в PHP та C ++. Що я отримаю? У документації сказано, що у мене буде трохи рядка, проте бітовий рядок - це не те, що я можу використовувати безпосередньо - як у цілих числах. Тоді в цьому випадку я повинен відмовитися від бітового поля?

Хто-небудь може розробити, чому і коли я повинен використовувати біт або біт варіювання?



2
Відповідь Ервіна на ПУ чудова (і якщо ви не проти скопіювати це через @Erwin, було б корисно мати тут), але я хотів би додати мою обережність: у більшості випадків ви б не задумувались зберігати інформацію у бітових рядках на RDBMS - з використанням окремих булевих стовпців у звичайному рішенні незалежно від «ефективності зберігання».
Джек каже, спробуйте topanswers.xyz

@JackDouglas: Я б не проти скопіювати свою відповідь. Цікаво, однак: чи дублювання відповіді на веб-сайтах SE є гарною ідеєю?
Ервін Брандштеттер

@Erwin Я не бачу, чому ні - між сайтами є певне перекриття, і обидва вони повинні стояти окремо (тому, наприклад, ми б не - і все одно не могли - закрити тут питання як дублікат, якби був ідентичне запитання щодо SO). Наша увага приділяється більшою мірою питанням "експертів", але відповідь ІМО відповідає тій категорії, якою вона є.
Джек каже, спробуйте topanswers.xyz

@JackDouglas: Ну, має сенс. І як я могла взагалі погодитися після похвали, яку ви проскочили? ;)
Ервін Брандштеттер

Відповіді:


18

Якщо у вас є лише кілька змінних, я б розглядав можливість збереження окремих booleanстовпців.

  • Індексація проста. Зокрема, індекси на вирази легко.
  • Умови запитів та часткової індексації прості у записі та читанні та значущі.
  • Булева колона займає 1 байт. Для лише кількох змінних це займає найменше місця.
  • На відміну від інших опцій булеві стовпці дозволяють використовувати NULLзначення для окремих бітів, якщо вам це потрібно. Ви завжди можете визначити стовпці, NOT NULLякщо цього не зробите.

Оптимізація пам’яті

Якщо у вас більше ручних повних змінних, але менше 33, integerстовпець може служити вам найкраще. (Або bigintдля до 64 змінних.)

  • Займає 4 байти на диску.
  • Дуже швидка індексація точних збігів ( =оператор).
  • Поводження з окремими значеннями може бути повільніше / менш зручним, ніж з bit stringабо boolean.

З ще більшою кількістю змінних, або якщо ви хочете багато маніпулювати значеннями, або якщо у вас немає величезних таблиць, а дисковий простір / ОЗУ - це не проблема, або якщо ви не впевнені, що вибрати, я б розглядав bit(n)абоbit varying(n) .

  • Займає щонайменше 5 байт (або 8 для дуже довгих рядків) плюс 1 байт для кожної групи з 8 біт (округлені вгору).
  • Ви можете використовувати бітові рядкові функції та оператори безпосередньо.

Приклади

Всього за 3 біти інформації окремі booleanстовпці отримують 3 байти, integerпотреба - 4 байти та bit string6 байт (5 + 1).

Для 32 біт інформації integerще потрібно 4 байти, bit string9 байт займає стільки ж (5 + 4), а booleanстовпці займають 32 байти.

Подальше читання


Так, я згоден з вами. В даний час я використовую Samllint для зберігання бітових масок будних днів. Це підходило для випадку, ефективності зберігання / продуктивності в цілому. Однак, якщо мені доведеться ще трохи індексувати / фільтрувати на бітових масках, це вийде з ладу через низьку продуктивність.
Жакей Ченг

3

Усі типи PostgreSQL є корисними для деяких речей і менш корисними для інших. Загалом, ви більше не переймаєтесь функціональністю та ефективністю пізніше. PostgreSQL має велику кількість функцій для управління різними типами даних, і вони не є винятком.

Я б очікував, що на рівні програми, якщо ваш драйвер db не обробляє його через якесь перетворення типів, ви отримаєте рядкове представлення і вам доведеться це впоратися. Таким чином, він може бути або не корисний у цій якості.

Там, де це, мабуть, корисно, коли ви хочете вибирати записи на основі побітових операцій, таких як побітове або побітове розмноження, або іншим чином маніпулювати даними в SQL-запитах. Якщо ви цим не займаєтеся, багато більш езотеричних особливостей PostgreSQL менш корисні.

Зауважте також, що для довших рядків двійкової інформації є великий об'єктний інтерфейс, який дозволяє здійснювати потокове передавання тощо, та інтерфейс bytea, що дозволяє більш компактне представлення рядків.

тл; д-р: Якщо вам це потрібно, ви знаєте це. В іншому випадку подайте його в розділ "Зарезервоване для майбутнього використання" вашого розуму.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.